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#if __GNUC__ <= 9
85 /* Avoid ICE on GCC 9 */
86 uint32_t r0 = 0;
87#else
88 register uint32_t r0 __asm__("r0");
89#endif
90
92}
93
94static inline void arch_dcache_zero_alloc_line(void *src) {
95 uint32_t *ptr = (uint32_t *)((uintptr_t)src & ~0x1f);
96
98
99 ptr[1] = ptr[2] = ptr[3] = ptr[4] = ptr[5] = ptr[6] = ptr[7] = 0;
100}
101
102static inline void arch_dcache_inval_line(void *src) {
103 uintptr_t *ptr = (uintptr_t *)src;
104
105 __asm__ ("ocbi @%8\n\t"
106 : "=m"(ptr[0]),
107 "=m"(ptr[1]),
108 "=m"(ptr[2]),
109 "=m"(ptr[3]),
110 "=m"(ptr[4]),
111 "=m"(ptr[5]),
112 "=m"(ptr[6]),
113 "=m"(ptr[7])
114 : "r" (ptr)
115 );
116}
117
118static inline void arch_dcache_purge_line(void *src) {
119 uintptr_t *ptr = (uintptr_t *)src;
120
121 __asm__ ("ocbp @%8\n\t"
122 : "=m"(ptr[0]),
123 "=m"(ptr[1]),
124 "=m"(ptr[2]),
125 "=m"(ptr[3]),
126 "=m"(ptr[4]),
127 "=m"(ptr[5]),
128 "=m"(ptr[6]),
129 "=m"(ptr[7])
130 : "r" (ptr)
131 );
132}
133
134static inline void arch_dcache_wback_line(void *src) {
135 uintptr_t *ptr = (uintptr_t *)src;
136
137 __asm__ ("ocbwb @%8\n\t"
138 : "=m"(ptr[0]),
139 "=m"(ptr[1]),
140 "=m"(ptr[2]),
141 "=m"(ptr[3]),
142 "=m"(ptr[4]),
143 "=m"(ptr[5]),
144 "=m"(ptr[6]),
145 "=m"(ptr[7])
146 : "r" (ptr)
147 );
148}
149
150static inline void arch_dcache_inval_range(uintptr_t start, size_t count) {
151 uintptr_t end = start + count;
152
153 start &= ~0x1f;
154
155 for(; start < end; start += 32)
157}
158
159static inline void arch_dcache_wback_all(void) {
160 unsigned int i;
161 volatile uint32_t *dca = (volatile uint32_t *)0xf4000008;
162
163 for (i = 0; i < 512; i++, dca += 8)
164 *dca &= ~BIT(1); /* Zero out U bit */
165}
166
167static inline void arch_dcache_wback_range(uintptr_t start, size_t count) {
168 uintptr_t end = start + count;
169
170 if(count >= 65560) {
171 /* Above this magic threshold, it's just faster to flush the whole cache. */
173 }
174 else {
175 start &= ~0x1f;
176
177 for(; start < end; start += 32)
179 }
180}
181
182static inline void arch_dcache_purge_all(void) {
183 unsigned int i;
184
185 if(__is_defined(__OPTIMIZE_SIZE__)) {
186 volatile uint32_t *dca = (volatile uint32_t *)0xf4000008;
187
188 for (i = 0; i < 512; i++, dca += 8)
189 *dca = 0;
190 }
191 else {
192 alignas(32) static char buffer[ARCH_CACHE_L1_DCACHE_SIZE];
193 char *buf = buffer;
194
195 for(i = 0; i < ARCH_CACHE_L1_DCACHE_SIZE / 32; i++) {
198 buf += 32;
199 }
200 }
201}
202
203static inline void arch_dcache_purge_range(uintptr_t start, size_t count) {
204 uintptr_t end = start + count;
205
206 if(count >= 39936) {
207 /* Above this magic threshold, it's just faster to purge the whole cache. */
209 }
210 else {
211 start &= ~0x1f;
212
213 for(; start < end; start += 32)
215 }
216}
217
218__END_DECLS
219
220#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:167
static void arch_dcache_purge_range(uintptr_t start, size_t count)
Definition cache.h:203
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:159
static void arch_dcache_inval_line(void *src)
Definition cache.h:102
static void arch_dcache_wback_line(void *src)
Definition cache.h:134
static void arch_dcache_zero_alloc_line(void *src)
Definition cache.h:94
static void arch_dcache_purge_line(void *src)
Definition cache.h:118
static void arch_dcache_inval_range(uintptr_t start, size_t count)
Definition cache.h:150
static void arch_dcache_pref_line(const void *src)
Definition cache.h:63
static void arch_dcache_purge_all(void)
Definition cache.h:182
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