diff options
-rw-r--r-- | arch/powerpc/kernel/head_8xx.S | 29 | ||||
-rw-r--r-- | arch/powerpc/mm/8xx_mmu.c | 56 | ||||
-rw-r--r-- | arch/powerpc/mm/mmu_decl.h | 3 |
3 files changed, 86 insertions, 2 deletions
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 378a1858687d..44f4edbd5dee 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S | |||
@@ -384,6 +384,27 @@ InstructionTLBMiss: | |||
384 | EXCEPTION_EPILOG_0 | 384 | EXCEPTION_EPILOG_0 |
385 | rfi | 385 | rfi |
386 | 386 | ||
387 | /* | ||
388 | * Bottom part of DataStoreTLBMiss handler for IMMR area | ||
389 | * not enough space in the DataStoreTLBMiss area | ||
390 | */ | ||
391 | DTLBMissIMMR: | ||
392 | mtcr r3 | ||
393 | /* Set 512k byte guarded page and mark it valid */ | ||
394 | li r10, MD_PS512K | MD_GUARDED | MD_SVALID | ||
395 | MTSPR_CPU6(SPRN_MD_TWC, r10, r3) | ||
396 | mfspr r10, SPRN_IMMR /* Get current IMMR */ | ||
397 | rlwinm r10, r10, 0, 0xfff80000 /* Get 512 kbytes boundary */ | ||
398 | ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_SHARED | _PAGE_DIRTY | \ | ||
399 | _PAGE_PRESENT | _PAGE_NO_CACHE | ||
400 | MTSPR_CPU6(SPRN_MD_RPN, r10, r3) /* Update TLB entry */ | ||
401 | |||
402 | li r11, RPN_PATTERN | ||
403 | mfspr r3, SPRN_SPRG_SCRATCH2 | ||
404 | mtspr SPRN_DAR, r11 /* Tag DAR */ | ||
405 | EXCEPTION_EPILOG_0 | ||
406 | rfi | ||
407 | |||
387 | . = 0x1200 | 408 | . = 0x1200 |
388 | DataStoreTLBMiss: | 409 | DataStoreTLBMiss: |
389 | mtspr SPRN_SPRG_SCRATCH2, r3 | 410 | mtspr SPRN_SPRG_SCRATCH2, r3 |
@@ -397,6 +418,14 @@ DataStoreTLBMiss: | |||
397 | IS_KERNEL(r11, r10) | 418 | IS_KERNEL(r11, r10) |
398 | mfspr r11, SPRN_M_TW /* Get level 1 table */ | 419 | mfspr r11, SPRN_M_TW /* Get level 1 table */ |
399 | BRANCH_UNLESS_KERNEL(3f) | 420 | BRANCH_UNLESS_KERNEL(3f) |
421 | |||
422 | rlwinm r11, r10, 16, 0xfff8 | ||
423 | #ifndef CONFIG_PIN_TLB | ||
424 | cmpli cr0, r11, VIRT_IMMR_BASE@h | ||
425 | _ENTRY(DTLBMiss_jmp) | ||
426 | beq- DTLBMissIMMR | ||
427 | #endif | ||
428 | |||
400 | lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha | 429 | lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha |
401 | 3: | 430 | 3: |
402 | 431 | ||
diff --git a/arch/powerpc/mm/8xx_mmu.c b/arch/powerpc/mm/8xx_mmu.c index 949100577db5..220772579113 100644 --- a/arch/powerpc/mm/8xx_mmu.c +++ b/arch/powerpc/mm/8xx_mmu.c | |||
@@ -13,10 +13,43 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/memblock.h> | 15 | #include <linux/memblock.h> |
16 | #include <asm/fixmap.h> | ||
17 | #include <asm/code-patching.h> | ||
16 | 18 | ||
17 | #include "mmu_decl.h" | 19 | #include "mmu_decl.h" |
18 | 20 | ||
21 | #define IMMR_SIZE (FIX_IMMR_SIZE << PAGE_SHIFT) | ||
22 | |||
19 | extern int __map_without_ltlbs; | 23 | extern int __map_without_ltlbs; |
24 | |||
25 | /* | ||
26 | * Return PA for this VA if it is in IMMR area, or 0 | ||
27 | */ | ||
28 | phys_addr_t v_block_mapped(unsigned long va) | ||
29 | { | ||
30 | unsigned long p = PHYS_IMMR_BASE; | ||
31 | |||
32 | if (__map_without_ltlbs) | ||
33 | return 0; | ||
34 | if (va >= VIRT_IMMR_BASE && va < VIRT_IMMR_BASE + IMMR_SIZE) | ||
35 | return p + va - VIRT_IMMR_BASE; | ||
36 | return 0; | ||
37 | } | ||
38 | |||
39 | /* | ||
40 | * Return VA for a given PA or 0 if not mapped | ||
41 | */ | ||
42 | unsigned long p_block_mapped(phys_addr_t pa) | ||
43 | { | ||
44 | unsigned long p = PHYS_IMMR_BASE; | ||
45 | |||
46 | if (__map_without_ltlbs) | ||
47 | return 0; | ||
48 | if (pa >= p && pa < p + IMMR_SIZE) | ||
49 | return VIRT_IMMR_BASE + pa - p; | ||
50 | return 0; | ||
51 | } | ||
52 | |||
20 | /* | 53 | /* |
21 | * MMU_init_hw does the chip-specific initialization of the MMU hardware. | 54 | * MMU_init_hw does the chip-specific initialization of the MMU hardware. |
22 | */ | 55 | */ |
@@ -29,6 +62,22 @@ void __init MMU_init_hw(void) | |||
29 | #define LARGE_PAGE_SIZE_8M (1<<23) | 62 | #define LARGE_PAGE_SIZE_8M (1<<23) |
30 | #define LARGE_PAGE_SIZE_64M (1<<26) | 63 | #define LARGE_PAGE_SIZE_64M (1<<26) |
31 | 64 | ||
65 | static void mmu_mapin_immr(void) | ||
66 | { | ||
67 | unsigned long p = PHYS_IMMR_BASE; | ||
68 | unsigned long v = VIRT_IMMR_BASE; | ||
69 | unsigned long f = pgprot_val(PAGE_KERNEL_NCG); | ||
70 | int offset; | ||
71 | |||
72 | for (offset = 0; offset < IMMR_SIZE; offset += PAGE_SIZE) | ||
73 | map_page(v + offset, p + offset, f); | ||
74 | } | ||
75 | |||
76 | /* Address of instructions to patch */ | ||
77 | #ifndef CONFIG_PIN_TLB | ||
78 | extern unsigned int DTLBMiss_jmp; | ||
79 | #endif | ||
80 | |||
32 | unsigned long __init mmu_mapin_ram(unsigned long top) | 81 | unsigned long __init mmu_mapin_ram(unsigned long top) |
33 | { | 82 | { |
34 | unsigned long v, s, mapped; | 83 | unsigned long v, s, mapped; |
@@ -38,8 +87,13 @@ unsigned long __init mmu_mapin_ram(unsigned long top) | |||
38 | p = 0; | 87 | p = 0; |
39 | s = top; | 88 | s = top; |
40 | 89 | ||
41 | if (__map_without_ltlbs) | 90 | if (__map_without_ltlbs) { |
91 | mmu_mapin_immr(); | ||
92 | #ifndef CONFIG_PIN_TLB | ||
93 | patch_instruction(&DTLBMiss_jmp, PPC_INST_NOP); | ||
94 | #endif | ||
42 | return 0; | 95 | return 0; |
96 | } | ||
43 | 97 | ||
44 | #ifdef CONFIG_PPC_4K_PAGES | 98 | #ifdef CONFIG_PPC_4K_PAGES |
45 | while (s >= LARGE_PAGE_SIZE_8M) { | 99 | while (s >= LARGE_PAGE_SIZE_8M) { |
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h index 6af65327c993..f988db655e5b 100644 --- a/arch/powerpc/mm/mmu_decl.h +++ b/arch/powerpc/mm/mmu_decl.h | |||
@@ -154,9 +154,10 @@ struct tlbcam { | |||
154 | }; | 154 | }; |
155 | #endif | 155 | #endif |
156 | 156 | ||
157 | #if defined(CONFIG_6xx) || defined(CONFIG_FSL_BOOKE) | 157 | #if defined(CONFIG_6xx) || defined(CONFIG_FSL_BOOKE) || defined(CONFIG_PPC_8xx) |
158 | /* 6xx have BATS */ | 158 | /* 6xx have BATS */ |
159 | /* FSL_BOOKE have TLBCAM */ | 159 | /* FSL_BOOKE have TLBCAM */ |
160 | /* 8xx have LTLB */ | ||
160 | phys_addr_t v_block_mapped(unsigned long va); | 161 | phys_addr_t v_block_mapped(unsigned long va); |
161 | unsigned long p_block_mapped(phys_addr_t pa); | 162 | unsigned long p_block_mapped(phys_addr_t pa); |
162 | #else | 163 | #else |