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 <kos/cdefs.h>
42__BEGIN_DECLS
43
44#include <stdint.h>
45#include <dc/memory.h>
46
47/** \brief Mask dest to Store Queue area as address
48 \ingroup store_queues
49*/
50#define SQ_MASK_DEST_ADDR(dest) \
51 (MEM_AREA_SQ_BASE | ((uintptr_t)(dest) & 0x03ffffe0))
52
53/** \brief Mask dest to Store Queue area as pointer
54 \ingroup store_queues
55*/
56#define SQ_MASK_DEST(dest) \
57 ((uint32_t *)(void *) SQ_MASK_DEST_ADDR(dest))
58
59/** \brief Lock Store Queues
60 \ingroup store_queues
61
62 Locks the store queues so that they cannot be used from another thread
63 until unlocked.
64
65 \warning
66 This function is called automatically by the store queue API provided by KOS;
67 however, it must be called manually when driving the SQs directly from outside
68 of this API.
69
70 \param dest The destination address.
71 \return The translated address that can be directly written to.
72
73 \sa sq_unlock()
74*/
75uint32_t *sq_lock(void *dest);
76
77/** \brief Unlock Store Queues
78 \ingroup store_queues
79
80 Unlocks the store queues so that they can be used from any thread.
81
82 \note
83 sq_lock() should've already been called previously.
84
85 \warning
86 sq_lock() and sq_unlock() are called automatically by the store queue API provided
87 by KOS; however, they must be called manually when driving the SQs directly from
88 outside this API.
89
90 \sa sq_lock()
91*/
92void sq_unlock(void);
93
94/** \brief Wait for both Store Queues to complete
95 \ingroup store_queues
96
97 Wait for both store queues to complete by writing to SQ area.
98
99 \sa sq_lock()
100*/
101void sq_wait(void);
102
103/** \brief Write-back one Store Queue
104 \ingroup store_queues
105
106 Initiates write-back from SQ buffer to external memory.
107
108 \param dest The address to copy to (32-byte aligned).
109
110 \sa sq_wait()
111*/
112static inline void sq_flush(void *src) {
113 __asm__ __volatile__("pref @%0\n"
114 : /* No outputs */
115 : "r" (src)
116 : "memory"
117 );
118}
119
120/** \brief Copy a block of memory.
121 \ingroup store_queues
122
123 This function is similar to memcpy4(), but uses the store queues to do its
124 work.
125
126 \warning
127 The dest pointer must be at least 32-byte aligned, the src pointer
128 must be at least 4-byte aligned (8-byte aligned uses fast path),
129 and n must be a multiple of 32!
130
131 \param dest The address to copy to (32-byte aligned).
132 \param src The address to copy from (32-bit (4/8-byte) aligned).
133 \param n The number of bytes to copy (multiple of 32).
134 \return The original value of dest.
135
136 \sa sq_fast_cpy()
137*/
138void *sq_cpy(void *dest, const void *src, size_t n);
139
140/** \brief Copy a block of memory.
141 \ingroup store_queues
142
143 This function is similar to sq_cpy() but expects the user to lock/unlock
144 the store queues before and after as well as having different requirements
145 for the params.
146
147 \warning
148 The dest pointer must be at least 32-byte aligned that already has been
149 masked by SQ_MASK_DEST(), the src pointer must be at least 8-byte aligned,
150 and n must be the number of 32-byte blocks you want to copy.
151
152 \param dest The store queue address to copy to (32-byte aligned).
153 \param src The address to copy from (8-byte aligned).
154 \param n The number of 32-byte blocks to copy.
155 \return The original value of dest.
156
157 \sa sq_cpy()
158 */
159void *sq_fast_cpy(void *dest, const void *src, size_t n);
160
161/** \brief Set a block of memory to an 8-bit value.
162 \ingroup store_queues
163
164 This function is similar to calling memset(), but uses the store queues to
165 do its work.
166
167 \warning
168 The dest pointer must be a 32-byte aligned with n being a multiple of 32,
169 and only the low 8-bits are used from c.
170
171 \param dest The address to begin setting at (32-byte aligned).
172 \param c The value to set (in the low 8-bits).
173 \param n The number of bytes to set (multiple of 32).
174 \return The original value of dest.
175
176 \sa sq_set16(), sq_set32()
177*/
178void *sq_set(void *dest, uint32_t c, size_t n);
179
180/** \brief Set a block of memory to a 16-bit value.
181 \ingroup store_queues
182
183 This function is similar to calling memset2(), but uses the store queues to
184 do its work.
185
186 \warning
187 The dest pointer must be a 32-byte aligned with n being a multiple of 32,
188 and only the low 16-bits are used from c.
189
190 \param dest The address to begin setting at (32-byte aligned).
191 \param c The value to set (in the low 16-bits).
192 \param n The number of bytes to set (multiple of 32).
193 \return The original value of dest.
194
195 \sa sq_set(), sq_set32()
196*/
197void *sq_set16(void *dest, uint32_t c, size_t n);
198
199/** \brief Set a block of memory to a 32-bit value.
200 \ingroup store_queues
201
202 This function is similar to calling memset4(), but uses the store queues to
203 do its work.
204
205 \warning
206 The dest pointer must be a 32-byte aligned with n being a multiple of 32!
207
208 \param dest The address to begin setting at (32-byte aligned).
209 \param c The value to set (all 32-bits).
210 \param n The number of bytes to set (multiple of 32).
211 \return The original value of dest.
212
213 \sa sq_set(), sq_set16()
214*/
215void *sq_set32(void *dest, uint32_t c, size_t n);
216
217/** \brief Clear a block of memory.
218 \ingroup store_queues
219
220 This function is similar to calling memset() with a value to set of 0, but
221 uses the store queues to do its work.
222
223 \warning
224 The dest pointer must be a 32-byte aligned with n being a multiple of 32!
225
226 \param dest The address to begin clearing at (32-byte aligned).
227 \param n The number of bytes to clear (multiple of 32).
228*/
229void sq_clr(void *dest, size_t n);
230
231
232__END_DECLS
233
234#endif
Various common macros used throughout the codebase.
Constants for areas of the system memory map.
static void sq_flush(void *src)
Write-back one Store Queue.
Definition sq.h:112
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.
object * dest
Definition nehe26.c:54