diff options
author | Catalin Marinas <catalin.marinas@arm.com> | 2011-11-22 12:30:29 -0500 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2011-12-08 05:30:39 -0500 |
commit | 1b6ba46b7efa31055eb993a6f2c6bbcb8b35b001 (patch) | |
tree | b04e3b1fd23ba81a643f64cba113551d127111a0 /arch/arm/mm | |
parent | da02877987e6e173ebba137d4e1e155e1f1151cd (diff) |
ARM: LPAE: MMU setup for the 3-level page table format
This patch adds the MMU initialisation for the LPAE page table format.
The swapper_pg_dir size with LPAE is 5 rather than 4 pages. A new
proc-v7-3level.S file contains the TTB initialisation, context switch
and PTE setting code with the LPAE. The TTBRx split is based on the
PAGE_OFFSET with TTBR1 used for the kernel mappings. The 36-bit mappings
(supersections) and a few other memory types in mmu.c are conditionally
compiled.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm/mm')
-rw-r--r-- | arch/arm/mm/mmu.c | 30 | ||||
-rw-r--r-- | arch/arm/mm/proc-macros.S | 5 | ||||
-rw-r--r-- | arch/arm/mm/proc-v7-3level.S | 150 | ||||
-rw-r--r-- | arch/arm/mm/proc-v7.S | 25 |
4 files changed, 200 insertions, 10 deletions
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index dc8c550e6cbd..1935311e17fc 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
@@ -150,6 +150,7 @@ static int __init early_nowrite(char *__unused) | |||
150 | } | 150 | } |
151 | early_param("nowb", early_nowrite); | 151 | early_param("nowb", early_nowrite); |
152 | 152 | ||
153 | #ifndef CONFIG_ARM_LPAE | ||
153 | static int __init early_ecc(char *p) | 154 | static int __init early_ecc(char *p) |
154 | { | 155 | { |
155 | if (memcmp(p, "on", 2) == 0) | 156 | if (memcmp(p, "on", 2) == 0) |
@@ -159,6 +160,7 @@ static int __init early_ecc(char *p) | |||
159 | return 0; | 160 | return 0; |
160 | } | 161 | } |
161 | early_param("ecc", early_ecc); | 162 | early_param("ecc", early_ecc); |
163 | #endif | ||
162 | 164 | ||
163 | static int __init noalign_setup(char *__unused) | 165 | static int __init noalign_setup(char *__unused) |
164 | { | 166 | { |
@@ -228,10 +230,12 @@ static struct mem_type mem_types[] = { | |||
228 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN, | 230 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN, |
229 | .domain = DOMAIN_KERNEL, | 231 | .domain = DOMAIN_KERNEL, |
230 | }, | 232 | }, |
233 | #ifndef CONFIG_ARM_LPAE | ||
231 | [MT_MINICLEAN] = { | 234 | [MT_MINICLEAN] = { |
232 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_MINICACHE, | 235 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_MINICACHE, |
233 | .domain = DOMAIN_KERNEL, | 236 | .domain = DOMAIN_KERNEL, |
234 | }, | 237 | }, |
238 | #endif | ||
235 | [MT_LOW_VECTORS] = { | 239 | [MT_LOW_VECTORS] = { |
236 | .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | | 240 | .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | |
237 | L_PTE_RDONLY, | 241 | L_PTE_RDONLY, |
@@ -429,6 +433,7 @@ static void __init build_mem_type_table(void) | |||
429 | * ARMv6 and above have extended page tables. | 433 | * ARMv6 and above have extended page tables. |
430 | */ | 434 | */ |
431 | if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) { | 435 | if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) { |
436 | #ifndef CONFIG_ARM_LPAE | ||
432 | /* | 437 | /* |
433 | * Mark cache clean areas and XIP ROM read only | 438 | * Mark cache clean areas and XIP ROM read only |
434 | * from SVC mode and no access from userspace. | 439 | * from SVC mode and no access from userspace. |
@@ -436,6 +441,7 @@ static void __init build_mem_type_table(void) | |||
436 | mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; | 441 | mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; |
437 | mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; | 442 | mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; |
438 | mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; | 443 | mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; |
444 | #endif | ||
439 | 445 | ||
440 | if (is_smp()) { | 446 | if (is_smp()) { |
441 | /* | 447 | /* |
@@ -474,6 +480,18 @@ static void __init build_mem_type_table(void) | |||
474 | mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_BUFFERABLE; | 480 | mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_BUFFERABLE; |
475 | } | 481 | } |
476 | 482 | ||
483 | #ifdef CONFIG_ARM_LPAE | ||
484 | /* | ||
485 | * Do not generate access flag faults for the kernel mappings. | ||
486 | */ | ||
487 | for (i = 0; i < ARRAY_SIZE(mem_types); i++) { | ||
488 | mem_types[i].prot_pte |= PTE_EXT_AF; | ||
489 | mem_types[i].prot_sect |= PMD_SECT_AF; | ||
490 | } | ||
491 | kern_pgprot |= PTE_EXT_AF; | ||
492 | vecs_pgprot |= PTE_EXT_AF; | ||
493 | #endif | ||
494 | |||
477 | for (i = 0; i < 16; i++) { | 495 | for (i = 0; i < 16; i++) { |
478 | unsigned long v = pgprot_val(protection_map[i]); | 496 | unsigned long v = pgprot_val(protection_map[i]); |
479 | protection_map[i] = __pgprot(v | user_pgprot); | 497 | protection_map[i] = __pgprot(v | user_pgprot); |
@@ -572,8 +590,10 @@ static void __init alloc_init_section(pud_t *pud, unsigned long addr, | |||
572 | if (((addr | end | phys) & ~SECTION_MASK) == 0) { | 590 | if (((addr | end | phys) & ~SECTION_MASK) == 0) { |
573 | pmd_t *p = pmd; | 591 | pmd_t *p = pmd; |
574 | 592 | ||
593 | #ifndef CONFIG_ARM_LPAE | ||
575 | if (addr & SECTION_SIZE) | 594 | if (addr & SECTION_SIZE) |
576 | pmd++; | 595 | pmd++; |
596 | #endif | ||
577 | 597 | ||
578 | do { | 598 | do { |
579 | *pmd = __pmd(phys | type->prot_sect); | 599 | *pmd = __pmd(phys | type->prot_sect); |
@@ -603,6 +623,7 @@ static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end, | |||
603 | } while (pud++, addr = next, addr != end); | 623 | } while (pud++, addr = next, addr != end); |
604 | } | 624 | } |
605 | 625 | ||
626 | #ifndef CONFIG_ARM_LPAE | ||
606 | static void __init create_36bit_mapping(struct map_desc *md, | 627 | static void __init create_36bit_mapping(struct map_desc *md, |
607 | const struct mem_type *type) | 628 | const struct mem_type *type) |
608 | { | 629 | { |
@@ -662,6 +683,7 @@ static void __init create_36bit_mapping(struct map_desc *md, | |||
662 | pgd += SUPERSECTION_SIZE >> PGDIR_SHIFT; | 683 | pgd += SUPERSECTION_SIZE >> PGDIR_SHIFT; |
663 | } while (addr != end); | 684 | } while (addr != end); |
664 | } | 685 | } |
686 | #endif /* !CONFIG_ARM_LPAE */ | ||
665 | 687 | ||
666 | /* | 688 | /* |
667 | * Create the page directory entries and any necessary | 689 | * Create the page directory entries and any necessary |
@@ -693,6 +715,7 @@ static void __init create_mapping(struct map_desc *md) | |||
693 | 715 | ||
694 | type = &mem_types[md->type]; | 716 | type = &mem_types[md->type]; |
695 | 717 | ||
718 | #ifndef CONFIG_ARM_LPAE | ||
696 | /* | 719 | /* |
697 | * Catch 36-bit addresses | 720 | * Catch 36-bit addresses |
698 | */ | 721 | */ |
@@ -700,6 +723,7 @@ static void __init create_mapping(struct map_desc *md) | |||
700 | create_36bit_mapping(md, type); | 723 | create_36bit_mapping(md, type); |
701 | return; | 724 | return; |
702 | } | 725 | } |
726 | #endif | ||
703 | 727 | ||
704 | addr = md->virtual & PAGE_MASK; | 728 | addr = md->virtual & PAGE_MASK; |
705 | phys = __pfn_to_phys(md->pfn); | 729 | phys = __pfn_to_phys(md->pfn); |
@@ -897,7 +921,13 @@ static inline void prepare_page_table(void) | |||
897 | pmd_clear(pmd_off_k(addr)); | 921 | pmd_clear(pmd_off_k(addr)); |
898 | } | 922 | } |
899 | 923 | ||
924 | #ifdef CONFIG_ARM_LPAE | ||
925 | /* the first page is reserved for pgd */ | ||
926 | #define SWAPPER_PG_DIR_SIZE (PAGE_SIZE + \ | ||
927 | PTRS_PER_PGD * PTRS_PER_PMD * sizeof(pmd_t)) | ||
928 | #else | ||
900 | #define SWAPPER_PG_DIR_SIZE (PTRS_PER_PGD * sizeof(pgd_t)) | 929 | #define SWAPPER_PG_DIR_SIZE (PTRS_PER_PGD * sizeof(pgd_t)) |
930 | #endif | ||
901 | 931 | ||
902 | /* | 932 | /* |
903 | * Reserve the special regions of memory | 933 | * Reserve the special regions of memory |
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S index 307a4def8d3a..2d8ff3ad86d3 100644 --- a/arch/arm/mm/proc-macros.S +++ b/arch/arm/mm/proc-macros.S | |||
@@ -91,8 +91,9 @@ | |||
91 | #if L_PTE_SHARED != PTE_EXT_SHARED | 91 | #if L_PTE_SHARED != PTE_EXT_SHARED |
92 | #error PTE shared bit mismatch | 92 | #error PTE shared bit mismatch |
93 | #endif | 93 | #endif |
94 | #if (L_PTE_XN+L_PTE_USER+L_PTE_RDONLY+L_PTE_DIRTY+L_PTE_YOUNG+\ | 94 | #if !defined (CONFIG_ARM_LPAE) && \ |
95 | L_PTE_FILE+L_PTE_PRESENT) > L_PTE_SHARED | 95 | (L_PTE_XN+L_PTE_USER+L_PTE_RDONLY+L_PTE_DIRTY+L_PTE_YOUNG+\ |
96 | L_PTE_FILE+L_PTE_PRESENT) > L_PTE_SHARED | ||
96 | #error Invalid Linux PTE bit settings | 97 | #error Invalid Linux PTE bit settings |
97 | #endif | 98 | #endif |
98 | #endif /* CONFIG_MMU */ | 99 | #endif /* CONFIG_MMU */ |
diff --git a/arch/arm/mm/proc-v7-3level.S b/arch/arm/mm/proc-v7-3level.S new file mode 100644 index 000000000000..8de0f1dd1549 --- /dev/null +++ b/arch/arm/mm/proc-v7-3level.S | |||
@@ -0,0 +1,150 @@ | |||
1 | /* | ||
2 | * arch/arm/mm/proc-v7-3level.S | ||
3 | * | ||
4 | * Copyright (C) 2001 Deep Blue Solutions Ltd. | ||
5 | * Copyright (C) 2011 ARM Ltd. | ||
6 | * Author: Catalin Marinas <catalin.marinas@arm.com> | ||
7 | * based on arch/arm/mm/proc-v7-2level.S | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #define TTB_IRGN_NC (0 << 8) | ||
24 | #define TTB_IRGN_WBWA (1 << 8) | ||
25 | #define TTB_IRGN_WT (2 << 8) | ||
26 | #define TTB_IRGN_WB (3 << 8) | ||
27 | #define TTB_RGN_NC (0 << 10) | ||
28 | #define TTB_RGN_OC_WBWA (1 << 10) | ||
29 | #define TTB_RGN_OC_WT (2 << 10) | ||
30 | #define TTB_RGN_OC_WB (3 << 10) | ||
31 | #define TTB_S (3 << 12) | ||
32 | #define TTB_EAE (1 << 31) | ||
33 | |||
34 | /* PTWs cacheable, inner WB not shareable, outer WB not shareable */ | ||
35 | #define TTB_FLAGS_UP (TTB_IRGN_WB|TTB_RGN_OC_WB) | ||
36 | #define PMD_FLAGS_UP (PMD_SECT_WB) | ||
37 | |||
38 | /* PTWs cacheable, inner WBWA shareable, outer WBWA not shareable */ | ||
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) | ||
41 | |||
42 | /* | ||
43 | * cpu_v7_switch_mm(pgd_phys, tsk) | ||
44 | * | ||
45 | * Set the translation table base pointer to be pgd_phys (physical address of | ||
46 | * the new TTB). | ||
47 | */ | ||
48 | ENTRY(cpu_v7_switch_mm) | ||
49 | #ifdef CONFIG_MMU | ||
50 | ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id | ||
51 | and r3, r1, #0xff | ||
52 | mov r3, r3, lsl #(48 - 32) @ ASID | ||
53 | mcrr p15, 0, r0, r3, c2 @ set TTB 0 | ||
54 | isb | ||
55 | #endif | ||
56 | mov pc, lr | ||
57 | ENDPROC(cpu_v7_switch_mm) | ||
58 | |||
59 | /* | ||
60 | * cpu_v7_set_pte_ext(ptep, pte) | ||
61 | * | ||
62 | * Set a level 2 translation table entry. | ||
63 | * - ptep - pointer to level 3 translation table entry | ||
64 | * - pte - PTE value to store (64-bit in r2 and r3) | ||
65 | */ | ||
66 | ENTRY(cpu_v7_set_pte_ext) | ||
67 | #ifdef CONFIG_MMU | ||
68 | tst r2, #L_PTE_PRESENT | ||
69 | beq 1f | ||
70 | tst r3, #1 << (55 - 32) @ L_PTE_DIRTY | ||
71 | orreq r2, #L_PTE_RDONLY | ||
72 | 1: strd r2, r3, [r0] | ||
73 | mcr p15, 0, r0, c7, c10, 1 @ flush_pte | ||
74 | #endif | ||
75 | mov pc, lr | ||
76 | ENDPROC(cpu_v7_set_pte_ext) | ||
77 | |||
78 | /* | ||
79 | * Memory region attributes for LPAE (defined in pgtable-3level.h): | ||
80 | * | ||
81 | * n = AttrIndx[2:0] | ||
82 | * | ||
83 | * n MAIR | ||
84 | * UNCACHED 000 00000000 | ||
85 | * BUFFERABLE 001 01000100 | ||
86 | * DEV_WC 001 01000100 | ||
87 | * WRITETHROUGH 010 10101010 | ||
88 | * WRITEBACK 011 11101110 | ||
89 | * DEV_CACHED 011 11101110 | ||
90 | * DEV_SHARED 100 00000100 | ||
91 | * DEV_NONSHARED 100 00000100 | ||
92 | * unused 101 | ||
93 | * unused 110 | ||
94 | * WRITEALLOC 111 11111111 | ||
95 | */ | ||
96 | .equ PRRR, 0xeeaa4400 @ MAIR0 | ||
97 | .equ NMRR, 0xff000004 @ MAIR1 | ||
98 | |||
99 | /* | ||
100 | * Macro for setting up the TTBRx and TTBCR registers. | ||
101 | * - \ttbr1 updated. | ||
102 | */ | ||
103 | .macro v7_ttb_setup, zero, ttbr0, ttbr1, tmp | ||
104 | ldr \tmp, =swapper_pg_dir @ swapper_pg_dir virtual address | ||
105 | cmp \ttbr1, \tmp @ PHYS_OFFSET > PAGE_OFFSET? (branch below) | ||
106 | mrc p15, 0, \tmp, c2, c0, 2 @ TTB control register | ||
107 | orr \tmp, \tmp, #TTB_EAE | ||
108 | ALT_SMP(orr \tmp, \tmp, #TTB_FLAGS_SMP) | ||
109 | ALT_UP(orr \tmp, \tmp, #TTB_FLAGS_UP) | ||
110 | ALT_SMP(orr \tmp, \tmp, #TTB_FLAGS_SMP << 16) | ||
111 | ALT_UP(orr \tmp, \tmp, #TTB_FLAGS_UP << 16) | ||
112 | /* | ||
113 | * TTBR0/TTBR1 split (PAGE_OFFSET): | ||
114 | * 0x40000000: T0SZ = 2, T1SZ = 0 (not used) | ||
115 | * 0x80000000: T0SZ = 0, T1SZ = 1 | ||
116 | * 0xc0000000: T0SZ = 0, T1SZ = 2 | ||
117 | * | ||
118 | * Only use this feature if PHYS_OFFSET <= PAGE_OFFSET, otherwise | ||
119 | * booting secondary CPUs would end up using TTBR1 for the identity | ||
120 | * mapping set up in TTBR0. | ||
121 | */ | ||
122 | bhi 9001f @ PHYS_OFFSET > PAGE_OFFSET? | ||
123 | orr \tmp, \tmp, #(((PAGE_OFFSET >> 30) - 1) << 16) @ TTBCR.T1SZ | ||
124 | #if defined CONFIG_VMSPLIT_2G | ||
125 | /* PAGE_OFFSET == 0x80000000, T1SZ == 1 */ | ||
126 | add \ttbr1, \ttbr1, #1 << 4 @ skip two L1 entries | ||
127 | #elif defined CONFIG_VMSPLIT_3G | ||
128 | /* PAGE_OFFSET == 0xc0000000, T1SZ == 2 */ | ||
129 | add \ttbr1, \ttbr1, #4096 * (1 + 3) @ only L2 used, skip pgd+3*pmd | ||
130 | #endif | ||
131 | /* CONFIG_VMSPLIT_1G does not need TTBR1 adjustment */ | ||
132 | 9001: mcr p15, 0, \tmp, c2, c0, 2 @ TTB control register | ||
133 | mcrr p15, 1, \ttbr1, \zero, c2 @ load TTBR1 | ||
134 | .endm | ||
135 | |||
136 | __CPUINIT | ||
137 | |||
138 | /* | ||
139 | * AT | ||
140 | * TFR EV X F IHD LR S | ||
141 | * .EEE ..EE PUI. .TAT 4RVI ZWRS BLDP WCAM | ||
142 | * rxxx rrxx xxx0 0101 xxxx xxxx x111 xxxx < forced | ||
143 | * 11 0 110 1 0011 1100 .111 1101 < we want | ||
144 | */ | ||
145 | .align 2 | ||
146 | .type v7_crval, #object | ||
147 | v7_crval: | ||
148 | crval clear=0x0120c302, mmuset=0x30c23c7d, ucset=0x00c01c7c | ||
149 | |||
150 | .previous | ||
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index ed1a4d115331..7efa2a721d5d 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S | |||
@@ -19,7 +19,11 @@ | |||
19 | 19 | ||
20 | #include "proc-macros.S" | 20 | #include "proc-macros.S" |
21 | 21 | ||
22 | #ifdef CONFIG_ARM_LPAE | ||
23 | #include "proc-v7-3level.S" | ||
24 | #else | ||
22 | #include "proc-v7-2level.S" | 25 | #include "proc-v7-2level.S" |
26 | #endif | ||
23 | 27 | ||
24 | ENTRY(cpu_v7_proc_init) | 28 | ENTRY(cpu_v7_proc_init) |
25 | mov pc, lr | 29 | mov pc, lr |
@@ -87,7 +91,7 @@ ENDPROC(cpu_v7_dcache_clean_area) | |||
87 | 91 | ||
88 | /* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */ | 92 | /* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */ |
89 | .globl cpu_v7_suspend_size | 93 | .globl cpu_v7_suspend_size |
90 | .equ cpu_v7_suspend_size, 4 * 7 | 94 | .equ cpu_v7_suspend_size, 4 * 8 |
91 | #ifdef CONFIG_ARM_CPU_SUSPEND | 95 | #ifdef CONFIG_ARM_CPU_SUSPEND |
92 | ENTRY(cpu_v7_do_suspend) | 96 | ENTRY(cpu_v7_do_suspend) |
93 | stmfd sp!, {r4 - r10, lr} | 97 | stmfd sp!, {r4 - r10, lr} |
@@ -96,10 +100,11 @@ ENTRY(cpu_v7_do_suspend) | |||
96 | stmia r0!, {r4 - r5} | 100 | stmia r0!, {r4 - r5} |
97 | mrc p15, 0, r6, c3, c0, 0 @ Domain ID | 101 | mrc p15, 0, r6, c3, c0, 0 @ Domain ID |
98 | mrc p15, 0, r7, c2, c0, 1 @ TTB 1 | 102 | mrc p15, 0, r7, c2, c0, 1 @ TTB 1 |
103 | mrc p15, 0, r11, c2, c0, 2 @ TTB control register | ||
99 | mrc p15, 0, r8, c1, c0, 0 @ Control register | 104 | mrc p15, 0, r8, c1, c0, 0 @ Control register |
100 | mrc p15, 0, r9, c1, c0, 1 @ Auxiliary control register | 105 | mrc p15, 0, r9, c1, c0, 1 @ Auxiliary control register |
101 | mrc p15, 0, r10, c1, c0, 2 @ Co-processor access control | 106 | mrc p15, 0, r10, c1, c0, 2 @ Co-processor access control |
102 | stmia r0, {r6 - r10} | 107 | stmia r0, {r6 - r11} |
103 | ldmfd sp!, {r4 - r10, pc} | 108 | ldmfd sp!, {r4 - r10, pc} |
104 | ENDPROC(cpu_v7_do_suspend) | 109 | ENDPROC(cpu_v7_do_suspend) |
105 | 110 | ||
@@ -111,13 +116,15 @@ ENTRY(cpu_v7_do_resume) | |||
111 | ldmia r0!, {r4 - r5} | 116 | ldmia r0!, {r4 - r5} |
112 | mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID | 117 | mcr p15, 0, r4, c13, c0, 0 @ FCSE/PID |
113 | mcr p15, 0, r5, c13, c0, 3 @ User r/o thread ID | 118 | mcr p15, 0, r5, c13, c0, 3 @ User r/o thread ID |
114 | ldmia r0, {r6 - r10} | 119 | ldmia r0, {r6 - r11} |
115 | mcr p15, 0, r6, c3, c0, 0 @ Domain ID | 120 | mcr p15, 0, r6, c3, c0, 0 @ Domain ID |
121 | #ifndef CONFIG_ARM_LPAE | ||
116 | ALT_SMP(orr r1, r1, #TTB_FLAGS_SMP) | 122 | ALT_SMP(orr r1, r1, #TTB_FLAGS_SMP) |
117 | ALT_UP(orr r1, r1, #TTB_FLAGS_UP) | 123 | ALT_UP(orr r1, r1, #TTB_FLAGS_UP) |
124 | #endif | ||
118 | mcr p15, 0, r1, c2, c0, 0 @ TTB 0 | 125 | mcr p15, 0, r1, c2, c0, 0 @ TTB 0 |
119 | mcr p15, 0, r7, c2, c0, 1 @ TTB 1 | 126 | mcr p15, 0, r7, c2, c0, 1 @ TTB 1 |
120 | mcr p15, 0, ip, c2, c0, 2 @ TTB control register | 127 | mcr p15, 0, r11, c2, c0, 2 @ TTB control register |
121 | mrc p15, 0, r4, c1, c0, 1 @ Read Auxiliary control register | 128 | mrc p15, 0, r4, c1, c0, 1 @ Read Auxiliary control register |
122 | teq r4, r9 @ Is it already set? | 129 | teq r4, r9 @ Is it already set? |
123 | mcrne p15, 0, r9, c1, c0, 1 @ No, so write it | 130 | mcrne p15, 0, r9, c1, c0, 1 @ No, so write it |
@@ -291,11 +298,11 @@ __v7_setup_stack: | |||
291 | */ | 298 | */ |
292 | .macro __v7_proc initfunc, mm_mmuflags = 0, io_mmuflags = 0, hwcaps = 0 | 299 | .macro __v7_proc initfunc, mm_mmuflags = 0, io_mmuflags = 0, hwcaps = 0 |
293 | ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \ | 300 | ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \ |
294 | PMD_FLAGS_SMP | \mm_mmuflags) | 301 | PMD_SECT_AF | PMD_FLAGS_SMP | \mm_mmuflags) |
295 | ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \ | 302 | ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \ |
296 | PMD_FLAGS_UP | \mm_mmuflags) | 303 | PMD_SECT_AF | PMD_FLAGS_UP | \mm_mmuflags) |
297 | .long PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_AP_WRITE | \ | 304 | .long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | \ |
298 | PMD_SECT_AP_READ | \io_mmuflags | 305 | PMD_SECT_AP_READ | PMD_SECT_AF | \io_mmuflags |
299 | W(b) \initfunc | 306 | W(b) \initfunc |
300 | .long cpu_arch_name | 307 | .long cpu_arch_name |
301 | .long cpu_elf_name | 308 | .long cpu_elf_name |
@@ -308,6 +315,7 @@ __v7_setup_stack: | |||
308 | .long v7_cache_fns | 315 | .long v7_cache_fns |
309 | .endm | 316 | .endm |
310 | 317 | ||
318 | #ifndef CONFIG_ARM_LPAE | ||
311 | /* | 319 | /* |
312 | * ARM Ltd. Cortex A5 processor. | 320 | * ARM Ltd. Cortex A5 processor. |
313 | */ | 321 | */ |
@@ -327,6 +335,7 @@ __v7_ca9mp_proc_info: | |||
327 | .long 0xff0ffff0 | 335 | .long 0xff0ffff0 |
328 | __v7_proc __v7_ca9mp_setup | 336 | __v7_proc __v7_ca9mp_setup |
329 | .size __v7_ca9mp_proc_info, . - __v7_ca9mp_proc_info | 337 | .size __v7_ca9mp_proc_info, . - __v7_ca9mp_proc_info |
338 | #endif /* CONFIG_ARM_LPAE */ | ||
330 | 339 | ||
331 | /* | 340 | /* |
332 | * ARM Ltd. Cortex A15 processor. | 341 | * ARM Ltd. Cortex A15 processor. |