1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * linux/arch/arm/mm/tlb-v7.S |
4 | * |
5 | * Copyright (C) 1997-2002 Russell King |
6 | * Modified for ARMv7 by Catalin Marinas |
7 | * |
8 | * ARM architecture version 6 TLB handling functions. |
9 | * These assume a split I/D TLB. |
10 | */ |
11 | #include <linux/init.h> |
12 | #include <linux/linkage.h> |
13 | #include <asm/assembler.h> |
14 | #include <asm/asm-offsets.h> |
15 | #include <asm/page.h> |
16 | #include <asm/tlbflush.h> |
17 | #include "proc-macros.S" |
18 | |
19 | .arch armv7-a |
20 | |
21 | /* |
22 | * v7wbi_flush_user_tlb_range(start, end, vma) |
23 | * |
24 | * Invalidate a range of TLB entries in the specified address space. |
25 | * |
26 | * - start - start address (may not be aligned) |
27 | * - end - end address (exclusive, may not be aligned) |
28 | * - vma - vm_area_struct describing address range |
29 | * |
30 | * It is assumed that: |
31 | * - the "Invalidate single entry" instruction will invalidate |
32 | * both the I and the D TLBs on Harvard-style TLBs |
33 | */ |
34 | ENTRY(v7wbi_flush_user_tlb_range) |
35 | vma_vm_mm r3, r2 @ get vma->vm_mm |
36 | mmid r3, r3 @ get vm_mm->context.id |
37 | dsb ish |
38 | mov r0, r0, lsr #PAGE_SHIFT @ align address |
39 | mov r1, r1, lsr #PAGE_SHIFT |
40 | asid r3, r3 @ mask ASID |
41 | #ifdef CONFIG_ARM_ERRATA_720789 |
42 | ALT_SMP(W(mov) r3, #0 ) |
43 | ALT_UP(W(nop) ) |
44 | #endif |
45 | orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA |
46 | mov r1, r1, lsl #PAGE_SHIFT |
47 | 1: |
48 | #ifdef CONFIG_ARM_ERRATA_720789 |
49 | ALT_SMP(mcr p15, 0, r0, c8, c3, 3) @ TLB invalidate U MVA all ASID (shareable) |
50 | #else |
51 | ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable) |
52 | #endif |
53 | ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA |
54 | |
55 | add r0, r0, #PAGE_SZ |
56 | cmp r0, r1 |
57 | blo 1b |
58 | dsb ish |
59 | ret lr |
60 | ENDPROC(v7wbi_flush_user_tlb_range) |
61 | |
62 | /* |
63 | * v7wbi_flush_kern_tlb_range(start,end) |
64 | * |
65 | * Invalidate a range of kernel TLB entries |
66 | * |
67 | * - start - start address (may not be aligned) |
68 | * - end - end address (exclusive, may not be aligned) |
69 | */ |
70 | ENTRY(v7wbi_flush_kern_tlb_range) |
71 | dsb ish |
72 | mov r0, r0, lsr #PAGE_SHIFT @ align address |
73 | mov r1, r1, lsr #PAGE_SHIFT |
74 | mov r0, r0, lsl #PAGE_SHIFT |
75 | mov r1, r1, lsl #PAGE_SHIFT |
76 | 1: |
77 | #ifdef CONFIG_ARM_ERRATA_720789 |
78 | ALT_SMP(mcr p15, 0, r0, c8, c3, 3) @ TLB invalidate U MVA all ASID (shareable) |
79 | #else |
80 | ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable) |
81 | #endif |
82 | ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA |
83 | add r0, r0, #PAGE_SZ |
84 | cmp r0, r1 |
85 | blo 1b |
86 | dsb ish |
87 | isb |
88 | ret lr |
89 | ENDPROC(v7wbi_flush_kern_tlb_range) |
90 | |
91 | __INIT |
92 | |
93 | /* define struct cpu_tlb_fns (see <asm/tlbflush.h> and proc-macros.S) */ |
94 | define_tlb_functions v7wbi, v7wbi_tlb_flags_up, flags_smp=v7wbi_tlb_flags_smp |
95 | |