blob: bd1d842703849d11137a494316a2ccf7f6531d0a [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
2 * Copyright (c) 2015 Stefan Kristiansson
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24#include <arch/ops.h>
25#include <arch/or1k.h>
26
27static inline uint32_t dc_block_size(void)
28{
29 uint32_t dccfgr = mfspr(OR1K_SPR_SYS_DCCFGR_ADDR);
30
31 return dccfgr & OR1K_SPR_SYS_DCCFGR_CBS_MASK ? 32 : 16;
32}
33
34static inline uint32_t dc_sets(void)
35{
36 uint32_t dccfgr = mfspr(OR1K_SPR_SYS_DCCFGR_ADDR);
37
38 return 1 << OR1K_SPR_SYS_DCCFGR_NCS_GET(dccfgr);
39}
40
41static inline uint32_t ic_block_size(void)
42{
43 uint32_t iccfgr = mfspr(OR1K_SPR_SYS_ICCFGR_ADDR);
44
45 return iccfgr & OR1K_SPR_SYS_ICCFGR_CBS_MASK ? 32 : 16;
46}
47
48static inline uint32_t ic_sets(void)
49{
50 uint32_t iccfgr = mfspr(OR1K_SPR_SYS_ICCFGR_ADDR);
51
52 return 1 << OR1K_SPR_SYS_ICCFGR_NCS_GET(iccfgr);
53}
54
55void arch_invalidate_cache_all(void)
56{
57 uint32_t i;
58 uint32_t cache_size;
59 uint32_t block_size;
60
61 block_size = ic_block_size();
62 cache_size = block_size * ic_sets();
63 for (i = 0; i < cache_size; i += block_size)
64 mtspr(OR1K_SPR_ICACHE_ICBIR_ADDR, i);
65
66 block_size = dc_block_size();
67 cache_size = block_size * dc_sets();
68 for (i = 0; i < cache_size; i += block_size)
69 mtspr(OR1K_SPR_DCACHE_DCBIR_ADDR, i);
70}
71
72void arch_disable_cache(uint flags)
73{
74 uint32_t sr = mfspr(OR1K_SPR_SYS_SR_ADDR);
75
76 if (flags & ICACHE)
77 sr &= ~OR1K_SPR_SYS_SR_ICE_MASK;
78 if (flags & DCACHE)
79 sr &= ~OR1K_SPR_SYS_SR_DCE_MASK;
80
81 mtspr(OR1K_SPR_SYS_SR_ADDR, sr);
82}
83
84void arch_enable_cache(uint flags)
85{
86 uint32_t sr = mfspr(OR1K_SPR_SYS_SR_ADDR);
87
88 if (flags & ICACHE)
89 sr |= OR1K_SPR_SYS_SR_ICE_MASK;
90 if (flags & DCACHE)
91 sr |= OR1K_SPR_SYS_SR_DCE_MASK;
92
93 mtspr(OR1K_SPR_SYS_SR_ADDR, sr);
94}
95
96/* flush dcache */
97void arch_clean_cache_range(addr_t start, size_t len)
98{
99 addr_t addr;
100 uint32_t block_size = dc_block_size();
101
102 for (addr = start; addr < start + len; addr += block_size)
103 mtspr(OR1K_SPR_DCACHE_DCBFR_ADDR, addr);
104}
105
106/* invalidate dcache */
107void arch_invalidate_cache_range(addr_t start, size_t len)
108{
109 addr_t addr;
110 uint32_t block_size = dc_block_size();
111
112 for (addr = start; addr < start + len; addr += block_size)
113 mtspr(OR1K_SPR_DCACHE_DCBIR_ADDR, addr);
114}
115
116/* flush + invalidate dcache */
117void arch_clean_invalidate_cache_range(addr_t start, size_t len)
118{
119 /* invalidate is implied by flush on or1k */
120 arch_clean_cache_range(start, len);
121}
122
123/* flush dcache + invalidate icache */
124void arch_sync_cache_range(addr_t start, size_t len)
125{
126 addr_t addr;
127 uint32_t block_size = ic_block_size();
128
129 arch_clean_cache_range(start, len);
130 for (addr = start; addr < start + len; addr += block_size)
131 mtspr(OR1K_SPR_ICACHE_ICBIR_ADDR, addr);
132}