1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     fnd_DetailHeapCommon.cpp
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 #include <nn/types.h>
17 #include <nn/assert.h>
18 #include "./fnd_DetailHeap.h"
19 #include "./fnd_DetailHeapCommon.h"
20 #include "./fnd_DetailHeapCommonImpl.h"
21 
22 
23 namespace nn { namespace fnd { namespace detail {
24 
25 /* ========================================================================
26     static variables
27    ======================================================================== */
28 
29 /* ------------------------------------------------------------------------
30     list-related
31    ------------------------------------------------------------------------ */
32 
33 static NNSFndList sRootList;                // root heap list
34 static bool sRootListInitialized = false;   // if sRootList is initialized, true
35 
36 
37 /* ------------------------------------------------------------------------
38     fill-related
39    ------------------------------------------------------------------------ */
40 
41 #ifdef NN_BUILD_VERBOSE
42 
43     static u32 sFillVals[NN_OS_HEAP_FILL_MAX] =
44     {
45         0xC3C3C3C3, // value to fill with when creating heap
46         0xF3F3F3F3, // value to fill with when allocating memory block
47         0xD3D3D3D3, // value to fill with when deallocating memory block
48     };
49 
50 // #ifdef NN_BUILD_VERBOSE
51 #endif
52 
53 
54 /* ========================================================================
55     Static functions
56    ======================================================================== */
57 
58 /* ------------------------------------------------------------------------
59     list-related
60    ------------------------------------------------------------------------ */
61 
62 /*---------------------------------------------------------------------------*
63   Name:         FindContainHeap
64   Description:  Searches recursively from the list for the heap that includes the specified memory block.
65 
66   Arguments:    pList:     Pointer to list
67                 memBlock:  Pointer to memory block
68   Returns:      When the heap that allocated the specified memory block is found, returns a pointer to that heap.
69 
70                 Returns NULL if it is not found.
71  *---------------------------------------------------------------------------
72 
73 
74 */
75 static NNSiFndHeapHead*
FindContainHeap(NNSFndList * pList,const void * memBlock)76 FindContainHeap(
77     NNSFndList* pList,
78     const void* memBlock
79 )
80 {
81     NNSiFndHeapHead* pHeapHd = NULL;
82     while (NULL != (pHeapHd = reinterpret_cast<NNSiFndHeapHead*>(
83                     GetNextListObject(pList, pHeapHd))))
84     {
85         if ( NNSiGetUIntPtr(pHeapHd->heapStart) <= NNSiGetUIntPtr(memBlock)
86          &&  NNSiGetUIntPtr(memBlock) < NNSiGetUIntPtr(pHeapHd->heapEnd)
87         )
88         {
89             NNSiFndHeapHead* pChildHeapHd = FindContainHeap(&pHeapHd->childList, memBlock);
90             if(pChildHeapHd)
91             {
92                 return pChildHeapHd;
93             }
94 
95             return pHeapHd;
96         }
97     }
98 
99     return NULL;
100 }
101 
102 /*---------------------------------------------------------------------------*
103   Name:         FindListContainHeap
104   Description:  Searches the parent heap that contains the heap, and returns a pointer to the parent heap list.
105 
106   Arguments:    pHeapHd:  Pointer to the header of search target heap
107   Returns:      If the parent heap that includes the specified heap is found, the pointer to the child list of the parent heap is returned.
108 
109                 If the parent heap is not found, a pointer to the root list is returned.
110  *---------------------------------------------------------------------------
111 
112 
113 */
114 static NNSFndList*
FindListContainHeap(NNSiFndHeapHead * pHeapHd)115 FindListContainHeap(NNSiFndHeapHead* pHeapHd)
116 {
117     NNSFndList* pList = &sRootList;
118 
119     NNSiFndHeapHead* pContainHeap = FindContainHeap(&sRootList, pHeapHd);
120 
121     if(pContainHeap)
122     {
123         pList = &pContainHeap->childList;
124     }
125 
126     return pList;
127 }
128 
129 #if 1
130     static inline void
131 //    static void
DumpHeapList()132     DumpHeapList() {}
133 #else
134     static void
DumpHeapList()135     DumpHeapList()
136     {
137         NNSiFndHeapHead* pHeapHd = NULL;
138         int count = 0;
139 
140         NN_TLOG_("Dump Heap List\n");
141         while (NULL != (pHeapHd = GetNextListObject(&sRootList, pHeapHd)))
142         {
143             count++;
144             NN_TLOG_("[%d] -> %p %08X\n", count, pHeapHd, pHeapHd->signature);
145         }
146     }
147 #endif
148 
149 /* ========================================================================
150     External functions (non-public)
151    ======================================================================== */
152 
153 /*---------------------------------------------------------------------------*
154   Name:         NNSi_FndInitHeapHead
155   Description:  Initializes the heap header.
156   Arguments:    pHeapHd:    Pointer to the heap header
157                 signature:  Signature
158                 heapStart:  Start address of heap memory
159                 heapEnd:    End address +1 of heap memory
160                 optFlag:    Heap option
161   Returns:      None.
162  *---------------------------------------------------------------------------
163 
164 
165 */
166 void
NNSi_FndInitHeapHead(NNSiFndHeapHead * pHeapHd,u32 signature,void * heapStart,void * heapEnd,u16 optFlag)167 NNSi_FndInitHeapHead(
168     NNSiFndHeapHead*    pHeapHd,
169     u32                 signature,
170     void*               heapStart,
171     void*               heapEnd,
172     u16                 optFlag
173 )
174 {
175     pHeapHd->signature = signature;
176 
177     pHeapHd->heapStart = heapStart;
178     pHeapHd->heapEnd   = heapEnd;
179 
180     pHeapHd->attribute = 0;
181     SetOptForHeap(pHeapHd, optFlag);
182 
183     FillNoUseMemory(
184         pHeapHd,
185         heapStart,
186         GetOffsetFromPtr(heapStart, heapEnd));
187 
188     NN_OS_INIT_LIST(&pHeapHd->childList, NNSiFndHeapHead, link);
189 
190     // heap list operation
191     if(! sRootListInitialized)
192     {
193         NN_OS_INIT_LIST(&sRootList, NNSiFndHeapHead, link);
194         sRootListInitialized = true;
195     }
196 
197     AppendListObject(FindListContainHeap(pHeapHd), pHeapHd);
198     DumpHeapList();
199 
200 }
201 
202 /*---------------------------------------------------------------------------*
203   Name:         NNSi_FndFinalizeHeap
204   Description:  Performs common heap cleanup.
205   Arguments:    pHeapHd:  Pointer to the heap header
206   Returns:      None.
207  *---------------------------------------------------------------------------
208 
209 
210 */
211 void
NNSi_FndFinalizeHeap(NNSiFndHeapHead * pHeapHd)212 NNSi_FndFinalizeHeap(NNSiFndHeapHead* pHeapHd)
213 {
214     // heap list operation
215     RemoveListObject(FindListContainHeap(pHeapHd), pHeapHd);
216     DumpHeapList();
217 }
218 
219 
220 /*---------------------------------------------------------------------------*
221   Name:         NNSi_FndDumpHeapHead
222   Description:  Displays heap header information.
223   Arguments:    pHeapHd:  Pointer to the heap header
224   Returns:      None.
225  *---------------------------------------------------------------------------
226 
227 
228 */
229 void
NNSi_FndDumpHeapHead(NNSiFndHeapHead const * pHeapHd)230 NNSi_FndDumpHeapHead(NNSiFndHeapHead const* pHeapHd)
231 {
232     NN_TLOG_("[NNS Foundation ");
233 
234     switch(pHeapHd->signature)
235     {
236     case NNSI_EXPHEAP_SIGNATURE: NN_TLOG_("Exp");   break;
237     case NNSI_FRMHEAP_SIGNATURE: NN_TLOG_("Frame"); break;
238     case NNSI_UNTHEAP_SIGNATURE: NN_TLOG_("Unit");  break;
239     default:
240         NN_TASSERT_(false);
241     }
242 
243     NN_TLOG_(" Heap]\n");
244 
245     NN_TLOG_("    whole [%p - %p)\n", pHeapHd, pHeapHd->heapEnd);
246 }
247 
248 
249 /* ========================================================================
250     External Functions (public)
251    ======================================================================== */
252 
253 /*---------------------------------------------------------------------------*
254   Name:         FindContainHeap
255   Description:  Searches for the heap containing the memory block.
256   Arguments:    memBlock:  Memory block to be searched for
257   Returns:      When the heap that includes the specified memory block is found, returns the handle of that heap.
258 
259                 If it is not found, NN_OS_HEAP_INVALID_HANDLE is returned.
260  *---------------------------------------------------------------------------
261 
262 
263 */
264 Heap
FindContainHeap(const void * memBlock)265 FindContainHeap(const void* memBlock)
266 {
267     return FindContainHeap(&sRootList, memBlock);
268 }
269 
270 /*---------------------------------------------------------------------------*
271   Name:         DumpHeap
272   Description:  Displays the information in the heap.
273                 This function is used for debugging.
274   Arguments:    heap:    Handle for the frame heap.
275   Returns:      None.
276  *---------------------------------------------------------------------------
277 
278 
279 */
280 #if ! defined(NN_SWITCH_DISABLE_DEBUG_PRINT_FOR_SDK)
281 
282     void
DumpHeap(Heap heap)283     DumpHeap(Heap heap)
284     {
285         NNSiFndHeapHead* pHeapHd = heap;
286         switch(pHeapHd->signature)
287         {
288         case NNSI_EXPHEAP_SIGNATURE: NNSi_FndDumpHeap(heap);  break;
289         default:
290             NN_TLOG_("[NNS Foundation] dump heap : unknown heap. - %p\n", heap);
291         }
292     }
293 
294 // #if ! defined(NN_SWITCH_DISABLE_DEBUG_PRINT_FOR_SDK)
295 #endif
296 
297 /*---------------------------------------------------------------------------*
298   Name:         SetFillValForHeap
299   Description:  Sets a value to set in memory when creating a heap or allocating or deallocating a memory block.
300 
301                 This function is for use in debugging.
302                 Always returns 0 in the final ROM version library (FINALROM).
303   Arguments:    type:  Type of value to get
304                 val:   Value to set
305   Returns:      Returns the previous value that was set in memory when the memory block was allocated.
306  *---------------------------------------------------------------------------
307 
308 
309 */
310 
311 #ifdef NN_BUILD_VERBOSE
312 
313     u32
SetFillValForHeap(int type,u32 val)314     SetFillValForHeap(
315         int     type,
316         u32     val
317     )
318     {
319         NN_TASSERT_(type < NN_OS_HEAP_FILL_MAX);
320 
321         {
322             u32 oldVal = sFillVals[type];
323             sFillVals[type] = val;
324             return oldVal;
325         }
326     }
327 
328 // #ifdef NN_BUILD_VERBOSE
329 #endif
330 
331 
332 /*---------------------------------------------------------------------------*
333   Name:         GetFillValForHeap
334   Description:  Gets the value to set in memory when creating a heap or allocating or deallocating a memory block.
335 
336                 This function is for use in debugging.
337                 Always returns 0 in the final ROM version library (FINALROM).
338   Arguments:    type:  Type of value to get
339   Returns:      Returns the value set in the memory of the type specified.
340  *---------------------------------------------------------------------------
341 
342 
343 */
344 
345 #ifdef NN_BUILD_VERBOSE
346 
347     u32
GetFillValForHeap(int type)348     GetFillValForHeap(int type)
349     {
350         NN_TASSERT_(type < NN_OS_HEAP_FILL_MAX);
351 
352         return sFillVals[type];
353     }
354 
355 // #ifdef NN_BUILD_VERBOSE
356 #endif
357 
358 }}} // namespace nn::os::fnd
359 
360