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