1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: fnd_DetailHeapCommonImpl.h
4 Copyright (C)2009 Nintendo Co., Ltd. All rights reserved.
5 These coded instructions, statements, and computer programs contain
6 proprietary information of Nintendo of America Inc. and/or Nintendo
7 Company Ltd., and are protected by Federal copyright law. They may
8 not be disclosed to third parties or copied or duplicated in any form,
9 in whole or in part, without the prior written consent of Nintendo.
10 $Rev: 12449 $
11 *---------------------------------------------------------------------------
12
13
14 */
15
16 #ifndef NN_FND_DETAIL_FND_DETAIL_HEAPCOMMONIMPL_H_
17 #define NN_FND_DETAIL_FND_DETAIL_HEAPCOMMONIMPL_H_
18
19 #include <nn/types.h>
20
21 #ifdef __cplusplus
22
23 namespace nn { namespace fnd { namespace detail {
24 //
25
26 /* =======================================================================
27 Type Definitions
28 ======================================================================== */
29
30 typedef s32 NNSiIntPtr; // signed integer type mutually convertible with void* pointer
31 typedef u32 NNSiUIntPtr; // unsigned integer type mutually convertible with void* pointer
32
33
34 /* ========================================================================
35 Macro Functions
36 ======================================================================== */
37
38 /*---------------------------------------------------------------------------*
39 Name: NNSi_FndRoundUp
40 Description: Rounds up to align with specified alignment.
41 Arguments: value: target data
42 alignment: alignment value
43 Returns: Returns a value that has been rounded up to the specified alignment value.
44 *---------------------------------------------------------------------------
45
46
47 */
48 #define NNSi_FndRoundUp(value, alignment) \
49 (((value) + (alignment-1)) & ~(alignment-1))
50
51 #define NNSi_FndRoundUpPtr(ptr, alignment) \
52 ((void*)NNSi_FndRoundUp(NNSiGetUIntPtr(ptr), alignment))
53
54 /*---------------------------------------------------------------------------*
55 Name: NNSi_FndRoundDown
56 Description: Rounds down to align for a specified alignment value.
57 Arguments: value: target data
58 alignment: alignment value
59 Returns: Returns a value that has been rounded down to the specified alignment.
60 *---------------------------------------------------------------------------
61
62
63 */
64 #define NNSi_FndRoundDown(value, alignment) \
65 ((value) & ~(alignment-1))
66
67 #define NNSi_FndRoundDownPtr(ptr, alignment) \
68 ((void*)NNSi_FndRoundDown(NNSiGetUIntPtr(ptr), alignment))
69
70 /*---------------------------------------------------------------------------*
71 Name: NNSi_FndGetBitValue
72 Description: Gets a value at a specific bit position.
73 Arguments: data: Data that contains the bit data to be gotten.
74 st: Start bit (start from 0)
75 bits: Number of bits (maximum 31)
76 Returns: Returns the value at a specific bit position.
77 *---------------------------------------------------------------------------
78
79
80 */
81 #define NNSi_FndGetBitValue(data, st, bits) \
82 (((data) >>(st)) & ((1 <<(bits)) -1))
83
84 /*---------------------------------------------------------------------------*
85 Name: NNSi_FndSetBitValue
86 Description: Sets a value at a specific bit position.
87 Arguments: data: Variable that holds the bit data that is to be set
88 st: Start bit (start from 0)
89 bits: Number of bits (maximum 31)
90 val: Bit data to set.
91 Returns: None.
92 *---------------------------------------------------------------------------
93
94
95 */
96 #define NNSi_FndSetBitValue(data, st, bits, val) \
97 do \
98 { \
99 u32 maskBits = (u32)((1 <<(bits)) -1); \
100 u32 newVal = (val) & maskBits; /* mask for safety */ \
101 (void)(maskBits <<= st); \
102 (data) &= ~maskBits; /* clears the region to set */ \
103 (data) |= newVal <<(st); \
104 } while(false);
105
106
107 /* ========================================================================
108 Inline Functions
109 ======================================================================== */
110
111 /* ------------------------------------------------------------------------
112 Pointer operations
113 ------------------------------------------------------------------------ */
114
115 inline NNSiUIntPtr
NNSiGetUIntPtr(const void * ptr)116 NNSiGetUIntPtr(const void* ptr)
117 {
118 return (NNSiUIntPtr)ptr;
119 }
120
121 inline u32
GetOffsetFromPtr(const void * start,const void * end)122 GetOffsetFromPtr(const void* start, const void* end)
123 {
124 return NNSiGetUIntPtr(end) - NNSiGetUIntPtr(start);
125 }
126
127 inline void*
AddU32ToPtr(void * ptr,u32 val)128 AddU32ToPtr(void* ptr, u32 val)
129 {
130 return (void*)( NNSiGetUIntPtr(ptr) + val );
131 }
132
133 inline const void*
AddU32ToCPtr(const void * ptr,u32 val)134 AddU32ToCPtr(const void* ptr, u32 val)
135 {
136 return (const void*)( NNSiGetUIntPtr(ptr) + val );
137 }
138
139 inline void*
SubU32ToPtr(void * ptr,u32 val)140 SubU32ToPtr(void* ptr, u32 val)
141 {
142 return (void*)( NNSiGetUIntPtr(ptr) - val );
143 }
144
145 inline const void*
SubU32ToCPtr(const void * ptr,u32 val)146 SubU32ToCPtr(const void* ptr, u32 val)
147 {
148 return (const void*)( NNSiGetUIntPtr(ptr) - val );
149 }
150
151 inline int
ComparePtr(const void * a,const void * b)152 ComparePtr(const void* a, const void* b)
153 {
154 const u8* wa = reinterpret_cast<const u8*>(a);
155 const u8* wb = reinterpret_cast<const u8*>(b);
156
157 return wa - wb;
158 }
159
160
161 inline u16
GetOptForHeap(const NNSiFndHeapHead * pHeapHd)162 GetOptForHeap(const NNSiFndHeapHead* pHeapHd)
163 {
164 return (u16)NNSi_FndGetBitValue(pHeapHd->attribute, 0, 8);
165 }
166
167 inline void
SetOptForHeap(NNSiFndHeapHead * pHeapHd,u16 optFlag)168 SetOptForHeap(
169 NNSiFndHeapHead* pHeapHd,
170 u16 optFlag
171 )
172 {
173 NNSi_FndSetBitValue(pHeapHd->attribute, 0, 8, optFlag);
174 }
175
176
177 /* ------------------------------------------------------------------------
178 Fill memory
179 ------------------------------------------------------------------------ */
180
181
182 // Tentative memset
MI_CpuFill32(void * dest,u32 data,u32 size)183 inline void MI_CpuFill32(void* dest, u32 data, u32 size)
184 {
185 u32* pDest = reinterpret_cast<u32*>(dest);
186 NN_TASSERT_(((u32)pDest & 0xfffffffc) == (u32)pDest); // dest should be 4-byte aligned
187 NN_TASSERT_((size & 0xfffffffc) == size); // size should be 4-byte aligned
188 for(int i = 0; i < size / 4; ++i)
189 {
190 pDest[i] = data;
191 }
192 }
193
194 inline void
FillAllocMemory(NNSiFndHeapHead * pHeapHd,void * address,u32 size)195 FillAllocMemory(
196 NNSiFndHeapHead* pHeapHd,
197 void* address,
198 u32 size
199 )
200 {
201
202 if (GetOptForHeap(pHeapHd) & NN_OS_HEAP_OPT_0_CLEAR)
203 {
204 MI_CpuFill32(address, 0, size);
205 }
206 else
207 {
208 #if ! defined(NN_SWITCH_DISABLE_DEBUG_PRINT)
209 if (GetOptForHeap(pHeapHd) & NN_OS_HEAP_OPT_DEBUG_FILL)
210 {
211 MI_CpuFill32(address, GetFillValForHeap(NN_OS_HEAP_FILL_ALLOC), size);
212 }
213 #endif
214 }
215 }
216
217 #if defined(NN_SWITCH_DISABLE_DEBUG_PRINT)
218 #define FillFreeMemory(pHeapHd, address, size) ((void) 0)
219 #else
220 inline void
FillFreeMemory(NNSiFndHeapHead * pHeapHd,void * address,u32 size)221 FillFreeMemory(
222 NNSiFndHeapHead* pHeapHd,
223 void* address,
224 u32 size
225 )
226 {
227 if (GetOptForHeap(pHeapHd) & NN_OS_HEAP_OPT_DEBUG_FILL)
228 {
229 MI_CpuFill32(address, GetFillValForHeap(NN_OS_HEAP_FILL_FREE), size);
230 }
231 }
232 #endif
233
234 #if defined(NN_SWITCH_DISABLE_DEBUG_PRINT)
235 #define FillNoUseMemory(pHeapHd, address, size) ((void) 0)
236 #else
237 inline void
FillNoUseMemory(NNSiFndHeapHead * pHeapHd,void * address,u32 size)238 FillNoUseMemory(
239 NNSiFndHeapHead* pHeapHd,
240 void* address,
241 u32 size
242 )
243 {
244 if (GetOptForHeap(pHeapHd) & NN_OS_HEAP_OPT_DEBUG_FILL)
245 {
246 MI_CpuFill32(address, GetFillValForHeap(NN_OS_HEAP_FILL_NOUSE), size);
247 }
248 }
249 #endif
250
251
252 /* =======================================================================
253 Function Prototypes
254 ======================================================================== */
255
256 void NNSi_FndInitHeapHead(
257 NNSiFndHeapHead* pHeapHd,
258 u32 signature,
259 void* heapStart,
260 void* heapEnd,
261 u16 optFlag);
262
263 void NNSi_FndFinalizeHeap(
264 NNSiFndHeapHead* pHeapHd);
265
266 void NNSi_FndDumpHeapHead(
267 NNSiFndHeapHead const* pHeapHd);
268
269 //
270
271 }}} // namespace nn::os
272
273 #endif // __cplusplus
274
275 /* NN_OS_HEAPCOMMONI_H_ */
276 #endif /* NN_OS_OS_HEAPCOMMONIMPL_H_ */
277