1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     fnd_DetailHeapCommonImpl.h
4 
5   Copyright (C)2009-2012 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: 46347 $
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