KallistiOS git master
Independent SDK for the Sega Dreamcast
Loading...
Searching...
No Matches
sq.h
Go to the documentation of this file.
1/* KallistiOS ##version##
2
3 kernel/arch/dreamcast/include/dc/sq.h
4 Copyright (C) 2000-2001 Andrew Kieschnick
5 Copyright (C) 2023 Falco Girgis
6 Copyright (C) 2023 Ruslan Rostovtsev
7 Copyright (C) 2023-2024 Andy Barajas
8*/
9
10/** \file dc/sq.h
11 \ingroup store_queues
12 \brief Functions to access the SH4 Store Queues.
13
14 \author Andrew Kieschnick
15 \author Falco Girgis
16 \author Andy Barajas
17 \author Ruslan Rostovtsev
18*/
19
20/** \defgroup store_queues Store Queues
21 \brief SH4 CPU Peripheral for burst memory transactions.
22 \ingroup system
23
24 The store queues are a way to do efficient burst transfers from the CPU to
25 external memory. They can be used in a variety of ways, such as to transfer
26 a texture to PVR memory. The transfers are in units of 32-bytes, and the
27 destinations must be 32-byte aligned.
28
29 \note
30 Mastery over knowing when and how to utilize the store queues is
31 important when trying to push the limits of the Dreamcast, specifically
32 when transferring chunks of data between regions of memory. It is often
33 the case that the DMA is faster for transactions which are consistently
34 large; however, the store queues tend to have better performance and
35 have less configuration overhead when bursting smaller chunks of data.
36*/
37
38#ifndef __DC_SQ_H
39#define __DC_SQ_H
40
41#include <sys/cdefs.h>
42__BEGIN_DECLS
43
44#include <stdint.h>
45#include <arch/types.h>
46#include <arch/memory.h>
47#include <arch/cache.h>
48
49/** \brief Mask dest to Store Queue area as address
50 \ingroup store_queues
51*/
52#define SQ_MASK_DEST_ADDR(dest) \
53 (MEM_AREA_SQ_BASE | ((uintptr_t)(dest) & 0x03ffffe0))
54
55/** \brief Mask dest to Store Queue area as pointer
56 \ingroup store_queues
57*/
58#define SQ_MASK_DEST(dest) \
59 ((uint32_t *)(void *) SQ_MASK_DEST_ADDR(dest))
60
61/** \brief Lock Store Queues
62 \ingroup store_queues
63
64 Locks the store queues so that they cannot be used from another thread
65 until unlocked.
66
67 \warning
68 This function is called automatically by the store queue API provided by KOS;
69 however, it must be called manually when driving the SQs directly from outside
70 of this API.
71
72 \param dest The destination address.
73 \return The translated address that can be directly written to.
74
75 \sa sq_unlock()
76*/
77uint32_t *sq_lock(void *dest);
78
79/** \brief Unlock Store Queues
80 \ingroup store_queues
81
82 Unlocks the store queues so that they can be used from any thread.
83
84 \note
85 sq_lock() should've already been called previously.
86
87 \warning
88 sq_lock() and sq_unlock() are called automatically by the store queue API provided
89 by KOS; however, they must be called manually when driving the SQs directly from
90 outside this API.
91
92 \sa sq_lock()
93*/
94void sq_unlock(void);
95
96/** \brief Wait for both Store Queues to complete
97 \ingroup store_queues
98
99 Wait for both store queues to complete by writing to SQ area.
100
101 \sa sq_lock()
102*/
103void sq_wait(void);
104
105/** \brief Write-back one Store Queue
106 \ingroup store_queues
107
108 Initiates write-back from SQ buffer to external memory.
109
110 \param dest The address to copy to (32-byte aligned).
111
112 \sa sq_wait()
113*/
114#define sq_flush(dest) dcache_wback_sq(dest)
115
116/** \brief Copy a block of memory.
117 \ingroup store_queues
118
119 This function is similar to memcpy4(), but uses the store queues to do its
120 work.
121
122 \warning
123 The dest pointer must be at least 32-byte aligned, the src pointer
124 must be at least 4-byte aligned (8-byte aligned uses fast path),
125 and n must be a multiple of 32!
126
127 \param dest The address to copy to (32-byte aligned).
128 \param src The address to copy from (32-bit (4/8-byte) aligned).
129 \param n The number of bytes to copy (multiple of 32).
130 \return The original value of dest.
131
132 \sa sq_fast_cpy()
133*/
134void *sq_cpy(void *dest, const void *src, size_t n);
135
136/** \brief Copy a block of memory.
137 \ingroup store_queues
138
139 This function is similar to sq_cpy() but expects the user to lock/unlock
140 the store queues before and after as well as having different requirements
141 for the params.
142
143 \warning
144 The dest pointer must be at least 32-byte aligned that already has been
145 masked by SQ_MASK_DEST(), the src pointer must be at least 8-byte aligned,
146 and n must be the number of 32-byte blocks you want to copy.
147
148 \param dest The store queue address to copy to (32-byte aligned).
149 \param src The address to copy from (8-byte aligned).
150 \param n The number of 32-byte blocks to copy.
151 \return The original value of dest.
152
153 \sa sq_cpy()
154 */
155void *sq_fast_cpy(void *dest, const void *src, size_t n);
156
157/** \brief Set a block of memory to an 8-bit value.
158 \ingroup store_queues
159
160 This function is similar to calling memset(), but uses the store queues to
161 do its work.
162
163 \warning
164 The dest pointer must be a 32-byte aligned with n being a multiple of 32,
165 and only the low 8-bits are used from c.
166
167 \param dest The address to begin setting at (32-byte aligned).
168 \param c The value to set (in the low 8-bits).
169 \param n The number of bytes to set (multiple of 32).
170 \return The original value of dest.
171
172 \sa sq_set16(), sq_set32()
173*/
174void *sq_set(void *dest, uint32_t c, size_t n);
175
176/** \brief Set a block of memory to a 16-bit value.
177 \ingroup store_queues
178
179 This function is similar to calling memset2(), but uses the store queues to
180 do its work.
181
182 \warning
183 The dest pointer must be a 32-byte aligned with n being a multiple of 32,
184 and only the low 16-bits are used from c.
185
186 \param dest The address to begin setting at (32-byte aligned).
187 \param c The value to set (in the low 16-bits).
188 \param n The number of bytes to set (multiple of 32).
189 \return The original value of dest.
190
191 \sa sq_set(), sq_set32()
192*/
193void *sq_set16(void *dest, uint32_t c, size_t n);
194
195/** \brief Set a block of memory to a 32-bit value.
196 \ingroup store_queues
197
198 This function is similar to calling memset4(), but uses the store queues to
199 do its work.
200
201 \warning
202 The dest pointer must be a 32-byte aligned with n being a multiple of 32!
203
204 \param dest The address to begin setting at (32-byte aligned).
205 \param c The value to set (all 32-bits).
206 \param n The number of bytes to set (multiple of 32).
207 \return The original value of dest.
208
209 \sa sq_set(), sq_set16()
210*/
211void *sq_set32(void *dest, uint32_t c, size_t n);
212
213/** \brief Clear a block of memory.
214 \ingroup store_queues
215
216 This function is similar to calling memset() with a value to set of 0, but
217 uses the store queues to do its work.
218
219 \warning
220 The dest pointer must be a 32-byte aligned with n being a multiple of 32!
221
222 \param dest The address to begin clearing at (32-byte aligned).
223 \param n The number of bytes to clear (multiple of 32).
224*/
225void sq_clr(void *dest, size_t n);
226
227
228__END_DECLS
229
230#endif
Cache management functionality.
void * sq_fast_cpy(void *dest, const void *src, size_t n)
Copy a block of memory.
void * sq_set(void *dest, uint32_t c, size_t n)
Set a block of memory to an 8-bit value.
void sq_wait(void)
Wait for both Store Queues to complete.
void * sq_set16(void *dest, uint32_t c, size_t n)
Set a block of memory to a 16-bit value.
void * sq_set32(void *dest, uint32_t c, size_t n)
Set a block of memory to a 32-bit value.
void sq_unlock(void)
Unlock Store Queues.
void * sq_cpy(void *dest, const void *src, size_t n)
Copy a block of memory.
uint32_t * sq_lock(void *dest)
Lock Store Queues.
void sq_clr(void *dest, size_t n)
Clear a block of memory.
Constants for areas of the system memory map.
Common integer types.