KallistiOS git master
Independent SDK for the Sega Dreamcast
Loading...
Searching...
No Matches
cache.h
Go to the documentation of this file.
1/* KallistiOS ##version##
2
3 arch/dreamcast/include/arch/cache.h
4 Copyright (C) 2001 Megan Potter
5 Copyright (C) 2014, 2016, 2023 Ruslan Rostovtsev
6 Copyright (C) 2023 Andy Barajas
7 Copyright (C) 2025 Eric Fradella
8 Copyright (C) 2026 Falco Girgis
9*/
10
11/** \file arch/cache.h
12 \brief Cache management functionality.
13 \ingroup system_cache
14
15 This file contains definitions for functions that manage the cache in the
16 Dreamcast, including functions to flush, invalidate, purge, prefetch and
17 allocate the caches.
18
19 \author Megan Potter
20 \author Ruslan Rostovtsev
21 \author Andy Barajas
22 \author Falco Girgis
23*/
24
25/* Keep this include above the macro guards */
26#include <kos/cache.h>
27
28#ifndef __ARCH_CACHE_H
29#define __ARCH_CACHE_H
30
31#include <kos/cdefs.h>
32__BEGIN_DECLS
33
34#include <kos/regfield.h>
35
36#include <stdalign.h>
37#include <stdint.h>
38
39#define ARCH_CACHE_L1_ICACHE_SIZE (8 * 1024)
40#define ARCH_CACHE_L1_ICACHE_ASSOC 1
41#define ARCH_CACHE_L1_ICACHE_LINESIZE 32
42
43#define ARCH_CACHE_L1_DCACHE_SIZE (16 * 1024)
44#define ARCH_CACHE_L1_DCACHE_ASSOC 1
45#define ARCH_CACHE_L1_DCACHE_LINESIZE 32
46
47#define ARCH_CACHE_L2_CACHE_SIZE 0
48#define ARCH_CACHE_L2_CACHE_ASSOC 0
49#define ARCH_CACHE_L2_CACHE_LINESIZE 0
50
51void arch_icache_inval_range(uintptr_t start, size_t count);
52void arch_icache_sync_range(uintptr_t start, size_t count);
53
54__depr("dcache_wback_sq is deprecated. Use sq_flush() from <dc/sq.h>")
55static __always_inline void dcache_wback_sq(void *src) {
56 __asm__ __volatile__("pref @%0\n"
57 : /* No outputs */
58 : "r" (src)
59 : "memory"
60 );
61}
62
63static inline void arch_dcache_pref_line(const void *src) {
64 __builtin_prefetch(src);
65}
66
67static inline void arch_dcache_alloc_line_with_value(void *src, uintptr_t value) {
68 uintptr_t *ptr = (uintptr_t *)src;
69
70 __asm__ ("movca.l r0, @%8\n\t"
71 : "=m"(ptr[0]),
72 "=m"(ptr[1]),
73 "=m"(ptr[2]),
74 "=m"(ptr[3]),
75 "=m"(ptr[4]),
76 "=m"(ptr[5]),
77 "=m"(ptr[6]),
78 "=m"(ptr[7])
79 : "r" (ptr), "z"(value)
80 );
81}
82
83static inline void arch_dcache_alloc_line(void *src) {
84 uintptr_t *ptr = (uintptr_t *)src;
85
86 __asm__ ("movca.l r0, @%8\n\t"
87 : "=m"(ptr[0]),
88 "=m"(ptr[1]),
89 "=m"(ptr[2]),
90 "=m"(ptr[3]),
91 "=m"(ptr[4]),
92 "=m"(ptr[5]),
93 "=m"(ptr[6]),
94 "=m"(ptr[7])
95 : "r" (ptr)
96 );
97}
98
99static inline void arch_dcache_zero_alloc_line(void *src) {
100 uint32_t *ptr = (uint32_t *)((uintptr_t)src & ~0x1f);
101
103
104 ptr[1] = ptr[2] = ptr[3] = ptr[4] = ptr[5] = ptr[6] = ptr[7] = 0;
105}
106
107static inline void arch_dcache_inval_line(void *src) {
108 uintptr_t *ptr = (uintptr_t *)src;
109
110 __asm__ ("ocbi @%8\n\t"
111 : "=m"(ptr[0]),
112 "=m"(ptr[1]),
113 "=m"(ptr[2]),
114 "=m"(ptr[3]),
115 "=m"(ptr[4]),
116 "=m"(ptr[5]),
117 "=m"(ptr[6]),
118 "=m"(ptr[7])
119 : "r" (ptr)
120 );
121}
122
123static inline void arch_dcache_purge_line(void *src) {
124 uintptr_t *ptr = (uintptr_t *)src;
125
126 __asm__ ("ocbp @%8\n\t"
127 : "=m"(ptr[0]),
128 "=m"(ptr[1]),
129 "=m"(ptr[2]),
130 "=m"(ptr[3]),
131 "=m"(ptr[4]),
132 "=m"(ptr[5]),
133 "=m"(ptr[6]),
134 "=m"(ptr[7])
135 : "r" (ptr)
136 );
137}
138
139static inline void arch_dcache_wback_line(void *src) {
140 uintptr_t *ptr = (uintptr_t *)src;
141
142 __asm__ ("ocbwb @%8\n\t"
143 : "=m"(ptr[0]),
144 "=m"(ptr[1]),
145 "=m"(ptr[2]),
146 "=m"(ptr[3]),
147 "=m"(ptr[4]),
148 "=m"(ptr[5]),
149 "=m"(ptr[6]),
150 "=m"(ptr[7])
151 : "r" (ptr)
152 );
153}
154
155static inline void arch_dcache_inval_range(uintptr_t start, size_t count) {
156 uintptr_t end = start + count;
157
158 start &= ~0x1f;
159
160 for(; start < end; start += 32)
162}
163
164static inline void arch_dcache_wback_all(void) {
165 unsigned int i;
166 volatile uint32_t *dca = (volatile uint32_t *)0xf4000008;
167
168 for (i = 0; i < 512; i++, dca += 8)
169 *dca &= ~BIT(1); /* Zero out U bit */
170}
171
172static inline void arch_dcache_wback_range(uintptr_t start, size_t count) {
173 uintptr_t end = start + count;
174
175 if(count >= 65560) {
176 /* Above this magic threshold, it's just faster to flush the whole cache. */
178 }
179 else {
180 start &= ~0x1f;
181
182 for(; start < end; start += 32)
184 }
185}
186
187static inline void arch_dcache_purge_all(void) {
188 unsigned int i;
189
190 if(__is_defined(__OPTIMIZE_SIZE__)) {
191 volatile uint32_t *dca = (volatile uint32_t *)0xf4000008;
192
193 for (i = 0; i < 512; i++, dca += 8)
194 *dca = 0;
195 }
196 else {
197 alignas(32) static char buffer[ARCH_CACHE_L1_DCACHE_SIZE];
198 char *buf = buffer;
199
200 for(i = 0; i < ARCH_CACHE_L1_DCACHE_SIZE / 32; i++) {
203 buf += 32;
204 }
205 }
206}
207
208static inline void arch_dcache_purge_range(uintptr_t start, size_t count) {
209 uintptr_t end = start + count;
210
211 if(count >= 39936) {
212 /* Above this magic threshold, it's just faster to purge the whole cache. */
214 }
215 else {
216 start &= ~0x1f;
217
218 for(; start < end; start += 32)
220 }
221}
222
223__END_DECLS
224
225#endif /* __ARCH_CACHE_H */
Various common macros used throughout the codebase.
#define __is_defined(macro)
Check if a macro is defined to 1.
Definition cdefs.h:189
Cache management functionality.
void arch_icache_sync_range(uintptr_t start, size_t count)
void arch_icache_inval_range(uintptr_t start, size_t count)
static void arch_dcache_wback_range(uintptr_t start, size_t count)
Definition cache.h:172
static void arch_dcache_purge_range(uintptr_t start, size_t count)
Definition cache.h:208
static __always_inline void dcache_wback_sq(void *src)
Definition cache.h:55
static void arch_dcache_alloc_line(void *src)
Definition cache.h:83
static void arch_dcache_alloc_line_with_value(void *src, uintptr_t value)
Definition cache.h:67
#define ARCH_CACHE_L1_DCACHE_SIZE
Definition cache.h:43
static void arch_dcache_wback_all(void)
Definition cache.h:164
static void arch_dcache_inval_line(void *src)
Definition cache.h:107
static void arch_dcache_wback_line(void *src)
Definition cache.h:139
static void arch_dcache_zero_alloc_line(void *src)
Definition cache.h:99
static void arch_dcache_purge_line(void *src)
Definition cache.h:123
static void arch_dcache_inval_range(uintptr_t start, size_t count)
Definition cache.h:155
static void arch_dcache_pref_line(const void *src)
Definition cache.h:63
static void arch_dcache_purge_all(void)
Definition cache.h:187
uint8_t end[]
static char buffer[256]
Definition porthelper.c:11
Macros to help dealing with register fields.
#define BIT(bit)
Create a 32-bit mask with a bit set.
Definition regfield.h:27
static void start(char *fn)
Definition songmenu.c:239