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/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*/
9
10/** \file arch/cache.h
11 \brief Cache management functionality.
12 \ingroup system_cache
13
14 This file contains definitions for functions that manage the cache in the
15 Dreamcast, including functions to flush, invalidate, purge, prefetch and
16 allocate the caches.
17
18 \author Megan Potter
19 \author Ruslan Rostovtsev
20 \author Andy Barajas
21*/
22
23#ifndef __ARCH_CACHE_H
24#define __ARCH_CACHE_H
25
26#include <kos/cdefs.h>
27__BEGIN_DECLS
28
29#include <stdint.h>
30
31/** \defgroup system_cache Cache
32 \brief Driver and API for managing the SH4's cache
33 \ingroup system
34
35 @{
36*/
37
38/** \brief Level 1 instruction cache size.
39
40 The capacity of the L1 instruction cache in bytes.
41*/
42#define CACHE_L1_ICACHE_SIZE 8 * 1024
43
44/** \brief Level 1 instruction cache associativity.
45
46 Number of ways in the L1 instruction cache.
47*/
48#define CACHE_L1_ICACHE_ASSOC 1
49
50/** \brief L1 instruction cache line size.
51
52 The size of each cache line in the L1 instruction cache.
53*/
54#define CACHE_L1_ICACHE_LINESIZE 32
55
56/** \brief Level 1 data cache size.
57
58 The capacity of the L1 data cache in bytes.
59*/
60#define CACHE_L1_DCACHE_SIZE 16 * 1024
61
62/** \brief Level 1 data cache associativity.
63
64 Number of ways in the L1 data cache.
65*/
66#define CACHE_L1_DCACHE_ASSOC 1
67
68/** \brief L1 data cache line size.
69
70 The size of each cache line in the L1 data cache.
71*/
72#define CACHE_L1_DCACHE_LINESIZE 32
73
74/** \brief Level 2 cache size.
75
76 The capacity of the L2 cache in bytes.
77*/
78#define CACHE_L2_CACHE_SIZE 0
79
80/** \brief Level 2 cache associativity.
81
82 Number of ways in the L2 cache.
83*/
84#define CACHE_L2_CACHE_ASSOC 0
85
86/** \brief Level 2 cache line size.
87
88 The size of each cache line in the L2 cache.
89*/
90#define CACHE_L2_CACHE_LINESIZE 0
91
92/** \brief Flush the instruction cache.
93
94 This function flushes a range of the instruction cache.
95
96 \param start The physical address to begin flushing at.
97 \param count The number of bytes to flush.
98*/
99void icache_flush_range(uintptr_t start, size_t count);
100
101/** \brief Invalidate the data/operand cache.
102
103 This function invalidates a range of the data/operand cache. If you care
104 about the contents of the cache that have not been written back yet, use
105 dcache_flush_range() before using this function.
106
107 \param start The physical address to begin invalidating at.
108 \param count The number of bytes to invalidate.
109*/
110void dcache_inval_range(uintptr_t start, size_t count);
111
112/** \brief Flush the data/operand cache.
113
114 This function flushes a range of the data/operand cache, forcing a write-
115 back on all of the data in the specified range. This does not invalidate
116 the cache in the process (meaning the blocks will still be in the cache,
117 just not marked as dirty after this has completed). If you wish to
118 invalidate the cache as well, call dcache_inval_range() after calling this
119 function or use dcache_purge_range() instead of dcache_flush_range().
120
121 \param start The physical address to begin flushing at.
122 \param count The number of bytes to flush.
123*/
124void dcache_flush_range(uintptr_t start, size_t count);
125
126/** \brief Flush all the data/operand cache.
127
128 This function flushes all the data/operand cache, forcing a write-
129 back on all of the cache blocks that are marked as dirty.
130
131 \note
132 dcache_flush_range() is faster than dcache_flush_all() if the count
133 param is 66560 or less.
134*/
136
137/** \brief Purge the data/operand cache.
138
139 This function flushes a range of the data/operand cache, forcing a write-
140 back and then invalidates all of the data in the specified range.
141
142 \param start The physical address to begin purging at.
143 \param count The number of bytes to purge.
144*/
145void dcache_purge_range(uintptr_t start, size_t count);
146
147/** \brief Purge all the data/operand cache.
148
149 This function flushes the entire data/operand cache, ensuring that all
150 cache blocks marked as dirty are written back to memory and all cache
151 entries are invalidated. It does not require an additional buffer and is
152 preferred when memory resources are constrained.
153
154 \note
155 dcache_purge_range() is faster than dcache_purge_all() if the count
156 param is 39936 or less.
157*/
159
160/** \brief Purge all the data/operand cache with buffer.
161
162 This function performs a purge of all data/operand cache blocks by
163 utilizing an external buffer to speed up the write-back and invalidation
164 process. It is always faster than dcache_purge_all() and is recommended
165 where maximum speed is required.
166
167 \note While this function offers a superior purge rate, it does require
168 the use of a temporary buffer. So use this function if you have an extra
169 8/16 kb of memory laying around that you can utilize for no other purpose
170 than for this function.
171
172 \param start The physical address for temporary buffer (32-byte
173 aligned)
174 \param count The size of the temporary buffer, which can be
175 either 8 KB or 16 KB, depending on cache
176 configuration - 8 KB buffer with OCRAM enabled,
177 otherwise 16 KB.
178
179*/
180void dcache_purge_all_with_buffer(uintptr_t start, size_t count);
181
182/** \brief Prefetch one block to the data/operand cache.
183
184 This function prefetch a block of the data/operand cache.
185
186 \param src The physical address to prefetch.
187*/
188static __always_inline void dcache_pref_block(const void *src) {
189 __asm__ __volatile__("pref @%0\n"
190 : /* No outputs */
191 : "r" (src)
192 : /* No clobbers */
193 );
194}
195
196/** \brief Write-back Store Queue buffer to external memory
197
198 This function initiates write-back for one Store Queue.
199
200 \param src The SQ mapped address to write-back.
201*/
202static __always_inline void dcache_wback_sq(void *src) {
203 __asm__ __volatile__("pref @%0\n"
204 : /* No outputs */
205 : "r" (src)
206 : "memory"
207 );
208}
209
210/** \brief Allocate one block of the data/operand cache.
211
212 This function allocate a block of the data/operand cache.
213
214 \param src The address to allocate (32-byte aligned)
215 \param value The value written to first 4-byte.
216*/
217static __always_inline void dcache_alloc_block(void *src, uint32_t value) {
218 uint32_t *src32 = (uint32_t *)src;
219
220 __asm__ ("movca.l r0, @%8\n\t"
221 : "=m"(src32[0]),
222 "=m"(src32[1]),
223 "=m"(src32[2]),
224 "=m"(src32[3]),
225 "=m"(src32[4]),
226 "=m"(src32[5]),
227 "=m"(src32[6]),
228 "=m"(src32[7])
229 : "r" (src32), "z" (value)
230 );
231}
232
233/** @} */
234
235__END_DECLS
236
237#endif /* __ARCH_CACHE_H */
Various common macros used throughout the codebase.
static uint32_t("Please see purupuru_effect_t for modern equivalent.") PURUPURU_EFFECT2_UINTENSITY(uint8_t x)
Definition purupuru.h:96
static __always_inline void dcache_alloc_block(void *src, uint32_t value)
Allocate one block of the data/operand cache.
Definition cache.h:217
void dcache_inval_range(uintptr_t start, size_t count)
Invalidate the data/operand cache.
void dcache_purge_all(void)
Purge all the data/operand cache.
void icache_flush_range(uintptr_t start, size_t count)
Flush the instruction cache.
static __always_inline void dcache_pref_block(const void *src)
Prefetch one block to the data/operand cache.
Definition cache.h:188
void dcache_purge_range(uintptr_t start, size_t count)
Purge the data/operand cache.
static __always_inline void dcache_wback_sq(void *src)
Write-back Store Queue buffer to external memory.
Definition cache.h:202
void dcache_flush_all(void)
Flush all the data/operand cache.
void dcache_purge_all_with_buffer(uintptr_t start, size_t count)
Purge all the data/operand cache with buffer.
void dcache_flush_range(uintptr_t start, size_t count)
Flush the data/operand cache.