sync-cache.c revision 1.9 1 1.1 mrg /* Machine description for AArch64 architecture.
2 1.9 mrg Copyright (C) 2012-2020 Free Software Foundation, Inc.
3 1.1 mrg Contributed by ARM Ltd.
4 1.1 mrg
5 1.1 mrg This file is part of GCC.
6 1.1 mrg
7 1.1 mrg GCC is free software; you can redistribute it and/or modify it under
8 1.1 mrg the terms of the GNU General Public License as published by the Free
9 1.1 mrg Software Foundation; either version 3, or (at your option) any later
10 1.1 mrg version.
11 1.1 mrg
12 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 1.1 mrg for more details.
16 1.1 mrg
17 1.1 mrg Under Section 7 of GPL version 3, you are granted additional
18 1.1 mrg permissions described in the GCC Runtime Library Exception, version
19 1.1 mrg 3.1, as published by the Free Software Foundation.
20 1.1 mrg
21 1.1 mrg You should have received a copy of the GNU General Public License and
22 1.1 mrg a copy of the GCC Runtime Library Exception along with this program;
23 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 1.1 mrg <http://www.gnu.org/licenses/>. */
25 1.1 mrg
26 1.9 mrg #define CTR_IDC_SHIFT 28
27 1.9 mrg #define CTR_DIC_SHIFT 29
28 1.9 mrg
29 1.1 mrg void __aarch64_sync_cache_range (const void *, const void *);
30 1.1 mrg
31 1.1 mrg void
32 1.1 mrg __aarch64_sync_cache_range (const void *base, const void *end)
33 1.1 mrg {
34 1.1 mrg unsigned icache_lsize;
35 1.1 mrg unsigned dcache_lsize;
36 1.1 mrg static unsigned int cache_info = 0;
37 1.1 mrg const char *address;
38 1.1 mrg
39 1.1 mrg if (! cache_info)
40 1.1 mrg /* CTR_EL0 [3:0] contains log2 of icache line size in words.
41 1.1 mrg CTR_EL0 [19:16] contains log2 of dcache line size in words. */
42 1.1 mrg asm volatile ("mrs\t%0, ctr_el0":"=r" (cache_info));
43 1.1 mrg
44 1.1 mrg icache_lsize = 4 << (cache_info & 0xF);
45 1.1 mrg dcache_lsize = 4 << ((cache_info >> 16) & 0xF);
46 1.1 mrg
47 1.9 mrg /* If CTR_EL0.IDC is enabled, Data cache clean to the Point of Unification is
48 1.9 mrg not required for instruction to data coherence. */
49 1.9 mrg
50 1.9 mrg if (((cache_info >> CTR_IDC_SHIFT) & 0x1) == 0x0) {
51 1.9 mrg /* Loop over the address range, clearing one cache line at once.
52 1.9 mrg Data cache must be flushed to unification first to make sure the
53 1.9 mrg instruction cache fetches the updated data. 'end' is exclusive,
54 1.9 mrg as per the GNU definition of __clear_cache. */
55 1.9 mrg
56 1.9 mrg /* Make the start address of the loop cache aligned. */
57 1.9 mrg address = (const char*) ((__UINTPTR_TYPE__) base
58 1.9 mrg & ~ (__UINTPTR_TYPE__) (dcache_lsize - 1));
59 1.9 mrg
60 1.9 mrg for (; address < (const char *) end; address += dcache_lsize)
61 1.9 mrg asm volatile ("dc\tcvau, %0"
62 1.9 mrg :
63 1.9 mrg : "r" (address)
64 1.9 mrg : "memory");
65 1.9 mrg }
66 1.1 mrg
67 1.1 mrg asm volatile ("dsb\tish" : : : "memory");
68 1.1 mrg
69 1.9 mrg /* If CTR_EL0.DIC is enabled, Instruction cache cleaning to the Point of
70 1.9 mrg Unification is not required for instruction to data coherence. */
71 1.9 mrg
72 1.9 mrg if (((cache_info >> CTR_DIC_SHIFT) & 0x1) == 0x0) {
73 1.9 mrg /* Make the start address of the loop cache aligned. */
74 1.9 mrg address = (const char*) ((__UINTPTR_TYPE__) base
75 1.9 mrg & ~ (__UINTPTR_TYPE__) (icache_lsize - 1));
76 1.9 mrg
77 1.9 mrg for (; address < (const char *) end; address += icache_lsize)
78 1.9 mrg asm volatile ("ic\tivau, %0"
79 1.9 mrg :
80 1.9 mrg : "r" (address)
81 1.9 mrg : "memory");
82 1.9 mrg
83 1.9 mrg asm volatile ("dsb\tish" : : : "memory");
84 1.9 mrg }
85 1.1 mrg
86 1.9 mrg asm volatile("isb" : : : "memory");
87 1.1 mrg }
88