1/*
2 * Copyright (c) 2014, Google Inc. All rights reserved
3 * Copyright 2016 The Fuchsia Authors
4 *
5 * Use of this source code is governed by a MIT-style
6 * license that can be found in the LICENSE file or at
7 * https://opensource.org/licenses/MIT
8 */
9
10#include <lk/asm.h>
11#include <arch/ops.h>
12#include <arch/defines.h>
13#include <arch/arm64/cache_loop.h>
14
15.text
16
17// Routines to flush the cache by address on the local cpu.
18// NOTE: the following routines do not touch the stack and only use x0-x3
19// so can be safely called from assembly that is aware of this.
20
21.macro cache_range_op, cache op
22    add     x2, x0, x1                  // calculate the end address
23    bic     x3, x0, #(CACHE_LINE-1)     // align the start with a cache line
24.Lcache_range_op_loop\@:
25    \cache  \op, x3
26    add     x3, x3, #CACHE_LINE
27    cmp     x3, x2
28    blo     .Lcache_range_op_loop\@
29    dsb     sy
30.endm
31
32    /* void arch_flush_cache_range(addr_t start, size_t len); */
33FUNCTION(arch_clean_cache_range)
34    cache_range_op dc cvac         // clean cache to PoC by MVA
35    ret
36END_FUNCTION(arch_clean_cache_range)
37
38    /* void arch_flush_invalidate_cache_range(addr_t start, size_t len); */
39FUNCTION(arch_clean_invalidate_cache_range)
40    cache_range_op dc civac        // clean & invalidate dcache to PoC by MVA
41    ret
42END_FUNCTION(arch_clean_invalidate_cache_range)
43
44    /* void arch_invalidate_cache_range(addr_t start, size_t len); */
45FUNCTION(arch_invalidate_cache_range)
46    cache_range_op dc ivac         // invalidate dcache to PoC by MVA
47    ret
48END_FUNCTION(arch_invalidate_cache_range)
49
50    /* void arch_sync_cache_range(addr_t start, size_t len); */
51FUNCTION(arch_sync_cache_range)
52    cache_range_op dc cvau         // clean dcache to PoU by MVA
53    cache_range_op ic ivau         // invalidate icache to PoU by MVA
54    ret
55END_FUNCTION(arch_sync_cache_range)
56
57// Below are 3 variants of cache flushing routines by way/set for
58// an individual cpu.
59// NOTE: does not touch the stack but trashes most of the temporary
60// registers.
61
62    // void arm64_local_invalidate_cache_all()
63FUNCTION(arm64_local_invalidate_cache_all)
64    cache_way_set_op isw, invalidate
65
66    // dump the instruction cache as well
67    ic      iallu
68    isb
69
70    ret
71END_FUNCTION(arm64_local_invalidate_cache_all)
72
73    // void arm64_local_clean_cache_all()
74FUNCTION(arm64_local_clean_cache_all)
75    cache_way_set_op csw, clean
76
77    // dump the instruction cache as well
78    ic      iallu
79    isb
80
81    ret
82END_FUNCTION(arm64_local_clean_cache_all)
83
84    // void arm64_local_clean_invalidate_cache_all()
85FUNCTION(arm64_local_clean_invalidate_cache_all)
86    cache_way_set_op cisw, clean_invalidate
87
88    // dump the instruction cache as well
89    ic      iallu
90    isb
91
92    ret
93END_FUNCTION(arm64_local_clean_invalidate_cache_all)
94
95