1*852ba100SJustin Hibbits /*
2*852ba100SJustin Hibbits * Copyright 2008-2012 Freescale Semiconductor Inc.
30aeed3e9SJustin Hibbits *
40aeed3e9SJustin Hibbits * Redistribution and use in source and binary forms, with or without
50aeed3e9SJustin Hibbits * modification, are permitted provided that the following conditions are met:
60aeed3e9SJustin Hibbits * * Redistributions of source code must retain the above copyright
70aeed3e9SJustin Hibbits * notice, this list of conditions and the following disclaimer.
80aeed3e9SJustin Hibbits * * Redistributions in binary form must reproduce the above copyright
90aeed3e9SJustin Hibbits * notice, this list of conditions and the following disclaimer in the
100aeed3e9SJustin Hibbits * documentation and/or other materials provided with the distribution.
110aeed3e9SJustin Hibbits * * Neither the name of Freescale Semiconductor nor the
120aeed3e9SJustin Hibbits * names of its contributors may be used to endorse or promote products
130aeed3e9SJustin Hibbits * derived from this software without specific prior written permission.
140aeed3e9SJustin Hibbits *
150aeed3e9SJustin Hibbits *
160aeed3e9SJustin Hibbits * ALTERNATIVELY, this software may be distributed under the terms of the
170aeed3e9SJustin Hibbits * GNU General Public License ("GPL") as published by the Free Software
180aeed3e9SJustin Hibbits * Foundation, either version 2 of that License or (at your option) any
190aeed3e9SJustin Hibbits * later version.
200aeed3e9SJustin Hibbits *
210aeed3e9SJustin Hibbits * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
220aeed3e9SJustin Hibbits * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
230aeed3e9SJustin Hibbits * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
240aeed3e9SJustin Hibbits * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
250aeed3e9SJustin Hibbits * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
260aeed3e9SJustin Hibbits * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
270aeed3e9SJustin Hibbits * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
280aeed3e9SJustin Hibbits * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
290aeed3e9SJustin Hibbits * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
300aeed3e9SJustin Hibbits * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
310aeed3e9SJustin Hibbits */
320aeed3e9SJustin Hibbits
33*852ba100SJustin Hibbits
340aeed3e9SJustin Hibbits #include "string_ext.h"
350aeed3e9SJustin Hibbits #include "error_ext.h"
360aeed3e9SJustin Hibbits #include "std_ext.h"
370aeed3e9SJustin Hibbits #include "part_ext.h"
380aeed3e9SJustin Hibbits #include "xx_ext.h"
390aeed3e9SJustin Hibbits
400aeed3e9SJustin Hibbits #include "mm.h"
410aeed3e9SJustin Hibbits
420aeed3e9SJustin Hibbits
430aeed3e9SJustin Hibbits
440aeed3e9SJustin Hibbits
450aeed3e9SJustin Hibbits /**********************************************************************
460aeed3e9SJustin Hibbits * MM internal routines set *
470aeed3e9SJustin Hibbits **********************************************************************/
480aeed3e9SJustin Hibbits
490aeed3e9SJustin Hibbits /****************************************************************
500aeed3e9SJustin Hibbits * Routine: CreateBusyBlock
510aeed3e9SJustin Hibbits *
520aeed3e9SJustin Hibbits * Description:
530aeed3e9SJustin Hibbits * Initializes a new busy block of "size" bytes and started
540aeed3e9SJustin Hibbits * rom "base" address. Each busy block has a name that
550aeed3e9SJustin Hibbits * specified the purpose of the memory allocation.
560aeed3e9SJustin Hibbits *
570aeed3e9SJustin Hibbits * Arguments:
580aeed3e9SJustin Hibbits * base - base address of the busy block
590aeed3e9SJustin Hibbits * size - size of the busy block
600aeed3e9SJustin Hibbits * name - name that specified the busy block
610aeed3e9SJustin Hibbits *
620aeed3e9SJustin Hibbits * Return value:
630aeed3e9SJustin Hibbits * A pointer to new created structure returned on success;
640aeed3e9SJustin Hibbits * Otherwise, NULL.
650aeed3e9SJustin Hibbits ****************************************************************/
CreateBusyBlock(uint64_t base,uint64_t size,char * name)660aeed3e9SJustin Hibbits static t_BusyBlock * CreateBusyBlock(uint64_t base, uint64_t size, char *name)
670aeed3e9SJustin Hibbits {
680aeed3e9SJustin Hibbits t_BusyBlock *p_BusyBlock;
690aeed3e9SJustin Hibbits uint32_t n;
700aeed3e9SJustin Hibbits
710aeed3e9SJustin Hibbits p_BusyBlock = (t_BusyBlock *)XX_Malloc(sizeof(t_BusyBlock));
720aeed3e9SJustin Hibbits if ( !p_BusyBlock )
730aeed3e9SJustin Hibbits {
740aeed3e9SJustin Hibbits REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
750aeed3e9SJustin Hibbits return NULL;
760aeed3e9SJustin Hibbits }
770aeed3e9SJustin Hibbits
780aeed3e9SJustin Hibbits p_BusyBlock->base = base;
790aeed3e9SJustin Hibbits p_BusyBlock->end = base + size;
800aeed3e9SJustin Hibbits
810aeed3e9SJustin Hibbits n = strlen(name);
820aeed3e9SJustin Hibbits if (n >= MM_MAX_NAME_LEN)
830aeed3e9SJustin Hibbits n = MM_MAX_NAME_LEN - 1;
840aeed3e9SJustin Hibbits strncpy(p_BusyBlock->name, name, MM_MAX_NAME_LEN-1);
850aeed3e9SJustin Hibbits p_BusyBlock->name[n] = '\0';
860aeed3e9SJustin Hibbits p_BusyBlock->p_Next = 0;
870aeed3e9SJustin Hibbits
880aeed3e9SJustin Hibbits return p_BusyBlock;
890aeed3e9SJustin Hibbits }
900aeed3e9SJustin Hibbits
910aeed3e9SJustin Hibbits /****************************************************************
920aeed3e9SJustin Hibbits * Routine: CreateNewBlock
930aeed3e9SJustin Hibbits *
940aeed3e9SJustin Hibbits * Description:
950aeed3e9SJustin Hibbits * Initializes a new memory block of "size" bytes and started
960aeed3e9SJustin Hibbits * from "base" address.
970aeed3e9SJustin Hibbits *
980aeed3e9SJustin Hibbits * Arguments:
990aeed3e9SJustin Hibbits * base - base address of the memory block
1000aeed3e9SJustin Hibbits * size - size of the memory block
1010aeed3e9SJustin Hibbits *
1020aeed3e9SJustin Hibbits * Return value:
1030aeed3e9SJustin Hibbits * A pointer to new created structure returned on success;
1040aeed3e9SJustin Hibbits * Otherwise, NULL.
1050aeed3e9SJustin Hibbits ****************************************************************/
CreateNewBlock(uint64_t base,uint64_t size)1060aeed3e9SJustin Hibbits static t_MemBlock * CreateNewBlock(uint64_t base, uint64_t size)
1070aeed3e9SJustin Hibbits {
1080aeed3e9SJustin Hibbits t_MemBlock *p_MemBlock;
1090aeed3e9SJustin Hibbits
1100aeed3e9SJustin Hibbits p_MemBlock = (t_MemBlock *)XX_Malloc(sizeof(t_MemBlock));
1110aeed3e9SJustin Hibbits if ( !p_MemBlock )
1120aeed3e9SJustin Hibbits {
1130aeed3e9SJustin Hibbits REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
1140aeed3e9SJustin Hibbits return NULL;
1150aeed3e9SJustin Hibbits }
1160aeed3e9SJustin Hibbits
1170aeed3e9SJustin Hibbits p_MemBlock->base = base;
1180aeed3e9SJustin Hibbits p_MemBlock->end = base+size;
1190aeed3e9SJustin Hibbits p_MemBlock->p_Next = 0;
1200aeed3e9SJustin Hibbits
1210aeed3e9SJustin Hibbits return p_MemBlock;
1220aeed3e9SJustin Hibbits }
1230aeed3e9SJustin Hibbits
1240aeed3e9SJustin Hibbits /****************************************************************
1250aeed3e9SJustin Hibbits * Routine: CreateFreeBlock
1260aeed3e9SJustin Hibbits *
1270aeed3e9SJustin Hibbits * Description:
1280aeed3e9SJustin Hibbits * Initializes a new free block of of "size" bytes and
1290aeed3e9SJustin Hibbits * started from "base" address.
1300aeed3e9SJustin Hibbits *
1310aeed3e9SJustin Hibbits * Arguments:
1320aeed3e9SJustin Hibbits * base - base address of the free block
1330aeed3e9SJustin Hibbits * size - size of the free block
1340aeed3e9SJustin Hibbits *
1350aeed3e9SJustin Hibbits * Return value:
1360aeed3e9SJustin Hibbits * A pointer to new created structure returned on success;
1370aeed3e9SJustin Hibbits * Otherwise, NULL.
1380aeed3e9SJustin Hibbits ****************************************************************/
CreateFreeBlock(uint64_t base,uint64_t size)1390aeed3e9SJustin Hibbits static t_FreeBlock * CreateFreeBlock(uint64_t base, uint64_t size)
1400aeed3e9SJustin Hibbits {
1410aeed3e9SJustin Hibbits t_FreeBlock *p_FreeBlock;
1420aeed3e9SJustin Hibbits
1430aeed3e9SJustin Hibbits p_FreeBlock = (t_FreeBlock *)XX_Malloc(sizeof(t_FreeBlock));
1440aeed3e9SJustin Hibbits if ( !p_FreeBlock )
1450aeed3e9SJustin Hibbits {
1460aeed3e9SJustin Hibbits REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
1470aeed3e9SJustin Hibbits return NULL;
1480aeed3e9SJustin Hibbits }
1490aeed3e9SJustin Hibbits
1500aeed3e9SJustin Hibbits p_FreeBlock->base = base;
1510aeed3e9SJustin Hibbits p_FreeBlock->end = base + size;
1520aeed3e9SJustin Hibbits p_FreeBlock->p_Next = 0;
1530aeed3e9SJustin Hibbits
1540aeed3e9SJustin Hibbits return p_FreeBlock;
1550aeed3e9SJustin Hibbits }
1560aeed3e9SJustin Hibbits
1570aeed3e9SJustin Hibbits /****************************************************************
1580aeed3e9SJustin Hibbits * Routine: AddFree
1590aeed3e9SJustin Hibbits *
1600aeed3e9SJustin Hibbits * Description:
1610aeed3e9SJustin Hibbits * Adds a new free block to the free lists. It updates each
1620aeed3e9SJustin Hibbits * free list to include a new free block.
1630aeed3e9SJustin Hibbits * Note, that all free block in each free list are ordered
1640aeed3e9SJustin Hibbits * by their base address.
1650aeed3e9SJustin Hibbits *
1660aeed3e9SJustin Hibbits * Arguments:
1670aeed3e9SJustin Hibbits * p_MM - pointer to the MM object
1680aeed3e9SJustin Hibbits * base - base address of a given free block
1690aeed3e9SJustin Hibbits * end - end address of a given free block
1700aeed3e9SJustin Hibbits *
1710aeed3e9SJustin Hibbits * Return value:
1720aeed3e9SJustin Hibbits *
1730aeed3e9SJustin Hibbits *
1740aeed3e9SJustin Hibbits ****************************************************************/
AddFree(t_MM * p_MM,uint64_t base,uint64_t end)1750aeed3e9SJustin Hibbits static t_Error AddFree(t_MM *p_MM, uint64_t base, uint64_t end)
1760aeed3e9SJustin Hibbits {
1770aeed3e9SJustin Hibbits t_FreeBlock *p_PrevB, *p_CurrB, *p_NewB;
1780aeed3e9SJustin Hibbits uint64_t alignment;
1790aeed3e9SJustin Hibbits uint64_t alignBase;
1800aeed3e9SJustin Hibbits int i;
1810aeed3e9SJustin Hibbits
1820aeed3e9SJustin Hibbits /* Updates free lists to include a just released block */
1830aeed3e9SJustin Hibbits for (i=0; i <= MM_MAX_ALIGNMENT; i++)
1840aeed3e9SJustin Hibbits {
1850aeed3e9SJustin Hibbits p_PrevB = p_NewB = 0;
1860aeed3e9SJustin Hibbits p_CurrB = p_MM->freeBlocks[i];
1870aeed3e9SJustin Hibbits
1880aeed3e9SJustin Hibbits alignment = (uint64_t)(0x1 << i);
1890aeed3e9SJustin Hibbits alignBase = MAKE_ALIGNED(base, alignment);
1900aeed3e9SJustin Hibbits
1910aeed3e9SJustin Hibbits /* Goes to the next free list if there is no block to free */
1920aeed3e9SJustin Hibbits if (alignBase >= end)
1930aeed3e9SJustin Hibbits continue;
1940aeed3e9SJustin Hibbits
1950aeed3e9SJustin Hibbits /* Looks for a free block that should be updated */
1960aeed3e9SJustin Hibbits while ( p_CurrB )
1970aeed3e9SJustin Hibbits {
1980aeed3e9SJustin Hibbits if ( alignBase <= p_CurrB->end )
1990aeed3e9SJustin Hibbits {
2000aeed3e9SJustin Hibbits if ( end > p_CurrB->end )
2010aeed3e9SJustin Hibbits {
2020aeed3e9SJustin Hibbits t_FreeBlock *p_NextB;
2030aeed3e9SJustin Hibbits while ( p_CurrB->p_Next && end > p_CurrB->p_Next->end )
2040aeed3e9SJustin Hibbits {
2050aeed3e9SJustin Hibbits p_NextB = p_CurrB->p_Next;
2060aeed3e9SJustin Hibbits p_CurrB->p_Next = p_CurrB->p_Next->p_Next;
2070aeed3e9SJustin Hibbits XX_Free(p_NextB);
2080aeed3e9SJustin Hibbits }
2090aeed3e9SJustin Hibbits
2100aeed3e9SJustin Hibbits p_NextB = p_CurrB->p_Next;
2110aeed3e9SJustin Hibbits if ( !p_NextB || (p_NextB && end < p_NextB->base) )
2120aeed3e9SJustin Hibbits {
2130aeed3e9SJustin Hibbits p_CurrB->end = end;
2140aeed3e9SJustin Hibbits }
2150aeed3e9SJustin Hibbits else
2160aeed3e9SJustin Hibbits {
2170aeed3e9SJustin Hibbits p_CurrB->end = p_NextB->end;
2180aeed3e9SJustin Hibbits p_CurrB->p_Next = p_NextB->p_Next;
2190aeed3e9SJustin Hibbits XX_Free(p_NextB);
2200aeed3e9SJustin Hibbits }
2210aeed3e9SJustin Hibbits }
2220aeed3e9SJustin Hibbits else if ( (end < p_CurrB->base) && ((end-alignBase) >= alignment) )
2230aeed3e9SJustin Hibbits {
2240aeed3e9SJustin Hibbits if ((p_NewB = CreateFreeBlock(alignBase, end-alignBase)) == NULL)
2250aeed3e9SJustin Hibbits RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
2260aeed3e9SJustin Hibbits
2270aeed3e9SJustin Hibbits p_NewB->p_Next = p_CurrB;
2280aeed3e9SJustin Hibbits if (p_PrevB)
2290aeed3e9SJustin Hibbits p_PrevB->p_Next = p_NewB;
2300aeed3e9SJustin Hibbits else
2310aeed3e9SJustin Hibbits p_MM->freeBlocks[i] = p_NewB;
2320aeed3e9SJustin Hibbits break;
2330aeed3e9SJustin Hibbits }
2340aeed3e9SJustin Hibbits
2350aeed3e9SJustin Hibbits if ((alignBase < p_CurrB->base) && (end >= p_CurrB->base))
2360aeed3e9SJustin Hibbits {
2370aeed3e9SJustin Hibbits p_CurrB->base = alignBase;
2380aeed3e9SJustin Hibbits }
2390aeed3e9SJustin Hibbits
2400aeed3e9SJustin Hibbits /* if size of the free block is less then alignment
2410aeed3e9SJustin Hibbits * deletes that free block from the free list. */
2420aeed3e9SJustin Hibbits if ( (p_CurrB->end - p_CurrB->base) < alignment)
2430aeed3e9SJustin Hibbits {
2440aeed3e9SJustin Hibbits if ( p_PrevB )
2450aeed3e9SJustin Hibbits p_PrevB->p_Next = p_CurrB->p_Next;
2460aeed3e9SJustin Hibbits else
2470aeed3e9SJustin Hibbits p_MM->freeBlocks[i] = p_CurrB->p_Next;
2480aeed3e9SJustin Hibbits XX_Free(p_CurrB);
249*852ba100SJustin Hibbits p_CurrB = NULL;
2500aeed3e9SJustin Hibbits }
2510aeed3e9SJustin Hibbits break;
2520aeed3e9SJustin Hibbits }
2530aeed3e9SJustin Hibbits else
2540aeed3e9SJustin Hibbits {
2550aeed3e9SJustin Hibbits p_PrevB = p_CurrB;
2560aeed3e9SJustin Hibbits p_CurrB = p_CurrB->p_Next;
2570aeed3e9SJustin Hibbits }
2580aeed3e9SJustin Hibbits }
2590aeed3e9SJustin Hibbits
2600aeed3e9SJustin Hibbits /* If no free block found to be updated, insert a new free block
2610aeed3e9SJustin Hibbits * to the end of the free list.
2620aeed3e9SJustin Hibbits */
2630aeed3e9SJustin Hibbits if ( !p_CurrB && ((((uint64_t)(end-base)) & ((uint64_t)(alignment-1))) == 0) )
2640aeed3e9SJustin Hibbits {
2650aeed3e9SJustin Hibbits if ((p_NewB = CreateFreeBlock(alignBase, end-base)) == NULL)
2660aeed3e9SJustin Hibbits RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
2670aeed3e9SJustin Hibbits
2680aeed3e9SJustin Hibbits if (p_PrevB)
2690aeed3e9SJustin Hibbits p_PrevB->p_Next = p_NewB;
2700aeed3e9SJustin Hibbits else
2710aeed3e9SJustin Hibbits p_MM->freeBlocks[i] = p_NewB;
2720aeed3e9SJustin Hibbits }
2730aeed3e9SJustin Hibbits
2740aeed3e9SJustin Hibbits /* Update boundaries of the new free block */
2750aeed3e9SJustin Hibbits if ((alignment == 1) && !p_NewB)
2760aeed3e9SJustin Hibbits {
2770aeed3e9SJustin Hibbits if ( p_CurrB && base > p_CurrB->base )
2780aeed3e9SJustin Hibbits base = p_CurrB->base;
2790aeed3e9SJustin Hibbits if ( p_CurrB && end < p_CurrB->end )
2800aeed3e9SJustin Hibbits end = p_CurrB->end;
2810aeed3e9SJustin Hibbits }
2820aeed3e9SJustin Hibbits }
2830aeed3e9SJustin Hibbits
2840aeed3e9SJustin Hibbits return (E_OK);
2850aeed3e9SJustin Hibbits }
2860aeed3e9SJustin Hibbits
2870aeed3e9SJustin Hibbits /****************************************************************
2880aeed3e9SJustin Hibbits * Routine: CutFree
2890aeed3e9SJustin Hibbits *
2900aeed3e9SJustin Hibbits * Description:
2910aeed3e9SJustin Hibbits * Cuts a free block from holdBase to holdEnd from the free lists.
2920aeed3e9SJustin Hibbits * That is, it updates all free lists of the MM object do
2930aeed3e9SJustin Hibbits * not include a block of memory from holdBase to holdEnd.
2940aeed3e9SJustin Hibbits * For each free lists it seek for a free block that holds
2950aeed3e9SJustin Hibbits * either holdBase or holdEnd. If such block is found it updates it.
2960aeed3e9SJustin Hibbits *
2970aeed3e9SJustin Hibbits * Arguments:
2980aeed3e9SJustin Hibbits * p_MM - pointer to the MM object
2990aeed3e9SJustin Hibbits * holdBase - base address of the allocated block
3000aeed3e9SJustin Hibbits * holdEnd - end address of the allocated block
3010aeed3e9SJustin Hibbits *
3020aeed3e9SJustin Hibbits * Return value:
3030aeed3e9SJustin Hibbits * E_OK is returned on success,
3040aeed3e9SJustin Hibbits * otherwise returns an error code.
3050aeed3e9SJustin Hibbits *
3060aeed3e9SJustin Hibbits ****************************************************************/
CutFree(t_MM * p_MM,uint64_t holdBase,uint64_t holdEnd)3070aeed3e9SJustin Hibbits static t_Error CutFree(t_MM *p_MM, uint64_t holdBase, uint64_t holdEnd)
3080aeed3e9SJustin Hibbits {
3090aeed3e9SJustin Hibbits t_FreeBlock *p_PrevB, *p_CurrB, *p_NewB;
3100aeed3e9SJustin Hibbits uint64_t alignBase, base, end;
3110aeed3e9SJustin Hibbits uint64_t alignment;
3120aeed3e9SJustin Hibbits int i;
3130aeed3e9SJustin Hibbits
3140aeed3e9SJustin Hibbits for (i=0; i <= MM_MAX_ALIGNMENT; i++)
3150aeed3e9SJustin Hibbits {
3160aeed3e9SJustin Hibbits p_PrevB = p_NewB = 0;
3170aeed3e9SJustin Hibbits p_CurrB = p_MM->freeBlocks[i];
3180aeed3e9SJustin Hibbits
3190aeed3e9SJustin Hibbits alignment = (uint64_t)(0x1 << i);
3200aeed3e9SJustin Hibbits alignBase = MAKE_ALIGNED(holdEnd, alignment);
3210aeed3e9SJustin Hibbits
3220aeed3e9SJustin Hibbits while ( p_CurrB )
3230aeed3e9SJustin Hibbits {
3240aeed3e9SJustin Hibbits base = p_CurrB->base;
3250aeed3e9SJustin Hibbits end = p_CurrB->end;
3260aeed3e9SJustin Hibbits
3270aeed3e9SJustin Hibbits if ( (holdBase <= base) && (holdEnd <= end) && (holdEnd > base) )
3280aeed3e9SJustin Hibbits {
3290aeed3e9SJustin Hibbits if ( alignBase >= end ||
3300aeed3e9SJustin Hibbits (alignBase < end && ((end-alignBase) < alignment)) )
3310aeed3e9SJustin Hibbits {
3320aeed3e9SJustin Hibbits if (p_PrevB)
3330aeed3e9SJustin Hibbits p_PrevB->p_Next = p_CurrB->p_Next;
3340aeed3e9SJustin Hibbits else
3350aeed3e9SJustin Hibbits p_MM->freeBlocks[i] = p_CurrB->p_Next;
3360aeed3e9SJustin Hibbits XX_Free(p_CurrB);
3370aeed3e9SJustin Hibbits }
3380aeed3e9SJustin Hibbits else
3390aeed3e9SJustin Hibbits {
3400aeed3e9SJustin Hibbits p_CurrB->base = alignBase;
3410aeed3e9SJustin Hibbits }
3420aeed3e9SJustin Hibbits break;
3430aeed3e9SJustin Hibbits }
3440aeed3e9SJustin Hibbits else if ( (holdBase > base) && (holdEnd <= end) )
3450aeed3e9SJustin Hibbits {
3460aeed3e9SJustin Hibbits if ( (holdBase-base) >= alignment )
3470aeed3e9SJustin Hibbits {
3480aeed3e9SJustin Hibbits if ( (alignBase < end) && ((end-alignBase) >= alignment) )
3490aeed3e9SJustin Hibbits {
3500aeed3e9SJustin Hibbits if ((p_NewB = CreateFreeBlock(alignBase, end-alignBase)) == NULL)
3510aeed3e9SJustin Hibbits RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
3520aeed3e9SJustin Hibbits p_NewB->p_Next = p_CurrB->p_Next;
3530aeed3e9SJustin Hibbits p_CurrB->p_Next = p_NewB;
3540aeed3e9SJustin Hibbits }
3550aeed3e9SJustin Hibbits p_CurrB->end = holdBase;
3560aeed3e9SJustin Hibbits }
3570aeed3e9SJustin Hibbits else if ( (alignBase < end) && ((end-alignBase) >= alignment) )
3580aeed3e9SJustin Hibbits {
3590aeed3e9SJustin Hibbits p_CurrB->base = alignBase;
3600aeed3e9SJustin Hibbits }
3610aeed3e9SJustin Hibbits else
3620aeed3e9SJustin Hibbits {
3630aeed3e9SJustin Hibbits if (p_PrevB)
3640aeed3e9SJustin Hibbits p_PrevB->p_Next = p_CurrB->p_Next;
3650aeed3e9SJustin Hibbits else
3660aeed3e9SJustin Hibbits p_MM->freeBlocks[i] = p_CurrB->p_Next;
3670aeed3e9SJustin Hibbits XX_Free(p_CurrB);
3680aeed3e9SJustin Hibbits }
3690aeed3e9SJustin Hibbits break;
3700aeed3e9SJustin Hibbits }
3710aeed3e9SJustin Hibbits else
3720aeed3e9SJustin Hibbits {
3730aeed3e9SJustin Hibbits p_PrevB = p_CurrB;
3740aeed3e9SJustin Hibbits p_CurrB = p_CurrB->p_Next;
3750aeed3e9SJustin Hibbits }
3760aeed3e9SJustin Hibbits }
3770aeed3e9SJustin Hibbits }
3780aeed3e9SJustin Hibbits
3790aeed3e9SJustin Hibbits return (E_OK);
3800aeed3e9SJustin Hibbits }
3810aeed3e9SJustin Hibbits
3820aeed3e9SJustin Hibbits /****************************************************************
3830aeed3e9SJustin Hibbits * Routine: AddBusy
3840aeed3e9SJustin Hibbits *
3850aeed3e9SJustin Hibbits * Description:
3860aeed3e9SJustin Hibbits * Adds a new busy block to the list of busy blocks. Note,
3870aeed3e9SJustin Hibbits * that all busy blocks are ordered by their base address in
3880aeed3e9SJustin Hibbits * the busy list.
3890aeed3e9SJustin Hibbits *
3900aeed3e9SJustin Hibbits * Arguments:
3910aeed3e9SJustin Hibbits * MM - handler to the MM object
3920aeed3e9SJustin Hibbits * p_NewBusyB - pointer to the a busy block
3930aeed3e9SJustin Hibbits *
3940aeed3e9SJustin Hibbits * Return value:
3950aeed3e9SJustin Hibbits * None.
3960aeed3e9SJustin Hibbits *
3970aeed3e9SJustin Hibbits ****************************************************************/
AddBusy(t_MM * p_MM,t_BusyBlock * p_NewBusyB)3980aeed3e9SJustin Hibbits static void AddBusy(t_MM *p_MM, t_BusyBlock *p_NewBusyB)
3990aeed3e9SJustin Hibbits {
4000aeed3e9SJustin Hibbits t_BusyBlock *p_CurrBusyB, *p_PrevBusyB;
4010aeed3e9SJustin Hibbits
4020aeed3e9SJustin Hibbits /* finds a place of a new busy block in the list of busy blocks */
4030aeed3e9SJustin Hibbits p_PrevBusyB = 0;
4040aeed3e9SJustin Hibbits p_CurrBusyB = p_MM->busyBlocks;
4050aeed3e9SJustin Hibbits
4060aeed3e9SJustin Hibbits while ( p_CurrBusyB && p_NewBusyB->base > p_CurrBusyB->base )
4070aeed3e9SJustin Hibbits {
4080aeed3e9SJustin Hibbits p_PrevBusyB = p_CurrBusyB;
4090aeed3e9SJustin Hibbits p_CurrBusyB = p_CurrBusyB->p_Next;
4100aeed3e9SJustin Hibbits }
4110aeed3e9SJustin Hibbits
4120aeed3e9SJustin Hibbits /* insert the new busy block into the list of busy blocks */
4130aeed3e9SJustin Hibbits if ( p_CurrBusyB )
4140aeed3e9SJustin Hibbits p_NewBusyB->p_Next = p_CurrBusyB;
4150aeed3e9SJustin Hibbits if ( p_PrevBusyB )
4160aeed3e9SJustin Hibbits p_PrevBusyB->p_Next = p_NewBusyB;
4170aeed3e9SJustin Hibbits else
4180aeed3e9SJustin Hibbits p_MM->busyBlocks = p_NewBusyB;
4190aeed3e9SJustin Hibbits }
4200aeed3e9SJustin Hibbits
4210aeed3e9SJustin Hibbits /****************************************************************
4220aeed3e9SJustin Hibbits * Routine: CutBusy
4230aeed3e9SJustin Hibbits *
4240aeed3e9SJustin Hibbits * Description:
4250aeed3e9SJustin Hibbits * Cuts a block from base to end from the list of busy blocks.
4260aeed3e9SJustin Hibbits * This is done by updating the list of busy blocks do not
4270aeed3e9SJustin Hibbits * include a given block, that block is going to be free. If a
4280aeed3e9SJustin Hibbits * given block is a part of some other busy block, so that
4290aeed3e9SJustin Hibbits * busy block is updated. If there are number of busy blocks
4300aeed3e9SJustin Hibbits * included in the given block, so all that blocks are removed
4310aeed3e9SJustin Hibbits * from the busy list and the end blocks are updated.
4320aeed3e9SJustin Hibbits * If the given block devides some block into two parts, a new
4330aeed3e9SJustin Hibbits * busy block is added to the busy list.
4340aeed3e9SJustin Hibbits *
4350aeed3e9SJustin Hibbits * Arguments:
4360aeed3e9SJustin Hibbits * p_MM - pointer to the MM object
4370aeed3e9SJustin Hibbits * base - base address of a given busy block
4380aeed3e9SJustin Hibbits * end - end address of a given busy block
4390aeed3e9SJustin Hibbits *
4400aeed3e9SJustin Hibbits * Return value:
4410aeed3e9SJustin Hibbits * E_OK on success, E_NOMEMORY otherwise.
4420aeed3e9SJustin Hibbits *
4430aeed3e9SJustin Hibbits ****************************************************************/
CutBusy(t_MM * p_MM,uint64_t base,uint64_t end)4440aeed3e9SJustin Hibbits static t_Error CutBusy(t_MM *p_MM, uint64_t base, uint64_t end)
4450aeed3e9SJustin Hibbits {
4460aeed3e9SJustin Hibbits t_BusyBlock *p_CurrB, *p_PrevB, *p_NewB;
4470aeed3e9SJustin Hibbits
4480aeed3e9SJustin Hibbits p_CurrB = p_MM->busyBlocks;
4490aeed3e9SJustin Hibbits p_PrevB = p_NewB = 0;
4500aeed3e9SJustin Hibbits
4510aeed3e9SJustin Hibbits while ( p_CurrB )
4520aeed3e9SJustin Hibbits {
4530aeed3e9SJustin Hibbits if ( base < p_CurrB->end )
4540aeed3e9SJustin Hibbits {
4550aeed3e9SJustin Hibbits if ( end > p_CurrB->end )
4560aeed3e9SJustin Hibbits {
4570aeed3e9SJustin Hibbits t_BusyBlock *p_NextB;
4580aeed3e9SJustin Hibbits while ( p_CurrB->p_Next && end >= p_CurrB->p_Next->end )
4590aeed3e9SJustin Hibbits {
4600aeed3e9SJustin Hibbits p_NextB = p_CurrB->p_Next;
4610aeed3e9SJustin Hibbits p_CurrB->p_Next = p_CurrB->p_Next->p_Next;
4620aeed3e9SJustin Hibbits XX_Free(p_NextB);
4630aeed3e9SJustin Hibbits }
4640aeed3e9SJustin Hibbits
4650aeed3e9SJustin Hibbits p_NextB = p_CurrB->p_Next;
4660aeed3e9SJustin Hibbits if ( p_NextB && end > p_NextB->base )
4670aeed3e9SJustin Hibbits {
4680aeed3e9SJustin Hibbits p_NextB->base = end;
4690aeed3e9SJustin Hibbits }
4700aeed3e9SJustin Hibbits }
4710aeed3e9SJustin Hibbits
4720aeed3e9SJustin Hibbits if ( base <= p_CurrB->base )
4730aeed3e9SJustin Hibbits {
4740aeed3e9SJustin Hibbits if ( end < p_CurrB->end && end > p_CurrB->base )
4750aeed3e9SJustin Hibbits {
4760aeed3e9SJustin Hibbits p_CurrB->base = end;
4770aeed3e9SJustin Hibbits }
4780aeed3e9SJustin Hibbits else if ( end >= p_CurrB->end )
4790aeed3e9SJustin Hibbits {
4800aeed3e9SJustin Hibbits if ( p_PrevB )
4810aeed3e9SJustin Hibbits p_PrevB->p_Next = p_CurrB->p_Next;
4820aeed3e9SJustin Hibbits else
4830aeed3e9SJustin Hibbits p_MM->busyBlocks = p_CurrB->p_Next;
4840aeed3e9SJustin Hibbits XX_Free(p_CurrB);
4850aeed3e9SJustin Hibbits }
4860aeed3e9SJustin Hibbits }
4870aeed3e9SJustin Hibbits else
4880aeed3e9SJustin Hibbits {
4890aeed3e9SJustin Hibbits if ( end < p_CurrB->end && end > p_CurrB->base )
4900aeed3e9SJustin Hibbits {
4910aeed3e9SJustin Hibbits if ((p_NewB = CreateBusyBlock(end,
4920aeed3e9SJustin Hibbits p_CurrB->end-end,
4930aeed3e9SJustin Hibbits p_CurrB->name)) == NULL)
4940aeed3e9SJustin Hibbits RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
4950aeed3e9SJustin Hibbits p_NewB->p_Next = p_CurrB->p_Next;
4960aeed3e9SJustin Hibbits p_CurrB->p_Next = p_NewB;
4970aeed3e9SJustin Hibbits }
4980aeed3e9SJustin Hibbits p_CurrB->end = base;
4990aeed3e9SJustin Hibbits }
5000aeed3e9SJustin Hibbits break;
5010aeed3e9SJustin Hibbits }
5020aeed3e9SJustin Hibbits else
5030aeed3e9SJustin Hibbits {
5040aeed3e9SJustin Hibbits p_PrevB = p_CurrB;
5050aeed3e9SJustin Hibbits p_CurrB = p_CurrB->p_Next;
5060aeed3e9SJustin Hibbits }
5070aeed3e9SJustin Hibbits }
5080aeed3e9SJustin Hibbits
5090aeed3e9SJustin Hibbits return (E_OK);
5100aeed3e9SJustin Hibbits }
5110aeed3e9SJustin Hibbits
5120aeed3e9SJustin Hibbits /****************************************************************
5130aeed3e9SJustin Hibbits * Routine: MmGetGreaterAlignment
5140aeed3e9SJustin Hibbits *
5150aeed3e9SJustin Hibbits * Description:
5160aeed3e9SJustin Hibbits * Allocates a block of memory according to the given size
5170aeed3e9SJustin Hibbits * and the alignment. That routine is called from the MM_Get
5180aeed3e9SJustin Hibbits * routine if the required alignment is greater then MM_MAX_ALIGNMENT.
5190aeed3e9SJustin Hibbits * In that case, it goes over free blocks of 64 byte align list
5200aeed3e9SJustin Hibbits * and checks if it has the required size of bytes of the required
5210aeed3e9SJustin Hibbits * alignment. If no blocks found returns ILLEGAL_BASE.
5220aeed3e9SJustin Hibbits * After the block is found and data is allocated, it calls
5230aeed3e9SJustin Hibbits * the internal CutFree routine to update all free lists
5240aeed3e9SJustin Hibbits * do not include a just allocated block. Of course, each
5250aeed3e9SJustin Hibbits * free list contains a free blocks with the same alignment.
5260aeed3e9SJustin Hibbits * It is also creates a busy block that holds
5270aeed3e9SJustin Hibbits * information about an allocated block.
5280aeed3e9SJustin Hibbits *
5290aeed3e9SJustin Hibbits * Arguments:
5300aeed3e9SJustin Hibbits * MM - handle to the MM object
5310aeed3e9SJustin Hibbits * size - size of the MM
5320aeed3e9SJustin Hibbits * alignment - index as a power of two defines
5330aeed3e9SJustin Hibbits * a required alignment that is greater then 64.
5340aeed3e9SJustin Hibbits * name - the name that specifies an allocated block.
5350aeed3e9SJustin Hibbits *
5360aeed3e9SJustin Hibbits * Return value:
5370aeed3e9SJustin Hibbits * base address of an allocated block.
5380aeed3e9SJustin Hibbits * ILLEGAL_BASE if can't allocate a block
5390aeed3e9SJustin Hibbits *
5400aeed3e9SJustin Hibbits ****************************************************************/
MmGetGreaterAlignment(t_MM * p_MM,uint64_t size,uint64_t alignment,char * name)5410aeed3e9SJustin Hibbits static uint64_t MmGetGreaterAlignment(t_MM *p_MM, uint64_t size, uint64_t alignment, char* name)
5420aeed3e9SJustin Hibbits {
5430aeed3e9SJustin Hibbits t_FreeBlock *p_FreeB;
5440aeed3e9SJustin Hibbits t_BusyBlock *p_NewBusyB;
5450aeed3e9SJustin Hibbits uint64_t holdBase, holdEnd, alignBase = 0;
5460aeed3e9SJustin Hibbits
5470aeed3e9SJustin Hibbits /* goes over free blocks of the 64 byte alignment list
5480aeed3e9SJustin Hibbits and look for a block of the suitable size and
5490aeed3e9SJustin Hibbits base address according to the alignment. */
5500aeed3e9SJustin Hibbits p_FreeB = p_MM->freeBlocks[MM_MAX_ALIGNMENT];
5510aeed3e9SJustin Hibbits
5520aeed3e9SJustin Hibbits while ( p_FreeB )
5530aeed3e9SJustin Hibbits {
5540aeed3e9SJustin Hibbits alignBase = MAKE_ALIGNED(p_FreeB->base, alignment);
5550aeed3e9SJustin Hibbits
5560aeed3e9SJustin Hibbits /* the block is found if the aligned base inside the block
5570aeed3e9SJustin Hibbits * and has the anough size. */
5580aeed3e9SJustin Hibbits if ( alignBase >= p_FreeB->base &&
5590aeed3e9SJustin Hibbits alignBase < p_FreeB->end &&
5600aeed3e9SJustin Hibbits size <= (p_FreeB->end - alignBase) )
5610aeed3e9SJustin Hibbits break;
5620aeed3e9SJustin Hibbits else
5630aeed3e9SJustin Hibbits p_FreeB = p_FreeB->p_Next;
5640aeed3e9SJustin Hibbits }
5650aeed3e9SJustin Hibbits
5660aeed3e9SJustin Hibbits /* If such block isn't found */
5670aeed3e9SJustin Hibbits if ( !p_FreeB )
5680aeed3e9SJustin Hibbits return (uint64_t)(ILLEGAL_BASE);
5690aeed3e9SJustin Hibbits
5700aeed3e9SJustin Hibbits holdBase = alignBase;
5710aeed3e9SJustin Hibbits holdEnd = alignBase + size;
5720aeed3e9SJustin Hibbits
5730aeed3e9SJustin Hibbits /* init a new busy block */
5740aeed3e9SJustin Hibbits if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
5750aeed3e9SJustin Hibbits return (uint64_t)(ILLEGAL_BASE);
5760aeed3e9SJustin Hibbits
5770aeed3e9SJustin Hibbits /* calls Update routine to update a lists of free blocks */
5780aeed3e9SJustin Hibbits if ( CutFree ( p_MM, holdBase, holdEnd ) != E_OK )
579*852ba100SJustin Hibbits {
580*852ba100SJustin Hibbits XX_Free(p_NewBusyB);
5810aeed3e9SJustin Hibbits return (uint64_t)(ILLEGAL_BASE);
582*852ba100SJustin Hibbits }
5830aeed3e9SJustin Hibbits
5840aeed3e9SJustin Hibbits /* insert the new busy block into the list of busy blocks */
5850aeed3e9SJustin Hibbits AddBusy ( p_MM, p_NewBusyB );
5860aeed3e9SJustin Hibbits
5870aeed3e9SJustin Hibbits return (holdBase);
5880aeed3e9SJustin Hibbits }
5890aeed3e9SJustin Hibbits
5900aeed3e9SJustin Hibbits
5910aeed3e9SJustin Hibbits /**********************************************************************
5920aeed3e9SJustin Hibbits * MM API routines set *
5930aeed3e9SJustin Hibbits **********************************************************************/
5940aeed3e9SJustin Hibbits
5950aeed3e9SJustin Hibbits /*****************************************************************************/
MM_Init(t_Handle * h_MM,uint64_t base,uint64_t size)5960aeed3e9SJustin Hibbits t_Error MM_Init(t_Handle *h_MM, uint64_t base, uint64_t size)
5970aeed3e9SJustin Hibbits {
5980aeed3e9SJustin Hibbits t_MM *p_MM;
5990aeed3e9SJustin Hibbits uint64_t newBase, newSize;
6000aeed3e9SJustin Hibbits int i;
6010aeed3e9SJustin Hibbits
6020aeed3e9SJustin Hibbits if (!size)
6030aeed3e9SJustin Hibbits {
6040aeed3e9SJustin Hibbits RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size (should be positive)"));
6050aeed3e9SJustin Hibbits }
6060aeed3e9SJustin Hibbits
6070aeed3e9SJustin Hibbits /* Initializes a new MM object */
6080aeed3e9SJustin Hibbits p_MM = (t_MM *)XX_Malloc(sizeof(t_MM));
6090aeed3e9SJustin Hibbits if (!p_MM)
6100aeed3e9SJustin Hibbits {
6110aeed3e9SJustin Hibbits RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
6120aeed3e9SJustin Hibbits }
6130aeed3e9SJustin Hibbits
6140aeed3e9SJustin Hibbits p_MM->h_Spinlock = XX_InitSpinlock();
6150aeed3e9SJustin Hibbits if (!p_MM->h_Spinlock)
6160aeed3e9SJustin Hibbits {
6170aeed3e9SJustin Hibbits XX_Free(p_MM);
6180aeed3e9SJustin Hibbits RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MM spinlock!"));
6190aeed3e9SJustin Hibbits }
6200aeed3e9SJustin Hibbits
621*852ba100SJustin Hibbits /* Initializes counter of free memory to total size */
622*852ba100SJustin Hibbits p_MM->freeMemSize = size;
6230aeed3e9SJustin Hibbits
6240aeed3e9SJustin Hibbits /* A busy list is empty */
6250aeed3e9SJustin Hibbits p_MM->busyBlocks = 0;
6260aeed3e9SJustin Hibbits
627*852ba100SJustin Hibbits /* Initializes a new memory block */
628*852ba100SJustin Hibbits if ((p_MM->memBlocks = CreateNewBlock(base, size)) == NULL)
629*852ba100SJustin Hibbits {
630*852ba100SJustin Hibbits MM_Free(p_MM);
631*852ba100SJustin Hibbits RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
632*852ba100SJustin Hibbits }
633*852ba100SJustin Hibbits
6340aeed3e9SJustin Hibbits /* Initializes a new free block for each free list*/
6350aeed3e9SJustin Hibbits for (i=0; i <= MM_MAX_ALIGNMENT; i++)
6360aeed3e9SJustin Hibbits {
6370aeed3e9SJustin Hibbits newBase = MAKE_ALIGNED( base, (0x1 << i) );
6380aeed3e9SJustin Hibbits newSize = size - (newBase - base);
6390aeed3e9SJustin Hibbits
6400aeed3e9SJustin Hibbits if ((p_MM->freeBlocks[i] = CreateFreeBlock(newBase, newSize)) == NULL)
641*852ba100SJustin Hibbits {
642*852ba100SJustin Hibbits MM_Free(p_MM);
6430aeed3e9SJustin Hibbits RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
6440aeed3e9SJustin Hibbits }
645*852ba100SJustin Hibbits }
6460aeed3e9SJustin Hibbits
6470aeed3e9SJustin Hibbits *h_MM = p_MM;
6480aeed3e9SJustin Hibbits
6490aeed3e9SJustin Hibbits return (E_OK);
6500aeed3e9SJustin Hibbits }
6510aeed3e9SJustin Hibbits
6520aeed3e9SJustin Hibbits /*****************************************************************************/
MM_Free(t_Handle h_MM)6530aeed3e9SJustin Hibbits void MM_Free(t_Handle h_MM)
6540aeed3e9SJustin Hibbits {
6550aeed3e9SJustin Hibbits t_MM *p_MM = (t_MM *)h_MM;
6560aeed3e9SJustin Hibbits t_MemBlock *p_MemBlock;
6570aeed3e9SJustin Hibbits t_BusyBlock *p_BusyBlock;
6580aeed3e9SJustin Hibbits t_FreeBlock *p_FreeBlock;
6590aeed3e9SJustin Hibbits void *p_Block;
6600aeed3e9SJustin Hibbits int i;
6610aeed3e9SJustin Hibbits
6620aeed3e9SJustin Hibbits ASSERT_COND(p_MM);
6630aeed3e9SJustin Hibbits
6640aeed3e9SJustin Hibbits /* release memory allocated for busy blocks */
6650aeed3e9SJustin Hibbits p_BusyBlock = p_MM->busyBlocks;
6660aeed3e9SJustin Hibbits while ( p_BusyBlock )
6670aeed3e9SJustin Hibbits {
6680aeed3e9SJustin Hibbits p_Block = p_BusyBlock;
6690aeed3e9SJustin Hibbits p_BusyBlock = p_BusyBlock->p_Next;
6700aeed3e9SJustin Hibbits XX_Free(p_Block);
6710aeed3e9SJustin Hibbits }
6720aeed3e9SJustin Hibbits
6730aeed3e9SJustin Hibbits /* release memory allocated for free blocks */
6740aeed3e9SJustin Hibbits for (i=0; i <= MM_MAX_ALIGNMENT; i++)
6750aeed3e9SJustin Hibbits {
6760aeed3e9SJustin Hibbits p_FreeBlock = p_MM->freeBlocks[i];
6770aeed3e9SJustin Hibbits while ( p_FreeBlock )
6780aeed3e9SJustin Hibbits {
6790aeed3e9SJustin Hibbits p_Block = p_FreeBlock;
6800aeed3e9SJustin Hibbits p_FreeBlock = p_FreeBlock->p_Next;
6810aeed3e9SJustin Hibbits XX_Free(p_Block);
6820aeed3e9SJustin Hibbits }
6830aeed3e9SJustin Hibbits }
6840aeed3e9SJustin Hibbits
6850aeed3e9SJustin Hibbits /* release memory allocated for memory blocks */
6860aeed3e9SJustin Hibbits p_MemBlock = p_MM->memBlocks;
6870aeed3e9SJustin Hibbits while ( p_MemBlock )
6880aeed3e9SJustin Hibbits {
6890aeed3e9SJustin Hibbits p_Block = p_MemBlock;
6900aeed3e9SJustin Hibbits p_MemBlock = p_MemBlock->p_Next;
6910aeed3e9SJustin Hibbits XX_Free(p_Block);
6920aeed3e9SJustin Hibbits }
6930aeed3e9SJustin Hibbits
6940aeed3e9SJustin Hibbits if (p_MM->h_Spinlock)
6950aeed3e9SJustin Hibbits XX_FreeSpinlock(p_MM->h_Spinlock);
6960aeed3e9SJustin Hibbits
6970aeed3e9SJustin Hibbits /* release memory allocated for MM object itself */
6980aeed3e9SJustin Hibbits XX_Free(p_MM);
6990aeed3e9SJustin Hibbits }
7000aeed3e9SJustin Hibbits
7010aeed3e9SJustin Hibbits /*****************************************************************************/
MM_Get(t_Handle h_MM,uint64_t size,uint64_t alignment,char * name)7020aeed3e9SJustin Hibbits uint64_t MM_Get(t_Handle h_MM, uint64_t size, uint64_t alignment, char* name)
7030aeed3e9SJustin Hibbits {
7040aeed3e9SJustin Hibbits t_MM *p_MM = (t_MM *)h_MM;
7050aeed3e9SJustin Hibbits t_FreeBlock *p_FreeB;
7060aeed3e9SJustin Hibbits t_BusyBlock *p_NewBusyB;
7070aeed3e9SJustin Hibbits uint64_t holdBase, holdEnd, j, i = 0;
7080aeed3e9SJustin Hibbits uint32_t intFlags;
7090aeed3e9SJustin Hibbits
7100aeed3e9SJustin Hibbits SANITY_CHECK_RETURN_VALUE(p_MM, E_INVALID_HANDLE, (uint64_t)ILLEGAL_BASE);
7110aeed3e9SJustin Hibbits
7120aeed3e9SJustin Hibbits /* checks that alignment value is greater then zero */
7130aeed3e9SJustin Hibbits if (alignment == 0)
7140aeed3e9SJustin Hibbits {
7150aeed3e9SJustin Hibbits alignment = 1;
7160aeed3e9SJustin Hibbits }
7170aeed3e9SJustin Hibbits
7180aeed3e9SJustin Hibbits j = alignment;
7190aeed3e9SJustin Hibbits
7200aeed3e9SJustin Hibbits /* checks if alignment is a power of two, if it correct and if the
7210aeed3e9SJustin Hibbits required size is multiple of the given alignment. */
7220aeed3e9SJustin Hibbits while ((j & 0x1) == 0)
7230aeed3e9SJustin Hibbits {
7240aeed3e9SJustin Hibbits i++;
7250aeed3e9SJustin Hibbits j = j >> 1;
7260aeed3e9SJustin Hibbits }
7270aeed3e9SJustin Hibbits
7280aeed3e9SJustin Hibbits /* if the given alignment isn't power of two, returns an error */
7290aeed3e9SJustin Hibbits if (j != 1)
7300aeed3e9SJustin Hibbits {
7310aeed3e9SJustin Hibbits REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("alignment (should be power of 2)"));
7320aeed3e9SJustin Hibbits return (uint64_t)ILLEGAL_BASE;
7330aeed3e9SJustin Hibbits }
7340aeed3e9SJustin Hibbits
7350aeed3e9SJustin Hibbits if (i > MM_MAX_ALIGNMENT)
7360aeed3e9SJustin Hibbits {
7370aeed3e9SJustin Hibbits return (MmGetGreaterAlignment(p_MM, size, alignment, name));
7380aeed3e9SJustin Hibbits }
7390aeed3e9SJustin Hibbits
7400aeed3e9SJustin Hibbits intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
7410aeed3e9SJustin Hibbits /* look for a block of the size greater or equal to the required size. */
7420aeed3e9SJustin Hibbits p_FreeB = p_MM->freeBlocks[i];
7430aeed3e9SJustin Hibbits while ( p_FreeB && (p_FreeB->end - p_FreeB->base) < size )
7440aeed3e9SJustin Hibbits p_FreeB = p_FreeB->p_Next;
7450aeed3e9SJustin Hibbits
7460aeed3e9SJustin Hibbits /* If such block is found */
7470aeed3e9SJustin Hibbits if ( !p_FreeB )
7480aeed3e9SJustin Hibbits {
7490aeed3e9SJustin Hibbits XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
7500aeed3e9SJustin Hibbits return (uint64_t)(ILLEGAL_BASE);
7510aeed3e9SJustin Hibbits }
7520aeed3e9SJustin Hibbits
7530aeed3e9SJustin Hibbits holdBase = p_FreeB->base;
7540aeed3e9SJustin Hibbits holdEnd = holdBase + size;
7550aeed3e9SJustin Hibbits
7560aeed3e9SJustin Hibbits /* init a new busy block */
7570aeed3e9SJustin Hibbits if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
7580aeed3e9SJustin Hibbits {
7590aeed3e9SJustin Hibbits XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
7600aeed3e9SJustin Hibbits return (uint64_t)(ILLEGAL_BASE);
7610aeed3e9SJustin Hibbits }
7620aeed3e9SJustin Hibbits
7630aeed3e9SJustin Hibbits /* calls Update routine to update a lists of free blocks */
7640aeed3e9SJustin Hibbits if ( CutFree ( p_MM, holdBase, holdEnd ) != E_OK )
7650aeed3e9SJustin Hibbits {
7660aeed3e9SJustin Hibbits XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
767*852ba100SJustin Hibbits XX_Free(p_NewBusyB);
7680aeed3e9SJustin Hibbits return (uint64_t)(ILLEGAL_BASE);
7690aeed3e9SJustin Hibbits }
7700aeed3e9SJustin Hibbits
771*852ba100SJustin Hibbits /* Decreasing the allocated memory size from free memory size */
772*852ba100SJustin Hibbits p_MM->freeMemSize -= size;
773*852ba100SJustin Hibbits
7740aeed3e9SJustin Hibbits /* insert the new busy block into the list of busy blocks */
7750aeed3e9SJustin Hibbits AddBusy ( p_MM, p_NewBusyB );
7760aeed3e9SJustin Hibbits XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
7770aeed3e9SJustin Hibbits
7780aeed3e9SJustin Hibbits return (holdBase);
7790aeed3e9SJustin Hibbits }
7800aeed3e9SJustin Hibbits
7810aeed3e9SJustin Hibbits /*****************************************************************************/
MM_GetForce(t_Handle h_MM,uint64_t base,uint64_t size,char * name)7820aeed3e9SJustin Hibbits uint64_t MM_GetForce(t_Handle h_MM, uint64_t base, uint64_t size, char* name)
7830aeed3e9SJustin Hibbits {
7840aeed3e9SJustin Hibbits t_MM *p_MM = (t_MM *)h_MM;
7850aeed3e9SJustin Hibbits t_FreeBlock *p_FreeB;
7860aeed3e9SJustin Hibbits t_BusyBlock *p_NewBusyB;
7870aeed3e9SJustin Hibbits uint32_t intFlags;
7880aeed3e9SJustin Hibbits bool blockIsFree = FALSE;
7890aeed3e9SJustin Hibbits
7900aeed3e9SJustin Hibbits ASSERT_COND(p_MM);
7910aeed3e9SJustin Hibbits
7920aeed3e9SJustin Hibbits intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
7930aeed3e9SJustin Hibbits p_FreeB = p_MM->freeBlocks[0]; /* The biggest free blocks are in the
7940aeed3e9SJustin Hibbits free list with alignment 1 */
7950aeed3e9SJustin Hibbits
7960aeed3e9SJustin Hibbits while ( p_FreeB )
7970aeed3e9SJustin Hibbits {
7980aeed3e9SJustin Hibbits if ( base >= p_FreeB->base && (base+size) <= p_FreeB->end )
7990aeed3e9SJustin Hibbits {
8000aeed3e9SJustin Hibbits blockIsFree = TRUE;
8010aeed3e9SJustin Hibbits break;
8020aeed3e9SJustin Hibbits }
8030aeed3e9SJustin Hibbits else
8040aeed3e9SJustin Hibbits p_FreeB = p_FreeB->p_Next;
8050aeed3e9SJustin Hibbits }
8060aeed3e9SJustin Hibbits
8070aeed3e9SJustin Hibbits if ( !blockIsFree )
8080aeed3e9SJustin Hibbits {
8090aeed3e9SJustin Hibbits XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
8100aeed3e9SJustin Hibbits return (uint64_t)(ILLEGAL_BASE);
8110aeed3e9SJustin Hibbits }
8120aeed3e9SJustin Hibbits
8130aeed3e9SJustin Hibbits /* init a new busy block */
8140aeed3e9SJustin Hibbits if ((p_NewBusyB = CreateBusyBlock(base, size, name)) == NULL)
8150aeed3e9SJustin Hibbits {
8160aeed3e9SJustin Hibbits XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
8170aeed3e9SJustin Hibbits return (uint64_t)(ILLEGAL_BASE);
8180aeed3e9SJustin Hibbits }
8190aeed3e9SJustin Hibbits
8200aeed3e9SJustin Hibbits /* calls Update routine to update a lists of free blocks */
8210aeed3e9SJustin Hibbits if ( CutFree ( p_MM, base, base+size ) != E_OK )
8220aeed3e9SJustin Hibbits {
8230aeed3e9SJustin Hibbits XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
824*852ba100SJustin Hibbits XX_Free(p_NewBusyB);
8250aeed3e9SJustin Hibbits return (uint64_t)(ILLEGAL_BASE);
8260aeed3e9SJustin Hibbits }
8270aeed3e9SJustin Hibbits
828*852ba100SJustin Hibbits /* Decreasing the allocated memory size from free memory size */
829*852ba100SJustin Hibbits p_MM->freeMemSize -= size;
830*852ba100SJustin Hibbits
8310aeed3e9SJustin Hibbits /* insert the new busy block into the list of busy blocks */
8320aeed3e9SJustin Hibbits AddBusy ( p_MM, p_NewBusyB );
8330aeed3e9SJustin Hibbits XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
8340aeed3e9SJustin Hibbits
8350aeed3e9SJustin Hibbits return (base);
8360aeed3e9SJustin Hibbits }
8370aeed3e9SJustin Hibbits
8380aeed3e9SJustin Hibbits /*****************************************************************************/
MM_GetForceMin(t_Handle h_MM,uint64_t size,uint64_t alignment,uint64_t min,char * name)8390aeed3e9SJustin Hibbits uint64_t MM_GetForceMin(t_Handle h_MM, uint64_t size, uint64_t alignment, uint64_t min, char* name)
8400aeed3e9SJustin Hibbits {
8410aeed3e9SJustin Hibbits t_MM *p_MM = (t_MM *)h_MM;
8420aeed3e9SJustin Hibbits t_FreeBlock *p_FreeB;
8430aeed3e9SJustin Hibbits t_BusyBlock *p_NewBusyB;
8440aeed3e9SJustin Hibbits uint64_t holdBase, holdEnd, j = alignment, i=0;
8450aeed3e9SJustin Hibbits uint32_t intFlags;
8460aeed3e9SJustin Hibbits
8470aeed3e9SJustin Hibbits ASSERT_COND(p_MM);
8480aeed3e9SJustin Hibbits
8490aeed3e9SJustin Hibbits /* checks if alignment is a power of two, if it correct and if the
8500aeed3e9SJustin Hibbits required size is multiple of the given alignment. */
8510aeed3e9SJustin Hibbits while ((j & 0x1) == 0)
8520aeed3e9SJustin Hibbits {
8530aeed3e9SJustin Hibbits i++;
8540aeed3e9SJustin Hibbits j = j >> 1;
8550aeed3e9SJustin Hibbits }
8560aeed3e9SJustin Hibbits
8570aeed3e9SJustin Hibbits if ( (j != 1) || (i > MM_MAX_ALIGNMENT) )
8580aeed3e9SJustin Hibbits {
8590aeed3e9SJustin Hibbits return (uint64_t)(ILLEGAL_BASE);
8600aeed3e9SJustin Hibbits }
8610aeed3e9SJustin Hibbits
8620aeed3e9SJustin Hibbits intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
8630aeed3e9SJustin Hibbits p_FreeB = p_MM->freeBlocks[i];
8640aeed3e9SJustin Hibbits
8650aeed3e9SJustin Hibbits /* look for the first block that contains the minimum
8660aeed3e9SJustin Hibbits base address. If the whole required size may be fit
8670aeed3e9SJustin Hibbits into it, use that block, otherwise look for the next
8680aeed3e9SJustin Hibbits block of size greater or equal to the required size. */
8690aeed3e9SJustin Hibbits while ( p_FreeB && (min >= p_FreeB->end))
8700aeed3e9SJustin Hibbits p_FreeB = p_FreeB->p_Next;
8710aeed3e9SJustin Hibbits
8720aeed3e9SJustin Hibbits /* If such block is found */
8730aeed3e9SJustin Hibbits if ( !p_FreeB )
8740aeed3e9SJustin Hibbits {
8750aeed3e9SJustin Hibbits XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
8760aeed3e9SJustin Hibbits return (uint64_t)(ILLEGAL_BASE);
8770aeed3e9SJustin Hibbits }
8780aeed3e9SJustin Hibbits
8790aeed3e9SJustin Hibbits /* if this block is large enough, use this block */
8800aeed3e9SJustin Hibbits holdBase = ( min <= p_FreeB->base ) ? p_FreeB->base : min;
8810aeed3e9SJustin Hibbits if ((holdBase + size) <= p_FreeB->end )
8820aeed3e9SJustin Hibbits {
8830aeed3e9SJustin Hibbits holdEnd = holdBase + size;
8840aeed3e9SJustin Hibbits }
8850aeed3e9SJustin Hibbits else
8860aeed3e9SJustin Hibbits {
8870aeed3e9SJustin Hibbits p_FreeB = p_FreeB->p_Next;
8880aeed3e9SJustin Hibbits while ( p_FreeB && ((p_FreeB->end - p_FreeB->base) < size) )
8890aeed3e9SJustin Hibbits p_FreeB = p_FreeB->p_Next;
8900aeed3e9SJustin Hibbits
8910aeed3e9SJustin Hibbits /* If such block is found */
8920aeed3e9SJustin Hibbits if ( !p_FreeB )
8930aeed3e9SJustin Hibbits {
8940aeed3e9SJustin Hibbits XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
8950aeed3e9SJustin Hibbits return (uint64_t)(ILLEGAL_BASE);
8960aeed3e9SJustin Hibbits }
8970aeed3e9SJustin Hibbits
8980aeed3e9SJustin Hibbits holdBase = p_FreeB->base;
8990aeed3e9SJustin Hibbits holdEnd = holdBase + size;
9000aeed3e9SJustin Hibbits }
9010aeed3e9SJustin Hibbits
9020aeed3e9SJustin Hibbits /* init a new busy block */
9030aeed3e9SJustin Hibbits if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
9040aeed3e9SJustin Hibbits {
9050aeed3e9SJustin Hibbits XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
9060aeed3e9SJustin Hibbits return (uint64_t)(ILLEGAL_BASE);
9070aeed3e9SJustin Hibbits }
9080aeed3e9SJustin Hibbits
9090aeed3e9SJustin Hibbits /* calls Update routine to update a lists of free blocks */
9100aeed3e9SJustin Hibbits if ( CutFree( p_MM, holdBase, holdEnd ) != E_OK )
9110aeed3e9SJustin Hibbits {
9120aeed3e9SJustin Hibbits XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
913*852ba100SJustin Hibbits XX_Free(p_NewBusyB);
9140aeed3e9SJustin Hibbits return (uint64_t)(ILLEGAL_BASE);
9150aeed3e9SJustin Hibbits }
9160aeed3e9SJustin Hibbits
917*852ba100SJustin Hibbits /* Decreasing the allocated memory size from free memory size */
918*852ba100SJustin Hibbits p_MM->freeMemSize -= size;
919*852ba100SJustin Hibbits
9200aeed3e9SJustin Hibbits /* insert the new busy block into the list of busy blocks */
9210aeed3e9SJustin Hibbits AddBusy( p_MM, p_NewBusyB );
9220aeed3e9SJustin Hibbits XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
9230aeed3e9SJustin Hibbits
9240aeed3e9SJustin Hibbits return (holdBase);
9250aeed3e9SJustin Hibbits }
9260aeed3e9SJustin Hibbits
9270aeed3e9SJustin Hibbits /*****************************************************************************/
MM_Put(t_Handle h_MM,uint64_t base)9280aeed3e9SJustin Hibbits uint64_t MM_Put(t_Handle h_MM, uint64_t base)
9290aeed3e9SJustin Hibbits {
9300aeed3e9SJustin Hibbits t_MM *p_MM = (t_MM *)h_MM;
9310aeed3e9SJustin Hibbits t_BusyBlock *p_BusyB, *p_PrevBusyB;
9320aeed3e9SJustin Hibbits uint64_t size;
9330aeed3e9SJustin Hibbits uint32_t intFlags;
9340aeed3e9SJustin Hibbits
9350aeed3e9SJustin Hibbits ASSERT_COND(p_MM);
9360aeed3e9SJustin Hibbits
9370aeed3e9SJustin Hibbits /* Look for a busy block that have the given base value.
9380aeed3e9SJustin Hibbits * That block will be returned back to the memory.
9390aeed3e9SJustin Hibbits */
9400aeed3e9SJustin Hibbits p_PrevBusyB = 0;
9410aeed3e9SJustin Hibbits
9420aeed3e9SJustin Hibbits intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
9430aeed3e9SJustin Hibbits p_BusyB = p_MM->busyBlocks;
9440aeed3e9SJustin Hibbits while ( p_BusyB && base != p_BusyB->base )
9450aeed3e9SJustin Hibbits {
9460aeed3e9SJustin Hibbits p_PrevBusyB = p_BusyB;
9470aeed3e9SJustin Hibbits p_BusyB = p_BusyB->p_Next;
9480aeed3e9SJustin Hibbits }
9490aeed3e9SJustin Hibbits
9500aeed3e9SJustin Hibbits if ( !p_BusyB )
9510aeed3e9SJustin Hibbits {
9520aeed3e9SJustin Hibbits XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
9530aeed3e9SJustin Hibbits return (uint64_t)(0);
9540aeed3e9SJustin Hibbits }
9550aeed3e9SJustin Hibbits
9560aeed3e9SJustin Hibbits if ( AddFree( p_MM, p_BusyB->base, p_BusyB->end ) != E_OK )
9570aeed3e9SJustin Hibbits {
9580aeed3e9SJustin Hibbits XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
9590aeed3e9SJustin Hibbits return (uint64_t)(0);
9600aeed3e9SJustin Hibbits }
9610aeed3e9SJustin Hibbits
9620aeed3e9SJustin Hibbits /* removes a busy block form the list of busy blocks */
9630aeed3e9SJustin Hibbits if ( p_PrevBusyB )
9640aeed3e9SJustin Hibbits p_PrevBusyB->p_Next = p_BusyB->p_Next;
9650aeed3e9SJustin Hibbits else
9660aeed3e9SJustin Hibbits p_MM->busyBlocks = p_BusyB->p_Next;
9670aeed3e9SJustin Hibbits
9680aeed3e9SJustin Hibbits size = p_BusyB->end - p_BusyB->base;
9690aeed3e9SJustin Hibbits
970*852ba100SJustin Hibbits /* Adding the deallocated memory size to free memory size */
971*852ba100SJustin Hibbits p_MM->freeMemSize += size;
972*852ba100SJustin Hibbits
9730aeed3e9SJustin Hibbits XX_Free(p_BusyB);
9740aeed3e9SJustin Hibbits XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
9750aeed3e9SJustin Hibbits
9760aeed3e9SJustin Hibbits return (size);
9770aeed3e9SJustin Hibbits }
9780aeed3e9SJustin Hibbits
9790aeed3e9SJustin Hibbits /*****************************************************************************/
MM_PutForce(t_Handle h_MM,uint64_t base,uint64_t size)9800aeed3e9SJustin Hibbits uint64_t MM_PutForce(t_Handle h_MM, uint64_t base, uint64_t size)
9810aeed3e9SJustin Hibbits {
9820aeed3e9SJustin Hibbits t_MM *p_MM = (t_MM *)h_MM;
9830aeed3e9SJustin Hibbits uint64_t end = base + size;
9840aeed3e9SJustin Hibbits uint32_t intFlags;
9850aeed3e9SJustin Hibbits
9860aeed3e9SJustin Hibbits ASSERT_COND(p_MM);
9870aeed3e9SJustin Hibbits
9880aeed3e9SJustin Hibbits intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
989*852ba100SJustin Hibbits
9900aeed3e9SJustin Hibbits if ( CutBusy( p_MM, base, end ) != E_OK )
9910aeed3e9SJustin Hibbits {
9920aeed3e9SJustin Hibbits XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
9930aeed3e9SJustin Hibbits return (uint64_t)(0);
9940aeed3e9SJustin Hibbits }
9950aeed3e9SJustin Hibbits
9960aeed3e9SJustin Hibbits if ( AddFree ( p_MM, base, end ) != E_OK )
9970aeed3e9SJustin Hibbits {
9980aeed3e9SJustin Hibbits XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
9990aeed3e9SJustin Hibbits return (uint64_t)(0);
10000aeed3e9SJustin Hibbits }
1001*852ba100SJustin Hibbits
1002*852ba100SJustin Hibbits /* Adding the deallocated memory size to free memory size */
1003*852ba100SJustin Hibbits p_MM->freeMemSize += size;
1004*852ba100SJustin Hibbits
10050aeed3e9SJustin Hibbits XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
10060aeed3e9SJustin Hibbits
10070aeed3e9SJustin Hibbits return (size);
10080aeed3e9SJustin Hibbits }
10090aeed3e9SJustin Hibbits
10100aeed3e9SJustin Hibbits /*****************************************************************************/
MM_Add(t_Handle h_MM,uint64_t base,uint64_t size)10110aeed3e9SJustin Hibbits t_Error MM_Add(t_Handle h_MM, uint64_t base, uint64_t size)
10120aeed3e9SJustin Hibbits {
10130aeed3e9SJustin Hibbits t_MM *p_MM = (t_MM *)h_MM;
10140aeed3e9SJustin Hibbits t_MemBlock *p_MemB, *p_NewMemB;
10150aeed3e9SJustin Hibbits t_Error errCode;
10160aeed3e9SJustin Hibbits uint32_t intFlags;
10170aeed3e9SJustin Hibbits
10180aeed3e9SJustin Hibbits ASSERT_COND(p_MM);
10190aeed3e9SJustin Hibbits
10200aeed3e9SJustin Hibbits /* find a last block in the list of memory blocks to insert a new
10210aeed3e9SJustin Hibbits * memory block
10220aeed3e9SJustin Hibbits */
10230aeed3e9SJustin Hibbits intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
1024*852ba100SJustin Hibbits
10250aeed3e9SJustin Hibbits p_MemB = p_MM->memBlocks;
10260aeed3e9SJustin Hibbits while ( p_MemB->p_Next )
10270aeed3e9SJustin Hibbits {
10280aeed3e9SJustin Hibbits if ( base >= p_MemB->base && base < p_MemB->end )
10290aeed3e9SJustin Hibbits {
10300aeed3e9SJustin Hibbits XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
10310aeed3e9SJustin Hibbits RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
10320aeed3e9SJustin Hibbits }
10330aeed3e9SJustin Hibbits p_MemB = p_MemB->p_Next;
10340aeed3e9SJustin Hibbits }
10350aeed3e9SJustin Hibbits /* check for a last memory block */
10360aeed3e9SJustin Hibbits if ( base >= p_MemB->base && base < p_MemB->end )
10370aeed3e9SJustin Hibbits {
10380aeed3e9SJustin Hibbits XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
10390aeed3e9SJustin Hibbits RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
10400aeed3e9SJustin Hibbits }
10410aeed3e9SJustin Hibbits
10420aeed3e9SJustin Hibbits /* create a new memory block */
10430aeed3e9SJustin Hibbits if ((p_NewMemB = CreateNewBlock(base, size)) == NULL)
10440aeed3e9SJustin Hibbits {
10450aeed3e9SJustin Hibbits XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
10460aeed3e9SJustin Hibbits RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
10470aeed3e9SJustin Hibbits }
10480aeed3e9SJustin Hibbits
10490aeed3e9SJustin Hibbits /* append a new memory block to the end of the list of memory blocks */
10500aeed3e9SJustin Hibbits p_MemB->p_Next = p_NewMemB;
10510aeed3e9SJustin Hibbits
10520aeed3e9SJustin Hibbits /* add a new free block to the free lists */
10530aeed3e9SJustin Hibbits errCode = AddFree(p_MM, base, base+size);
10540aeed3e9SJustin Hibbits if (errCode)
10550aeed3e9SJustin Hibbits {
10560aeed3e9SJustin Hibbits XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
10570aeed3e9SJustin Hibbits p_MemB->p_Next = 0;
10580aeed3e9SJustin Hibbits XX_Free(p_NewMemB);
10590aeed3e9SJustin Hibbits return ((t_Error)errCode);
10600aeed3e9SJustin Hibbits }
1061*852ba100SJustin Hibbits
1062*852ba100SJustin Hibbits /* Adding the new block size to free memory size */
1063*852ba100SJustin Hibbits p_MM->freeMemSize += size;
1064*852ba100SJustin Hibbits
10650aeed3e9SJustin Hibbits XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
10660aeed3e9SJustin Hibbits
10670aeed3e9SJustin Hibbits return (E_OK);
10680aeed3e9SJustin Hibbits }
10690aeed3e9SJustin Hibbits
10700aeed3e9SJustin Hibbits /*****************************************************************************/
MM_GetMemBlock(t_Handle h_MM,int index)10710aeed3e9SJustin Hibbits uint64_t MM_GetMemBlock(t_Handle h_MM, int index)
10720aeed3e9SJustin Hibbits {
10730aeed3e9SJustin Hibbits t_MM *p_MM = (t_MM*)h_MM;
10740aeed3e9SJustin Hibbits t_MemBlock *p_MemBlock;
10750aeed3e9SJustin Hibbits int i;
10760aeed3e9SJustin Hibbits
10770aeed3e9SJustin Hibbits ASSERT_COND(p_MM);
10780aeed3e9SJustin Hibbits
10790aeed3e9SJustin Hibbits p_MemBlock = p_MM->memBlocks;
10800aeed3e9SJustin Hibbits for (i=0; i < index; i++)
10810aeed3e9SJustin Hibbits p_MemBlock = p_MemBlock->p_Next;
10820aeed3e9SJustin Hibbits
10830aeed3e9SJustin Hibbits if ( p_MemBlock )
10840aeed3e9SJustin Hibbits return (p_MemBlock->base);
10850aeed3e9SJustin Hibbits else
10860aeed3e9SJustin Hibbits return (uint64_t)ILLEGAL_BASE;
10870aeed3e9SJustin Hibbits }
10880aeed3e9SJustin Hibbits
10890aeed3e9SJustin Hibbits /*****************************************************************************/
MM_GetBase(t_Handle h_MM)10900aeed3e9SJustin Hibbits uint64_t MM_GetBase(t_Handle h_MM)
10910aeed3e9SJustin Hibbits {
10920aeed3e9SJustin Hibbits t_MM *p_MM = (t_MM*)h_MM;
10930aeed3e9SJustin Hibbits t_MemBlock *p_MemBlock;
10940aeed3e9SJustin Hibbits
10950aeed3e9SJustin Hibbits ASSERT_COND(p_MM);
10960aeed3e9SJustin Hibbits
10970aeed3e9SJustin Hibbits p_MemBlock = p_MM->memBlocks;
10980aeed3e9SJustin Hibbits return p_MemBlock->base;
10990aeed3e9SJustin Hibbits }
11000aeed3e9SJustin Hibbits
11010aeed3e9SJustin Hibbits /*****************************************************************************/
MM_InRange(t_Handle h_MM,uint64_t addr)11020aeed3e9SJustin Hibbits bool MM_InRange(t_Handle h_MM, uint64_t addr)
11030aeed3e9SJustin Hibbits {
11040aeed3e9SJustin Hibbits t_MM *p_MM = (t_MM*)h_MM;
11050aeed3e9SJustin Hibbits t_MemBlock *p_MemBlock;
11060aeed3e9SJustin Hibbits
11070aeed3e9SJustin Hibbits ASSERT_COND(p_MM);
11080aeed3e9SJustin Hibbits
11090aeed3e9SJustin Hibbits p_MemBlock = p_MM->memBlocks;
11100aeed3e9SJustin Hibbits
11110aeed3e9SJustin Hibbits if ((addr >= p_MemBlock->base) && (addr < p_MemBlock->end))
11120aeed3e9SJustin Hibbits return TRUE;
11130aeed3e9SJustin Hibbits else
11140aeed3e9SJustin Hibbits return FALSE;
11150aeed3e9SJustin Hibbits }
11160aeed3e9SJustin Hibbits
11170aeed3e9SJustin Hibbits /*****************************************************************************/
MM_GetFreeMemSize(t_Handle h_MM)1118*852ba100SJustin Hibbits uint64_t MM_GetFreeMemSize(t_Handle h_MM)
1119*852ba100SJustin Hibbits {
1120*852ba100SJustin Hibbits t_MM *p_MM = (t_MM*)h_MM;
1121*852ba100SJustin Hibbits
1122*852ba100SJustin Hibbits ASSERT_COND(p_MM);
1123*852ba100SJustin Hibbits
1124*852ba100SJustin Hibbits return p_MM->freeMemSize;
1125*852ba100SJustin Hibbits }
1126*852ba100SJustin Hibbits
1127*852ba100SJustin Hibbits /*****************************************************************************/
MM_Dump(t_Handle h_MM)1128*852ba100SJustin Hibbits void MM_Dump(t_Handle h_MM)
11290aeed3e9SJustin Hibbits {
11300aeed3e9SJustin Hibbits t_MM *p_MM = (t_MM *)h_MM;
11310aeed3e9SJustin Hibbits t_FreeBlock *p_FreeB;
11320aeed3e9SJustin Hibbits t_BusyBlock *p_BusyB;
11330aeed3e9SJustin Hibbits int i;
11340aeed3e9SJustin Hibbits
11350aeed3e9SJustin Hibbits p_BusyB = p_MM->busyBlocks;
1136*852ba100SJustin Hibbits XX_Print("List of busy blocks:\n");
11370aeed3e9SJustin Hibbits while (p_BusyB)
11380aeed3e9SJustin Hibbits {
1139*852ba100SJustin Hibbits XX_Print("\t0x%p: (%s: b=0x%llx, e=0x%llx)\n", p_BusyB, p_BusyB->name, p_BusyB->base, p_BusyB->end );
11400aeed3e9SJustin Hibbits p_BusyB = p_BusyB->p_Next;
11410aeed3e9SJustin Hibbits }
11420aeed3e9SJustin Hibbits
1143*852ba100SJustin Hibbits XX_Print("\nLists of free blocks according to alignment:\n");
11440aeed3e9SJustin Hibbits for (i=0; i <= MM_MAX_ALIGNMENT; i++)
11450aeed3e9SJustin Hibbits {
1146*852ba100SJustin Hibbits XX_Print("%d alignment:\n", (0x1 << i));
11470aeed3e9SJustin Hibbits p_FreeB = p_MM->freeBlocks[i];
11480aeed3e9SJustin Hibbits while (p_FreeB)
11490aeed3e9SJustin Hibbits {
1150*852ba100SJustin Hibbits XX_Print("\t0x%p: (b=0x%llx, e=0x%llx)\n", p_FreeB, p_FreeB->base, p_FreeB->end);
11510aeed3e9SJustin Hibbits p_FreeB = p_FreeB->p_Next;
11520aeed3e9SJustin Hibbits }
1153*852ba100SJustin Hibbits XX_Print("\n");
11540aeed3e9SJustin Hibbits }
11550aeed3e9SJustin Hibbits }
1156