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