source: svn/trunk/newcon3bcm2_21bu/magnum/basemodules/mem/bmem_local.c @ 11

Last change on this file since 11 was 2, checked in by phkim, 11 years ago

1.phkim

  1. revision copy newcon3sk r27
  • Property svn:executable set to *
File size: 12.8 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2002-2012, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: bmem_local.c $
11 * $brcm_Revision: Hydra_Software_Devel/26 $
12 * $brcm_Date: 2/7/12 6:36p $
13 *
14 * Module Description:
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/basemodules/mem/bmem_local.c $
19 *
20 * Hydra_Software_Devel/26   2/7/12 6:36p albertl
21 * SW7425-2345: Changed total allocation and number of allocation tracking
22 * to work in eFastest.
23 *
24 * Hydra_Software_Devel/25   11/14/11 2:22p albertl
25 * SW7425-1293: Fixed use of uncached address when cached addresses exist
26 * during heap creation.  Fixed coverity issues.
27 *
28 * Hydra_Software_Devel/24   9/9/11 7:10p albertl
29 * SW7346-201: Moved watermark calculation to alloc and free for accurate
30 * calculation.
31 *
32 * Hydra_Software_Devel/23   3/28/11 5:12p albertl
33 * SW7425-247: Incorporated BDBG_OBJECT handle validation.
34 *
35 * Hydra_Software_Devel/22   1/10/11 3:32p albertl
36 * SW7408-193: BMEM_Heapinfo now includes high watermark.  Added
37 * BMEM_Heap_ResetHighWatermark().
38 *
39 * Hydra_Software_Devel/21   11/8/10 4:48p albertl
40 * SW7420-1155: Fixed size calculation to match fixed implementation of
41 * pEnd.
42 *
43 * Hydra_Software_Devel/20   11/4/10 7:39p albertl
44 * SW7420-1155: Fixed pEnd to really be last available byte and addrEnd to
45 * be last byte in chunk rather than byte after that.
46 *
47 * Hydra_Software_Devel/19   5/26/09 4:18p albertl
48 * PR55389: Replaced uintptr_t with uint32_t.
49 *
50 * Hydra_Software_Devel/18   7/12/07 6:26p albertl
51 * PR31066:  Updated warning message to give platform and user specified
52 * uiAlignment size.
53 *
54 * Hydra_Software_Devel/17   7/6/07 6:53p albertl
55 * PR31066:  Changed BMEM_HEAP_ALIGNMENT to 6 for 7400 B0 and later and
56 * 7405.  Added warnings when user specified alignment is less than and
57 * forced to BMEM_HEAP_ALIGNMENT.
58 *
59 * Hydra_Software_Devel/16   3/15/07 7:23p albertl
60 * PR28682:  Changed BMEM_GUARD_SIZE_BYTES to be dynamically calculated
61 * based on runtime safety config.
62 *
63 * Hydra_Software_Devel/15   6/21/06 3:11p albertl
64 * PR20247:  Moved safety config table to bmem.c  BMEM_P_Heap now uses a
65 * BMEM_P_SafetyConfigInfo pointer to track safety configuration settings
66 * instead of tracking each configuration separately.
67 *
68 * Hydra_Software_Devel/14   6/16/06 3:23p albertl
69 * PR20247, PR20276, PR20354:  Added the ability to control debug
70 * configuration at runtime.  Added address and offset checking to
71 * conversion functions.  BMEM_SetCache can now only be called before
72 * heaps are allocated from.  Added BMEM_Heap functions.
73 *
74 * Hydra_Software_Devel/13   10/7/05 3:53p jasonh
75 * PR 17374: Allowed GetHeapInfo to return original creation parameters.
76 *
77 * Hydra_Software_Devel/12   3/10/05 5:05p albertl
78 * PR13677:  Both local and system bookkeeping made available at heap
79 * creation though functions BMEM_CreateHeapSystem and
80 * BMEM_CreateHeapLocal.
81 *
82 * Hydra_Software_Devel/11   1/21/05 4:23p albertl
83 * PR13717:  Replaced BMEM_DBG_ENTER with BDBG_ENTER.  Moved printouts to
84 * DBG_MSG, fixed pvHeap.
85 *
86 * Hydra_Software_Devel/10   11/2/04 5:27p pntruong
87 * PR13076: Initialized new members added.
88 *
89 * Hydra_Software_Devel/9   4/1/04 12:49p vsilyaev
90 * PR 10201: Added memory monitor
91 *
92 * Hydra_Software_Devel/8   12/31/03 12:02p jasonh
93 * PR 8940: Changed return type of destroyheap to void. Removed use of
94 * DEBUG macro and printf.
95 *
96 * Hydra_Software_Devel/7   9/15/03 5:21p jasonh
97 * Fixed heap control to store offset and address. Added local specific
98 * destroy heap function.
99 *
100 * Hydra_Software_Devel/6   9/5/03 2:04p jasonh
101 * Changed Check to ValidateHeap.
102 *
103 * Hydra_Software_Devel/5   9/5/03 1:41p jasonh
104 * Wrapped unused arguments with BSTD_UNUSED.
105 *
106 * Hydra_Software_Devel/4   9/2/03 1:48p vadim
107 * Some magnum updates.
108 *
109 * Hydra_Software_Devel/2   3/20/03 3:51p erickson
110 * renamed all MEM_ to BMEM_
111 *
112 * Hydra_Software_Devel/1   3/20/03 3:24p erickson
113 * initial bmem work, taken from SetTop/memorylib
114 *
115 * SanJose_DVTSW_Devel\4   4/15/02 10:14p eric
116 * BMEM_CheckHeap is dead.  Long live bcmHeapCheck.
117 *
118 * SanJose_DVTSW_Devel\3   4/15/02 3:34p poz
119 * Updated function name to bcmHeapCreate.
120 *
121 * SanJose_DVTSW_Devel\2   4/15/02 2:29p poz
122 * Modified to get semaphore when BMEM_REENTRANT.
123 *
124 * SanJose_DVTSW_Devel\1   4/15/02 1:35p poz
125 * Implementation of local-memory heap manager.
126 *
127 ***************************************************************************/
128
129#include "bstd.h"
130#include "bmem.h"
131#include "bmem_config.h"
132#include "bmem_priv.h"
133#include "bmem_debug.h"
134#include "berr.h"
135
136BDBG_MODULE(BMEM);
137
138/**********************************************************************func*
139 * BMEM_P_LocalGetAddress - Get the managed memory base address for a
140 *                           block.
141 *
142 * Returns:
143 *    0 if a NULL BlockInfo is given, otherwise the base address.
144 */
145
146uint32_t BMEM_P_LocalGetAddress
147(
148        BMEM_Handle pheap,
149        BMEM_P_BlockInfo *pbi
150)
151{
152        BSTD_UNUSED( pheap );
153        return (uint32_t) pbi;
154}
155
156/**********************************************************************func*
157 * BMEM_P_LocalGetBlockInfo - Get the bookkeeping info for a managed base
158 *                             address.
159 *
160 * Local implementation just returns the address, being also the location
161 * of the bookkeeping info.
162 *
163 * Returns:
164 *    On success, a pointer to the BlockInfo for the managed base address.
165 *
166 */
167
168BMEM_P_BlockInfo *BMEM_P_LocalGetBlockInfo
169(
170        BMEM_Handle pheap,
171        uint32_t addr
172)
173{
174        BSTD_UNUSED( pheap );
175        return (BMEM_P_BlockInfo *) addr;
176}
177
178/**********************************************************************func*
179 * BMEM_P_LocalDropBlockInfo -
180 *    Free up the bookkeeping info for a managed memory base address
181 *
182 * Returns:
183 *    void
184 */
185
186void BMEM_P_LocalDropBlockInfo
187(
188        BMEM_Handle pheap,
189        BMEM_P_BlockInfo *pbi
190)
191{
192        BSTD_UNUSED( pheap );
193        BSTD_UNUSED( pbi );
194        return;
195}
196
197
198/**********************************************************************func*
199 * BMEM_CreateHeapLocal - Initializes the heap with local bookkeeping.
200 *
201 * This function inititalizes a heap at a given location and size.
202 * Any previous allocations in the chunk of memory handed over to this
203 * function are lost. Every heap has a base minimum alignment for all of
204 * the allocations within that heap. (However, you can specify a greater
205 * alignment when actually doing an allocation.)
206 *
207 * In this implementation, the first bit of the heap is used to store heap
208 * information such as pointers to the free and used list, as well as other
209 * bookkeeping information.
210 *
211 * Returns:
212 *   Returns true if heap is initialized, or false if the given memory
213 *   chunk is too small to be a heap.
214 *
215 */
216BERR_Code BMEM_CreateHeapLocal
217(
218        BMEM_Handle  *ppHeap,      /* Address to store pointer of new heap info structure */
219        void         *pvHeap,      /* Pointer to beginning of memory chunk to manage */
220        uint32_t      ulOffset,    /* Device offset of initial location */
221        size_t        zSize,       /* Size of chunk to manage in bytes */
222        unsigned int  uiAlignment  /* Minimum alignment for all allocations in the heap */
223)
224{
225        BMEM_Heap_Settings stHeapSettings;
226        BMEM_Heap_Settings *pHeapSettings = &stHeapSettings;
227
228        BMEM_Heap_GetDefaultSettings(pHeapSettings);
229
230        pHeapSettings->uiAlignment = uiAlignment;
231        pHeapSettings->eBookKeeping = BMEM_BOOKKEEPING_LOCAL;
232
233        return (BMEM_Heap_Create(NULL, pvHeap, ulOffset, zSize, pHeapSettings, ppHeap));
234}
235
236BERR_Code BMEM_P_LocalCreateHeap
237(
238        BMEM_Handle        *ppHeap,      /* Address to store pointer of new heap info structure */
239        void               *pvHeap,      /* Pointer to beginning of memory chunk to manage */
240        uint32_t            ulOffset,    /* Device offset of initial location */
241        size_t              zSize,       /* Size of chunk to manage in bytes */
242        BMEM_Heap_Settings *pHeapSettings
243)
244{
245        BERR_Code         err = BERR_SUCCESS;
246        BMEM_Handle       pheap;
247        BMEM_P_BlockInfo *pbi;
248        uint32_t          addrHeap;
249        uint32_t          addrEnd = (uint32_t)pvHeap + zSize - 1;
250        unsigned int      uiAlignment = pHeapSettings->uiAlignment;
251        size_t            ulAlignedSize;
252        uint32_t          eSafetyConfig = pHeapSettings->eSafetyConfig;
253
254        BDBG_ENTER(BMEM_P_LocalCreateHeap);
255        BDBG_MSG(("BMEM_P_LocalCreateHeap(%p, %lu, %d)",
256                pvHeap, zSize, (int)pHeapSettings->uiAlignment));
257
258        if (pHeapSettings->eSafetyConfig > BMEM_P_SafetyTableSize)
259        {
260                /* Invalid safety config. */
261                err = BERR_TRACE(BERR_INVALID_PARAMETER);
262                goto done;
263        }
264
265        if (pHeapSettings->eSafetyConfig > BMEM_SAFETY_CONFIG)
266        {
267                /* Invalid run-time safety config. */
268                        BDBG_ERR(("Run-time safety config cannot be higher than compiled safety config!"));
269                        err = BERR_TRACE(BERR_INVALID_PARAMETER);
270                goto done;
271        }
272
273
274        /*
275         * The first bit of the heap is used to hold information about the heap
276         * itself. This is forced to a 4-byte alignment if for some reason we
277         * were given a non-aligned pointer.
278         */
279        addrHeap = BMEM_HEAP_ALIGN( pvHeap );
280        if( addrEnd < addrHeap + sizeof **ppHeap - 1)
281        {
282                /* There is no way to use this as a heap. It's too small. */
283                err = BERR_TRACE(BERR_OUT_OF_DEVICE_MEMORY);
284                goto done;
285        }
286
287        /* get location of heap */
288        *ppHeap = pheap = (BMEM_Handle) addrHeap;
289        addrHeap += sizeof (*pheap);
290
291        /* initialize heap */
292        BDBG_OBJECT_SET(pheap, BMEM_Heap);
293        pheap->pFreeTop = NULL;
294        pheap->pAllocTop = NULL;
295        pheap->ulAlignMask = 0;
296        pheap->pStart = NULL;
297        pheap->pEnd = NULL;
298        pheap->ulNumErrors = 0;
299        pheap->pvData = NULL;
300        pheap->pvHeap = pvHeap;
301        pheap->ulOffset = ulOffset;
302        pheap->monitor = NULL;
303        pheap->pvCache = pHeapSettings->pCachedAddress;
304        pheap->pfFlushCb = pHeapSettings->flush;
305        pheap->pfFlushCb_isr = pHeapSettings->flush_isr;
306        pheap->zSize = zSize;
307        pheap->ulNumAllocated = 0;
308        pheap->ulTotalAllocated = 0;
309        pheap->ulHighWatermark = 0;
310
311        pheap->pSafetyConfigInfo = &(BMEM_P_SafetyConfigTbl[eSafetyConfig]);
312        pheap->ulGuardSizeBytes  = pheap->pSafetyConfigInfo->iGuardSize * BMEM_GUARD_UNIT_BYTES;
313
314        pheap->eBookKeeping = pHeapSettings->eBookKeeping;
315        pheap->bCacheLocked = false;
316
317        pheap->pGetAddressFunc = &BMEM_P_LocalGetAddress;
318        pheap->pGetBlockInfoFunc = &BMEM_P_LocalGetBlockInfo;
319        pheap->pDropBlockInfoFunc = &BMEM_P_LocalDropBlockInfo;
320        pheap->pDestroyHeapFunc = &BMEM_P_LocalDestroyHeap;
321
322#if (BMEM_REENTRANT_CONFIG==BMEM_REENTRANT)
323        /* create mutex for re-entrant control */
324        if(BKNI_CreateMutex(&(pheap->pMutex)) != BERR_SUCCESS)
325        {
326                err = BERR_OS_ERROR;
327                goto done;
328        }
329#endif
330
331        /*
332         * The minimum alignment allowed is 4 bytes since that is the required
333         * alignment for the bookkeeping information.
334         */
335        if(uiAlignment < BMEM_HEAP_ALIGNMENT)
336        {
337                BDBG_WRN(("uiAlignment %d less than platform minimum %d.  Setting alignment to minimum.", uiAlignment, BMEM_HEAP_ALIGNMENT));
338                uiAlignment = BMEM_HEAP_ALIGNMENT;
339        }
340        pheap->uiAlignment = uiAlignment;
341        pheap->ulAlignMask = (1L << uiAlignment) - 1;
342
343        /* Align the heap to be on the requested alignment. */
344        pheap->pStart = (uint8_t *)((addrHeap+pheap->ulAlignMask) & ~pheap->ulAlignMask);
345        /* Last usable byte after alignment. */
346        pheap->pEnd = (uint8_t *)(((addrEnd + 1) & ~pheap->ulAlignMask) - 1);
347
348        /* Make the first block, which represents the remaining (free) heap */
349        pbi = BMEM_P_LocalGetBlockInfo(pheap, (uint32_t)pheap->pStart);
350
351        ulAlignedSize = pheap->pEnd-pheap->pStart+1;
352
353        if(ulAlignedSize > BMEM_BOOKKEEPING_SIZE_LOCAL)
354        {
355                /* Create a free block representing the entire heap. */
356                pbi->ulSize = ulAlignedSize;
357                pbi->ulFrontScrap = 0;
358                pbi->ulBackScrap = 0;
359                pbi->pnext = NULL;
360                BMEM_P_FillGuard(pheap, pbi);
361
362                pheap->pFreeTop = pbi;
363        }
364        else
365        {
366                /* The chunk of memory we've been given is too small for a heap. */
367                err = BERR_OS_ERROR;
368        }
369
370#if BMEM_CHECK_ALL_GUARDS
371        if (pheap->pSafetyConfigInfo->bCheckAllGuards)
372        {
373                if (err)
374                {
375                        BMEM_ValidateHeap(pheap);
376                }
377        }
378#endif
379
380done:
381        BDBG_MSG(("BMEM_P_LocalCreateHeap = %d", err));
382        BDBG_LEAVE(BMEM_P_LocalCreateHeap);
383        return err;
384}
385
386/***************************************************************************/
387void BMEM_P_LocalDestroyHeap
388(
389        BMEM_Handle pheap
390)
391{
392#if BMEM_CHECK_ALL_GUARDS
393        BERR_Code  err;
394#endif
395
396        BDBG_OBJECT_ASSERT(pheap, BMEM_Heap);
397
398#if BMEM_CHECK_ALL_GUARDS
399        if (pheap->pSafetyConfigInfo->bCheckAllGuards)
400        {
401                /* validate heap */
402                err = BERR_TRACE(BMEM_ValidateHeap(pheap));
403                if (err != BERR_SUCCESS)
404                {
405                        /* error validating heap */
406                        goto done;
407                }
408        }
409#endif
410
411        /* blocks still allocated? */
412        if (pheap->pAllocTop)
413        {
414                /* leaked resource */
415                BDBG_ERR(("Leaked resource -- unfreed blocks detected"));
416        }
417
418        BDBG_OBJECT_UNSET(pheap, BMEM_Heap);
419#if (BMEM_REENTRANT_CONFIG==BMEM_REENTRANT)
420        /* destroy mutex */
421        BKNI_DestroyMutex(pheap->pMutex);
422#endif
423
424done:
425        /* return */
426        return;
427}
428
429/* End of File */
Note: See TracBrowser for help on using the repository browser.