diff options
Diffstat (limited to 'arch/arm/mm/proc-v7-3level.S')
-rw-r--r-- | arch/arm/mm/proc-v7-3level.S | 53 |
1 files changed, 28 insertions, 25 deletions
diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S index 363027e811d6..5ffe1956c6d9 100644 --- a/arch/arm/mm/proc-v7-3level.S +++ b/arch/arm/mm/proc-v7-3level.S | |||
@@ -39,6 +39,14 @@ | |||
39 | #define TTB_FLAGS_SMP (TTB_IRGN_WBWA|TTB_S|TTB_RGN_OC_WBWA) | 39 | #define TTB_FLAGS_SMP (TTB_IRGN_WBWA|TTB_S|TTB_RGN_OC_WBWA) |
40 | #define PMD_FLAGS_SMP (PMD_SECT_WBWA|PMD_SECT_S) | 40 | #define PMD_FLAGS_SMP (PMD_SECT_WBWA|PMD_SECT_S) |
41 | 41 | ||
42 | #ifndef __ARMEB__ | ||
43 | # define rpgdl r0 | ||
44 | # define rpgdh r1 | ||
45 | #else | ||
46 | # define rpgdl r1 | ||
47 | # define rpgdh r0 | ||
48 | #endif | ||
49 | |||
42 | /* | 50 | /* |
43 | * cpu_v7_switch_mm(pgd_phys, tsk) | 51 | * cpu_v7_switch_mm(pgd_phys, tsk) |
44 | * | 52 | * |
@@ -47,10 +55,10 @@ | |||
47 | */ | 55 | */ |
48 | ENTRY(cpu_v7_switch_mm) | 56 | ENTRY(cpu_v7_switch_mm) |
49 | #ifdef CONFIG_MMU | 57 | #ifdef CONFIG_MMU |
50 | mmid r1, r1 @ get mm->context.id | 58 | mmid r2, r2 |
51 | asid r3, r1 | 59 | asid r2, r2 |
52 | mov r3, r3, lsl #(48 - 32) @ ASID | 60 | orr rpgdh, rpgdh, r2, lsl #(48 - 32) @ upper 32-bits of pgd |
53 | mcrr p15, 0, r0, r3, c2 @ set TTB 0 | 61 | mcrr p15, 0, rpgdl, rpgdh, c2 @ set TTB 0 |
54 | isb | 62 | isb |
55 | #endif | 63 | #endif |
56 | mov pc, lr | 64 | mov pc, lr |
@@ -106,7 +114,8 @@ ENDPROC(cpu_v7_set_pte_ext) | |||
106 | */ | 114 | */ |
107 | .macro v7_ttb_setup, zero, ttbr0, ttbr1, tmp | 115 | .macro v7_ttb_setup, zero, ttbr0, ttbr1, tmp |
108 | ldr \tmp, =swapper_pg_dir @ swapper_pg_dir virtual address | 116 | ldr \tmp, =swapper_pg_dir @ swapper_pg_dir virtual address |
109 | cmp \ttbr1, \tmp @ PHYS_OFFSET > PAGE_OFFSET? (branch below) | 117 | mov \tmp, \tmp, lsr #ARCH_PGD_SHIFT |
118 | cmp \ttbr1, \tmp @ PHYS_OFFSET > PAGE_OFFSET? | ||
110 | mrc p15, 0, \tmp, c2, c0, 2 @ TTB control register | 119 | mrc p15, 0, \tmp, c2, c0, 2 @ TTB control register |
111 | orr \tmp, \tmp, #TTB_EAE | 120 | orr \tmp, \tmp, #TTB_EAE |
112 | ALT_SMP(orr \tmp, \tmp, #TTB_FLAGS_SMP) | 121 | ALT_SMP(orr \tmp, \tmp, #TTB_FLAGS_SMP) |
@@ -114,27 +123,21 @@ ENDPROC(cpu_v7_set_pte_ext) | |||
114 | ALT_SMP(orr \tmp, \tmp, #TTB_FLAGS_SMP << 16) | 123 | ALT_SMP(orr \tmp, \tmp, #TTB_FLAGS_SMP << 16) |
115 | ALT_UP(orr \tmp, \tmp, #TTB_FLAGS_UP << 16) | 124 | ALT_UP(orr \tmp, \tmp, #TTB_FLAGS_UP << 16) |
116 | /* | 125 | /* |
117 | * TTBR0/TTBR1 split (PAGE_OFFSET): | 126 | * Only use split TTBRs if PHYS_OFFSET <= PAGE_OFFSET (cmp above), |
118 | * 0x40000000: T0SZ = 2, T1SZ = 0 (not used) | 127 | * otherwise booting secondary CPUs would end up using TTBR1 for the |
119 | * 0x80000000: T0SZ = 0, T1SZ = 1 | 128 | * identity mapping set up in TTBR0. |
120 | * 0xc0000000: T0SZ = 0, T1SZ = 2 | ||
121 | * | ||
122 | * Only use this feature if PHYS_OFFSET <= PAGE_OFFSET, otherwise | ||
123 | * booting secondary CPUs would end up using TTBR1 for the identity | ||
124 | * mapping set up in TTBR0. | ||
125 | */ | 129 | */ |
126 | bhi 9001f @ PHYS_OFFSET > PAGE_OFFSET? | 130 | orrls \tmp, \tmp, #TTBR1_SIZE @ TTBCR.T1SZ |
127 | orr \tmp, \tmp, #(((PAGE_OFFSET >> 30) - 1) << 16) @ TTBCR.T1SZ | 131 | mcr p15, 0, \tmp, c2, c0, 2 @ TTBCR |
128 | #if defined CONFIG_VMSPLIT_2G | 132 | mov \tmp, \ttbr1, lsr #(32 - ARCH_PGD_SHIFT) @ upper bits |
129 | /* PAGE_OFFSET == 0x80000000, T1SZ == 1 */ | 133 | mov \ttbr1, \ttbr1, lsl #ARCH_PGD_SHIFT @ lower bits |
130 | add \ttbr1, \ttbr1, #1 << 4 @ skip two L1 entries | 134 | addls \ttbr1, \ttbr1, #TTBR1_OFFSET |
131 | #elif defined CONFIG_VMSPLIT_3G | 135 | mcrr p15, 1, \ttbr1, \zero, c2 @ load TTBR1 |
132 | /* PAGE_OFFSET == 0xc0000000, T1SZ == 2 */ | 136 | mov \tmp, \ttbr0, lsr #(32 - ARCH_PGD_SHIFT) @ upper bits |
133 | add \ttbr1, \ttbr1, #4096 * (1 + 3) @ only L2 used, skip pgd+3*pmd | 137 | mov \ttbr0, \ttbr0, lsl #ARCH_PGD_SHIFT @ lower bits |
134 | #endif | 138 | mcrr p15, 0, \ttbr0, \zero, c2 @ load TTBR0 |
135 | /* CONFIG_VMSPLIT_1G does not need TTBR1 adjustment */ | 139 | mcrr p15, 1, \ttbr1, \zero, c2 @ load TTBR1 |
136 | 9001: mcr p15, 0, \tmp, c2, c0, 2 @ TTB control register | 140 | mcrr p15, 0, \ttbr0, \zero, c2 @ load TTBR0 |
137 | mcrr p15, 1, \ttbr1, \zero, c2 @ load TTBR1 | ||
138 | .endm | 141 | .endm |
139 | 142 | ||
140 | __CPUINIT | 143 | __CPUINIT |