diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-22 00:19:54 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-22 00:19:54 -0400 |
commit | d4429f608abde89e8bc1e24b43cd503feb95c496 (patch) | |
tree | 4c11afa193593a5e3949391bf35022b4f87ba375 /arch/powerpc/mm | |
parent | e10117d36ef758da0690c95ecffc09d5dd7da479 (diff) | |
parent | 6a1c9dfe4186f18fed38421b35b40fb9260cbfe1 (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: (71 commits)
powerpc/44x: Update ppc44x_defconfig
powerpc/watchdog: Make default timeout for Book-E watchdog a Kconfig option
fsl_rio: Add comments for sRIO registers.
powerpc/fsl-booke: Add e55xx (64-bit) smp defconfig
powerpc/fsl-booke: Add p5020 DS board support
powerpc/fsl-booke64: Use TLB CAMs to cover linear mapping on FSL 64-bit chips
powerpc/fsl-booke: Add support for FSL Arch v1.0 MMU in setup_page_sizes
powerpc/fsl-booke: Add support for FSL 64-bit e5500 core
powerpc/85xx: add cache-sram support
powerpc/85xx: add ngPIXIS FPGA device tree node to the P1022DS board
powerpc: Fix compile error with paca code on ppc64e
powerpc/fsl-booke: Add p3041 DS board support
oprofile/fsl emb: Don't set MSR[PMM] until after clearing the interrupt.
powerpc/fsl-booke: Add PCI device ids for P2040/P3041/P5010/P5020 QoirQ chips
powerpc/mpc8xxx_gpio: Add support for 'qoriq-gpio' controllers
powerpc/fsl_booke: Add support to boot from core other than 0
powerpc/p1022: Add probing for individual DMA channels
powerpc/fsl_soc: Search all global-utilities nodes for rstccr
powerpc: Fix invalid page flags in create TLB CAM path for PTE_64BIT
powerpc/mpc83xx: Support for MPC8308 P1M board
...
Fix up conflict with the generic irq_work changes in arch/powerpc/kernel/time.c
Diffstat (limited to 'arch/powerpc/mm')
-rw-r--r-- | arch/powerpc/mm/Makefile | 6 | ||||
-rw-r--r-- | arch/powerpc/mm/fault.c | 6 | ||||
-rw-r--r-- | arch/powerpc/mm/fsl_booke_mmu.c | 15 | ||||
-rw-r--r-- | arch/powerpc/mm/mmu_context_nohash.c | 6 | ||||
-rw-r--r-- | arch/powerpc/mm/mmu_decl.h | 5 | ||||
-rw-r--r-- | arch/powerpc/mm/tlb_nohash.c | 56 | ||||
-rw-r--r-- | arch/powerpc/mm/tlb_nohash_low.S | 2 |
7 files changed, 79 insertions, 17 deletions
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile index ce68708bbad5..bdca46e08382 100644 --- a/arch/powerpc/mm/Makefile +++ b/arch/powerpc/mm/Makefile | |||
@@ -4,9 +4,7 @@ | |||
4 | 4 | ||
5 | subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror | 5 | subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror |
6 | 6 | ||
7 | ifeq ($(CONFIG_PPC64),y) | 7 | ccflags-$(CONFIG_PPC64) := -mno-minimal-toc |
8 | EXTRA_CFLAGS += -mno-minimal-toc | ||
9 | endif | ||
10 | 8 | ||
11 | obj-y := fault.o mem.o pgtable.o gup.o \ | 9 | obj-y := fault.o mem.o pgtable.o gup.o \ |
12 | init_$(CONFIG_WORD_SIZE).o \ | 10 | init_$(CONFIG_WORD_SIZE).o \ |
@@ -25,7 +23,7 @@ obj-$(CONFIG_PPC_STD_MMU) += hash_low_$(CONFIG_WORD_SIZE).o \ | |||
25 | mmu_context_hash$(CONFIG_WORD_SIZE).o | 23 | mmu_context_hash$(CONFIG_WORD_SIZE).o |
26 | obj-$(CONFIG_40x) += 40x_mmu.o | 24 | obj-$(CONFIG_40x) += 40x_mmu.o |
27 | obj-$(CONFIG_44x) += 44x_mmu.o | 25 | obj-$(CONFIG_44x) += 44x_mmu.o |
28 | obj-$(CONFIG_FSL_BOOKE) += fsl_booke_mmu.o | 26 | obj-$(CONFIG_PPC_FSL_BOOK3E) += fsl_booke_mmu.o |
29 | obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o | 27 | obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o |
30 | obj-$(CONFIG_PPC_MM_SLICES) += slice.o | 28 | obj-$(CONFIG_PPC_MM_SLICES) += slice.o |
31 | ifeq ($(CONFIG_HUGETLB_PAGE),y) | 29 | ifeq ($(CONFIG_HUGETLB_PAGE),y) |
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index 1bd712c33ce2..54f4fb994e99 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/kprobes.h> | 30 | #include <linux/kprobes.h> |
31 | #include <linux/kdebug.h> | 31 | #include <linux/kdebug.h> |
32 | #include <linux/perf_event.h> | 32 | #include <linux/perf_event.h> |
33 | #include <linux/magic.h> | ||
33 | 34 | ||
34 | #include <asm/firmware.h> | 35 | #include <asm/firmware.h> |
35 | #include <asm/page.h> | 36 | #include <asm/page.h> |
@@ -385,6 +386,7 @@ do_sigbus: | |||
385 | void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) | 386 | void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) |
386 | { | 387 | { |
387 | const struct exception_table_entry *entry; | 388 | const struct exception_table_entry *entry; |
389 | unsigned long *stackend; | ||
388 | 390 | ||
389 | /* Are we prepared to handle this fault? */ | 391 | /* Are we prepared to handle this fault? */ |
390 | if ((entry = search_exception_tables(regs->nip)) != NULL) { | 392 | if ((entry = search_exception_tables(regs->nip)) != NULL) { |
@@ -413,5 +415,9 @@ void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) | |||
413 | printk(KERN_ALERT "Faulting instruction address: 0x%08lx\n", | 415 | printk(KERN_ALERT "Faulting instruction address: 0x%08lx\n", |
414 | regs->nip); | 416 | regs->nip); |
415 | 417 | ||
418 | stackend = end_of_stack(current); | ||
419 | if (current != &init_task && *stackend != STACK_END_MAGIC) | ||
420 | printk(KERN_ALERT "Thread overran stack, or stack corrupted\n"); | ||
421 | |||
416 | die("Kernel access of bad area", regs, sig); | 422 | die("Kernel access of bad area", regs, sig); |
417 | } | 423 | } |
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c index cde270847e7c..f7802c8bba0a 100644 --- a/arch/powerpc/mm/fsl_booke_mmu.c +++ b/arch/powerpc/mm/fsl_booke_mmu.c | |||
@@ -57,11 +57,6 @@ | |||
57 | 57 | ||
58 | unsigned int tlbcam_index; | 58 | unsigned int tlbcam_index; |
59 | 59 | ||
60 | |||
61 | #if defined(CONFIG_LOWMEM_CAM_NUM_BOOL) && (CONFIG_LOWMEM_CAM_NUM >= NUM_TLBCAMS) | ||
62 | #error "LOWMEM_CAM_NUM must be less than NUM_TLBCAMS" | ||
63 | #endif | ||
64 | |||
65 | #define NUM_TLBCAMS (64) | 60 | #define NUM_TLBCAMS (64) |
66 | struct tlbcam TLBCAM[NUM_TLBCAMS]; | 61 | struct tlbcam TLBCAM[NUM_TLBCAMS]; |
67 | 62 | ||
@@ -138,7 +133,8 @@ static void settlbcam(int index, unsigned long virt, phys_addr_t phys, | |||
138 | if (mmu_has_feature(MMU_FTR_BIG_PHYS)) | 133 | if (mmu_has_feature(MMU_FTR_BIG_PHYS)) |
139 | TLBCAM[index].MAS7 = (u64)phys >> 32; | 134 | TLBCAM[index].MAS7 = (u64)phys >> 32; |
140 | 135 | ||
141 | if (flags & _PAGE_USER) { | 136 | /* Below is unlikely -- only for large user pages or similar */ |
137 | if (pte_user(flags)) { | ||
142 | TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR; | 138 | TLBCAM[index].MAS3 |= MAS3_UX | MAS3_UR; |
143 | TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0); | 139 | TLBCAM[index].MAS3 |= ((flags & _PAGE_RW) ? MAS3_UW : 0); |
144 | } | 140 | } |
@@ -185,6 +181,12 @@ unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx) | |||
185 | return amount_mapped; | 181 | return amount_mapped; |
186 | } | 182 | } |
187 | 183 | ||
184 | #ifdef CONFIG_PPC32 | ||
185 | |||
186 | #if defined(CONFIG_LOWMEM_CAM_NUM_BOOL) && (CONFIG_LOWMEM_CAM_NUM >= NUM_TLBCAMS) | ||
187 | #error "LOWMEM_CAM_NUM must be less than NUM_TLBCAMS" | ||
188 | #endif | ||
189 | |||
188 | unsigned long __init mmu_mapin_ram(unsigned long top) | 190 | unsigned long __init mmu_mapin_ram(unsigned long top) |
189 | { | 191 | { |
190 | return tlbcam_addrs[tlbcam_index - 1].limit - PAGE_OFFSET + 1; | 192 | return tlbcam_addrs[tlbcam_index - 1].limit - PAGE_OFFSET + 1; |
@@ -225,3 +227,4 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base, | |||
225 | /* 64M mapped initially according to head_fsl_booke.S */ | 227 | /* 64M mapped initially according to head_fsl_booke.S */ |
226 | memblock_set_current_limit(min_t(u64, limit, 0x04000000)); | 228 | memblock_set_current_limit(min_t(u64, limit, 0x04000000)); |
227 | } | 229 | } |
230 | #endif | ||
diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c index ddfd7ad4e1d6..5ce99848d91e 100644 --- a/arch/powerpc/mm/mmu_context_nohash.c +++ b/arch/powerpc/mm/mmu_context_nohash.c | |||
@@ -334,7 +334,7 @@ static int __cpuinit mmu_context_cpu_notify(struct notifier_block *self, | |||
334 | /* We don't touch CPU 0 map, it's allocated at aboot and kept | 334 | /* We don't touch CPU 0 map, it's allocated at aboot and kept |
335 | * around forever | 335 | * around forever |
336 | */ | 336 | */ |
337 | if (cpu == 0) | 337 | if (cpu == boot_cpuid) |
338 | return NOTIFY_OK; | 338 | return NOTIFY_OK; |
339 | 339 | ||
340 | switch (action) { | 340 | switch (action) { |
@@ -420,9 +420,11 @@ void __init mmu_context_init(void) | |||
420 | */ | 420 | */ |
421 | context_map = alloc_bootmem(CTX_MAP_SIZE); | 421 | context_map = alloc_bootmem(CTX_MAP_SIZE); |
422 | context_mm = alloc_bootmem(sizeof(void *) * (last_context + 1)); | 422 | context_mm = alloc_bootmem(sizeof(void *) * (last_context + 1)); |
423 | #ifndef CONFIG_SMP | ||
423 | stale_map[0] = alloc_bootmem(CTX_MAP_SIZE); | 424 | stale_map[0] = alloc_bootmem(CTX_MAP_SIZE); |
425 | #else | ||
426 | stale_map[boot_cpuid] = alloc_bootmem(CTX_MAP_SIZE); | ||
424 | 427 | ||
425 | #ifdef CONFIG_SMP | ||
426 | register_cpu_notifier(&mmu_context_cpu_nb); | 428 | register_cpu_notifier(&mmu_context_cpu_nb); |
427 | #endif | 429 | #endif |
428 | 430 | ||
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index 63b84a0d3b10..dd0a2589591d 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h | |||
@@ -140,10 +140,13 @@ extern void wii_memory_fixups(void); | |||
140 | extern void MMU_init_hw(void); | 140 | extern void MMU_init_hw(void); |
141 | extern unsigned long mmu_mapin_ram(unsigned long top); | 141 | extern unsigned long mmu_mapin_ram(unsigned long top); |
142 | 142 | ||
143 | #elif defined(CONFIG_FSL_BOOKE) | 143 | #elif defined(CONFIG_PPC_FSL_BOOK3E) |
144 | extern unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx); | ||
145 | #ifdef CONFIG_PPC32 | ||
144 | extern void MMU_init_hw(void); | 146 | extern void MMU_init_hw(void); |
145 | extern unsigned long mmu_mapin_ram(unsigned long top); | 147 | extern unsigned long mmu_mapin_ram(unsigned long top); |
146 | extern void adjust_total_lowmem(void); | 148 | extern void adjust_total_lowmem(void); |
149 | #endif | ||
147 | extern void loadcam_entry(unsigned int index); | 150 | extern void loadcam_entry(unsigned int index); |
148 | 151 | ||
149 | struct tlbcam { | 152 | struct tlbcam { |
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c index 6a0f20c25469..36c0c449a899 100644 --- a/arch/powerpc/mm/tlb_nohash.c +++ b/arch/powerpc/mm/tlb_nohash.c | |||
@@ -349,11 +349,47 @@ void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address) | |||
349 | 349 | ||
350 | static void setup_page_sizes(void) | 350 | static void setup_page_sizes(void) |
351 | { | 351 | { |
352 | unsigned int tlb0cfg = mfspr(SPRN_TLB0CFG); | 352 | unsigned int tlb0cfg; |
353 | unsigned int tlb0ps = mfspr(SPRN_TLB0PS); | 353 | unsigned int tlb0ps; |
354 | unsigned int eptcfg = mfspr(SPRN_EPTCFG); | 354 | unsigned int eptcfg; |
355 | int i, psize; | 355 | int i, psize; |
356 | 356 | ||
357 | #ifdef CONFIG_PPC_FSL_BOOK3E | ||
358 | unsigned int mmucfg = mfspr(SPRN_MMUCFG); | ||
359 | |||
360 | if (((mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V1) && | ||
361 | (mmu_has_feature(MMU_FTR_TYPE_FSL_E))) { | ||
362 | unsigned int tlb1cfg = mfspr(SPRN_TLB1CFG); | ||
363 | unsigned int min_pg, max_pg; | ||
364 | |||
365 | min_pg = (tlb1cfg & TLBnCFG_MINSIZE) >> TLBnCFG_MINSIZE_SHIFT; | ||
366 | max_pg = (tlb1cfg & TLBnCFG_MAXSIZE) >> TLBnCFG_MAXSIZE_SHIFT; | ||
367 | |||
368 | for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { | ||
369 | struct mmu_psize_def *def; | ||
370 | unsigned int shift; | ||
371 | |||
372 | def = &mmu_psize_defs[psize]; | ||
373 | shift = def->shift; | ||
374 | |||
375 | if (shift == 0) | ||
376 | continue; | ||
377 | |||
378 | /* adjust to be in terms of 4^shift Kb */ | ||
379 | shift = (shift - 10) >> 1; | ||
380 | |||
381 | if ((shift >= min_pg) && (shift <= max_pg)) | ||
382 | def->flags |= MMU_PAGE_SIZE_DIRECT; | ||
383 | } | ||
384 | |||
385 | goto no_indirect; | ||
386 | } | ||
387 | #endif | ||
388 | |||
389 | tlb0cfg = mfspr(SPRN_TLB0CFG); | ||
390 | tlb0ps = mfspr(SPRN_TLB0PS); | ||
391 | eptcfg = mfspr(SPRN_EPTCFG); | ||
392 | |||
357 | /* Look for supported direct sizes */ | 393 | /* Look for supported direct sizes */ |
358 | for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { | 394 | for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) { |
359 | struct mmu_psize_def *def = &mmu_psize_defs[psize]; | 395 | struct mmu_psize_def *def = &mmu_psize_defs[psize]; |
@@ -505,6 +541,20 @@ static void __early_init_mmu(int boot_cpu) | |||
505 | */ | 541 | */ |
506 | linear_map_top = memblock_end_of_DRAM(); | 542 | linear_map_top = memblock_end_of_DRAM(); |
507 | 543 | ||
544 | #ifdef CONFIG_PPC_FSL_BOOK3E | ||
545 | if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) { | ||
546 | unsigned int num_cams; | ||
547 | |||
548 | /* use a quarter of the TLBCAM for bolted linear map */ | ||
549 | num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4; | ||
550 | linear_map_top = map_mem_in_cams(linear_map_top, num_cams); | ||
551 | |||
552 | /* limit memory so we dont have linear faults */ | ||
553 | memblock_enforce_memory_limit(linear_map_top); | ||
554 | memblock_analyze(); | ||
555 | } | ||
556 | #endif | ||
557 | |||
508 | /* A sync won't hurt us after mucking around with | 558 | /* A sync won't hurt us after mucking around with |
509 | * the MMU configuration | 559 | * the MMU configuration |
510 | */ | 560 | */ |
diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S index b9d9fed8f36e..af405eefe48d 100644 --- a/arch/powerpc/mm/tlb_nohash_low.S +++ b/arch/powerpc/mm/tlb_nohash_low.S | |||
@@ -367,7 +367,7 @@ _GLOBAL(set_context) | |||
367 | #error Unsupported processor type ! | 367 | #error Unsupported processor type ! |
368 | #endif | 368 | #endif |
369 | 369 | ||
370 | #if defined(CONFIG_FSL_BOOKE) | 370 | #if defined(CONFIG_PPC_FSL_BOOK3E) |
371 | /* | 371 | /* |
372 | * extern void loadcam_entry(unsigned int index) | 372 | * extern void loadcam_entry(unsigned int index) |
373 | * | 373 | * |