1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: fnd_DetailHeapCommonImpl.h
4
5 Copyright (C)2009 Nintendo Co., Ltd. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Rev: 12449 $
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 /// @cond
25
26 /* =======================================================================
27 型定義
28 ======================================================================== */
29
30 typedef s32 NNSiIntPtr; // void*ポインタと相互変換可能な符号付き整数型
31 typedef u32 NNSiUIntPtr; // void*ポインタと相互変換可能な符号無し整数型
32
33
34 /* ========================================================================
35 マクロ関数
36 ======================================================================== */
37
38 /*---------------------------------------------------------------------------*
39 Name: NNSi_FndRoundUp
40
41 Description: 指定した境界値に合わせるため、上位方向に切り上げます。
42
43 Arguments: value: 対象となるデータ
44 alignment: 境界値
45
46 Returns: 指定した境界に切り上げられた値を返します。
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
57 Description: 指定した境界値に合わせるため、下位方向に切り下げます。
58
59 Arguments: value: 対象となるデータ
60 alignment: 境界値
61
62 Returns: 指定した境界に切り下げられた値を返します。
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
73 Description: 特定のビット位置の値を取得します。
74
75 Arguments: data: 取得するビットデータを含むデータ。
76 st: 開始ビット(0から始まる)。
77 bits: ビット数(31以下とする)。
78
79 Returns: 特定のビット位置の値を返します。
80 *---------------------------------------------------------------------------*/
81 #define NNSi_FndGetBitValue(data, st, bits) \
82 (((data) >>(st)) & ((1 <<(bits)) -1))
83
84 /*---------------------------------------------------------------------------*
85 Name: NNSi_FndSetBitValue
86
87 Description: 特定のビット位置に値をセットします。
88
89 Arguments: data: セットするビットデータを格納する変数。
90 st: 開始ビット(0から始まる)。
91 bits: ビット数(31以下とする)。
92 val: セットするビットデータ。
93
94 Returns: なし。
95 *---------------------------------------------------------------------------*/
96 #define NNSi_FndSetBitValue(data, st, bits, val) \
97 do \
98 { \
99 u32 maskBits = (u32)((1 <<(bits)) -1); \
100 u32 newVal = (val) & maskBits; /* 安全のためマスク */ \
101 (void)(maskBits <<= st); \
102 (data) &= ~maskBits; /* セットする領域をクリア */ \
103 (data) |= newVal <<(st); \
104 } while(false);
105
106
107 /* ========================================================================
108 inline関数
109 ======================================================================== */
110
111 /* ------------------------------------------------------------------------
112 ポインタ操作
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 メモリ充填
179 ------------------------------------------------------------------------ */
180
181
182 // TORIAEZU: とりあえずな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 は4バイトアライメントされてるはず
187 NN_TASSERT_((size & 0xfffffffc) == size); // size は4バイトアライメントされてるはず
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 関数プロトタイプ
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 /// @endcond
270
271 }}} // namespace nn::os
272
273 #endif // __cplusplus
274
275 /* NN_OS_HEAPCOMMONI_H_ */
276 #endif /* NN_OS_OS_HEAPCOMMONIMPL_H_ */
277