Lines Matching +full:block +full:- +full:size
2 * Copyright 2008-2012 Freescale Semiconductor Inc.
53 * Initializes a new busy block of "size" bytes and started
54 * rom "base" address. Each busy block has a name that
58 * base - base address of the busy block
59 * size - size of the busy block
60 * name - name that specified the busy block
66 static t_BusyBlock * CreateBusyBlock(uint64_t base, uint64_t size, char *name) in CreateBusyBlock() argument
78 p_BusyBlock->base = base; in CreateBusyBlock()
79 p_BusyBlock->end = base + size; in CreateBusyBlock()
83 n = MM_MAX_NAME_LEN - 1; in CreateBusyBlock()
84 strncpy(p_BusyBlock->name, name, MM_MAX_NAME_LEN-1); in CreateBusyBlock()
85 p_BusyBlock->name[n] = '\0'; in CreateBusyBlock()
86 p_BusyBlock->p_Next = 0; in CreateBusyBlock()
95 * Initializes a new memory block of "size" bytes and started
99 * base - base address of the memory block
100 * size - size of the memory block
106 static t_MemBlock * CreateNewBlock(uint64_t base, uint64_t size) in CreateNewBlock() argument
117 p_MemBlock->base = base; in CreateNewBlock()
118 p_MemBlock->end = base+size; in CreateNewBlock()
119 p_MemBlock->p_Next = 0; in CreateNewBlock()
128 * Initializes a new free block of of "size" bytes and
132 * base - base address of the free block
133 * size - size of the free block
139 static t_FreeBlock * CreateFreeBlock(uint64_t base, uint64_t size) in CreateFreeBlock() argument
150 p_FreeBlock->base = base; in CreateFreeBlock()
151 p_FreeBlock->end = base + size; in CreateFreeBlock()
152 p_FreeBlock->p_Next = 0; in CreateFreeBlock()
161 * Adds a new free block to the free lists. It updates each
162 * free list to include a new free block.
163 * Note, that all free block in each free list are ordered
167 * p_MM - pointer to the MM object
168 * base - base address of a given free block
169 * end - end address of a given free block
182 /* Updates free lists to include a just released block */ in AddFree()
186 p_CurrB = p_MM->freeBlocks[i]; in AddFree()
191 /* Goes to the next free list if there is no block to free */ in AddFree()
195 /* Looks for a free block that should be updated */ in AddFree()
198 if ( alignBase <= p_CurrB->end ) in AddFree()
200 if ( end > p_CurrB->end ) in AddFree()
203 while ( p_CurrB->p_Next && end > p_CurrB->p_Next->end ) in AddFree()
205 p_NextB = p_CurrB->p_Next; in AddFree()
206 p_CurrB->p_Next = p_CurrB->p_Next->p_Next; in AddFree()
210 p_NextB = p_CurrB->p_Next; in AddFree()
211 if ( !p_NextB || (p_NextB && end < p_NextB->base) ) in AddFree()
213 p_CurrB->end = end; in AddFree()
217 p_CurrB->end = p_NextB->end; in AddFree()
218 p_CurrB->p_Next = p_NextB->p_Next; in AddFree()
222 else if ( (end < p_CurrB->base) && ((end-alignBase) >= alignment) ) in AddFree()
224 if ((p_NewB = CreateFreeBlock(alignBase, end-alignBase)) == NULL) in AddFree()
227 p_NewB->p_Next = p_CurrB; in AddFree()
229 p_PrevB->p_Next = p_NewB; in AddFree()
231 p_MM->freeBlocks[i] = p_NewB; in AddFree()
235 if ((alignBase < p_CurrB->base) && (end >= p_CurrB->base)) in AddFree()
237 p_CurrB->base = alignBase; in AddFree()
240 /* if size of the free block is less then alignment in AddFree()
241 * deletes that free block from the free list. */ in AddFree()
242 if ( (p_CurrB->end - p_CurrB->base) < alignment) in AddFree()
245 p_PrevB->p_Next = p_CurrB->p_Next; in AddFree()
247 p_MM->freeBlocks[i] = p_CurrB->p_Next; in AddFree()
256 p_CurrB = p_CurrB->p_Next; in AddFree()
260 /* If no free block found to be updated, insert a new free block in AddFree()
263 if ( !p_CurrB && ((((uint64_t)(end-base)) & ((uint64_t)(alignment-1))) == 0) ) in AddFree()
265 if ((p_NewB = CreateFreeBlock(alignBase, end-base)) == NULL) in AddFree()
269 p_PrevB->p_Next = p_NewB; in AddFree()
271 p_MM->freeBlocks[i] = p_NewB; in AddFree()
274 /* Update boundaries of the new free block */ in AddFree()
277 if ( p_CurrB && base > p_CurrB->base ) in AddFree()
278 base = p_CurrB->base; in AddFree()
279 if ( p_CurrB && end < p_CurrB->end ) in AddFree()
280 end = p_CurrB->end; in AddFree()
291 * Cuts a free block from holdBase to holdEnd from the free lists.
293 * not include a block of memory from holdBase to holdEnd.
294 * For each free lists it seek for a free block that holds
295 * either holdBase or holdEnd. If such block is found it updates it.
298 * p_MM - pointer to the MM object
299 * holdBase - base address of the allocated block
300 * holdEnd - end address of the allocated block
317 p_CurrB = p_MM->freeBlocks[i]; in CutFree()
324 base = p_CurrB->base; in CutFree()
325 end = p_CurrB->end; in CutFree()
330 (alignBase < end && ((end-alignBase) < alignment)) ) in CutFree()
333 p_PrevB->p_Next = p_CurrB->p_Next; in CutFree()
335 p_MM->freeBlocks[i] = p_CurrB->p_Next; in CutFree()
340 p_CurrB->base = alignBase; in CutFree()
346 if ( (holdBase-base) >= alignment ) in CutFree()
348 if ( (alignBase < end) && ((end-alignBase) >= alignment) ) in CutFree()
350 if ((p_NewB = CreateFreeBlock(alignBase, end-alignBase)) == NULL) in CutFree()
352 p_NewB->p_Next = p_CurrB->p_Next; in CutFree()
353 p_CurrB->p_Next = p_NewB; in CutFree()
355 p_CurrB->end = holdBase; in CutFree()
357 else if ( (alignBase < end) && ((end-alignBase) >= alignment) ) in CutFree()
359 p_CurrB->base = alignBase; in CutFree()
364 p_PrevB->p_Next = p_CurrB->p_Next; in CutFree()
366 p_MM->freeBlocks[i] = p_CurrB->p_Next; in CutFree()
374 p_CurrB = p_CurrB->p_Next; in CutFree()
386 * Adds a new busy block to the list of busy blocks. Note,
391 * MM - handler to the MM object
392 * p_NewBusyB - pointer to the a busy block
402 /* finds a place of a new busy block in the list of busy blocks */ in AddBusy()
404 p_CurrBusyB = p_MM->busyBlocks; in AddBusy()
406 while ( p_CurrBusyB && p_NewBusyB->base > p_CurrBusyB->base ) in AddBusy()
409 p_CurrBusyB = p_CurrBusyB->p_Next; in AddBusy()
412 /* insert the new busy block into the list of busy blocks */ in AddBusy()
414 p_NewBusyB->p_Next = p_CurrBusyB; in AddBusy()
416 p_PrevBusyB->p_Next = p_NewBusyB; in AddBusy()
418 p_MM->busyBlocks = p_NewBusyB; in AddBusy()
425 * Cuts a block from base to end from the list of busy blocks.
427 * include a given block, that block is going to be free. If a
428 * given block is a part of some other busy block, so that
429 * busy block is updated. If there are number of busy blocks
430 * included in the given block, so all that blocks are removed
432 * If the given block devides some block into two parts, a new
433 * busy block is added to the busy list.
436 * p_MM - pointer to the MM object
437 * base - base address of a given busy block
438 * end - end address of a given busy block
448 p_CurrB = p_MM->busyBlocks; in CutBusy()
453 if ( base < p_CurrB->end ) in CutBusy()
455 if ( end > p_CurrB->end ) in CutBusy()
458 while ( p_CurrB->p_Next && end >= p_CurrB->p_Next->end ) in CutBusy()
460 p_NextB = p_CurrB->p_Next; in CutBusy()
461 p_CurrB->p_Next = p_CurrB->p_Next->p_Next; in CutBusy()
465 p_NextB = p_CurrB->p_Next; in CutBusy()
466 if ( p_NextB && end > p_NextB->base ) in CutBusy()
468 p_NextB->base = end; in CutBusy()
472 if ( base <= p_CurrB->base ) in CutBusy()
474 if ( end < p_CurrB->end && end > p_CurrB->base ) in CutBusy()
476 p_CurrB->base = end; in CutBusy()
478 else if ( end >= p_CurrB->end ) in CutBusy()
481 p_PrevB->p_Next = p_CurrB->p_Next; in CutBusy()
483 p_MM->busyBlocks = p_CurrB->p_Next; in CutBusy()
489 if ( end < p_CurrB->end && end > p_CurrB->base ) in CutBusy()
492 p_CurrB->end-end, in CutBusy()
493 p_CurrB->name)) == NULL) in CutBusy()
495 p_NewB->p_Next = p_CurrB->p_Next; in CutBusy()
496 p_CurrB->p_Next = p_NewB; in CutBusy()
498 p_CurrB->end = base; in CutBusy()
505 p_CurrB = p_CurrB->p_Next; in CutBusy()
516 * Allocates a block of memory according to the given size
520 * and checks if it has the required size of bytes of the required
522 * After the block is found and data is allocated, it calls
524 * do not include a just allocated block. Of course, each
526 * It is also creates a busy block that holds
527 * information about an allocated block.
530 * MM - handle to the MM object
531 * size - size of the MM
532 * alignment - index as a power of two defines
534 * name - the name that specifies an allocated block.
537 * base address of an allocated block.
538 * ILLEGAL_BASE if can't allocate a block
541 static uint64_t MmGetGreaterAlignment(t_MM *p_MM, uint64_t size, uint64_t alignment, char* name) in MmGetGreaterAlignment() argument
548 and look for a block of the suitable size and in MmGetGreaterAlignment()
550 p_FreeB = p_MM->freeBlocks[MM_MAX_ALIGNMENT]; in MmGetGreaterAlignment()
554 alignBase = MAKE_ALIGNED(p_FreeB->base, alignment); in MmGetGreaterAlignment()
556 /* the block is found if the aligned base inside the block in MmGetGreaterAlignment()
557 * and has the anough size. */ in MmGetGreaterAlignment()
558 if ( alignBase >= p_FreeB->base && in MmGetGreaterAlignment()
559 alignBase < p_FreeB->end && in MmGetGreaterAlignment()
560 size <= (p_FreeB->end - alignBase) ) in MmGetGreaterAlignment()
563 p_FreeB = p_FreeB->p_Next; in MmGetGreaterAlignment()
566 /* If such block isn't found */ in MmGetGreaterAlignment()
571 holdEnd = alignBase + size; in MmGetGreaterAlignment()
573 /* init a new busy block */ in MmGetGreaterAlignment()
574 if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL) in MmGetGreaterAlignment()
584 /* insert the new busy block into the list of busy blocks */ in MmGetGreaterAlignment()
596 t_Error MM_Init(t_Handle *h_MM, uint64_t base, uint64_t size) in MM_Init() argument
602 if (!size) in MM_Init()
604 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size (should be positive)")); in MM_Init()
614 p_MM->h_Spinlock = XX_InitSpinlock(); in MM_Init()
615 if (!p_MM->h_Spinlock) in MM_Init()
621 /* Initializes counter of free memory to total size */ in MM_Init()
622 p_MM->freeMemSize = size; in MM_Init()
625 p_MM->busyBlocks = 0; in MM_Init()
627 /* Initializes a new memory block */ in MM_Init()
628 if ((p_MM->memBlocks = CreateNewBlock(base, size)) == NULL) in MM_Init()
634 /* Initializes a new free block for each free list*/ in MM_Init()
638 newSize = size - (newBase - base); in MM_Init()
640 if ((p_MM->freeBlocks[i] = CreateFreeBlock(newBase, newSize)) == NULL) in MM_Init()
665 p_BusyBlock = p_MM->busyBlocks; in MM_Free()
669 p_BusyBlock = p_BusyBlock->p_Next; in MM_Free()
676 p_FreeBlock = p_MM->freeBlocks[i]; in MM_Free()
680 p_FreeBlock = p_FreeBlock->p_Next; in MM_Free()
686 p_MemBlock = p_MM->memBlocks; in MM_Free()
690 p_MemBlock = p_MemBlock->p_Next; in MM_Free()
694 if (p_MM->h_Spinlock) in MM_Free()
695 XX_FreeSpinlock(p_MM->h_Spinlock); in MM_Free()
702 uint64_t MM_Get(t_Handle h_MM, uint64_t size, uint64_t alignment, char* name) in MM_Get() argument
721 required size is multiple of the given alignment. */ in MM_Get()
737 return (MmGetGreaterAlignment(p_MM, size, alignment, name)); in MM_Get()
740 intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock); in MM_Get()
741 /* look for a block of the size greater or equal to the required size. */ in MM_Get()
742 p_FreeB = p_MM->freeBlocks[i]; in MM_Get()
743 while ( p_FreeB && (p_FreeB->end - p_FreeB->base) < size ) in MM_Get()
744 p_FreeB = p_FreeB->p_Next; in MM_Get()
746 /* If such block is found */ in MM_Get()
749 XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); in MM_Get()
753 holdBase = p_FreeB->base; in MM_Get()
754 holdEnd = holdBase + size; in MM_Get()
756 /* init a new busy block */ in MM_Get()
757 if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL) in MM_Get()
759 XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); in MM_Get()
766 XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); in MM_Get()
771 /* Decreasing the allocated memory size from free memory size */ in MM_Get()
772 p_MM->freeMemSize -= size; in MM_Get()
774 /* insert the new busy block into the list of busy blocks */ in MM_Get()
776 XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); in MM_Get()
782 uint64_t MM_GetForce(t_Handle h_MM, uint64_t base, uint64_t size, char* name) in MM_GetForce() argument
792 intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock); in MM_GetForce()
793 p_FreeB = p_MM->freeBlocks[0]; /* The biggest free blocks are in the in MM_GetForce()
798 if ( base >= p_FreeB->base && (base+size) <= p_FreeB->end ) in MM_GetForce()
804 p_FreeB = p_FreeB->p_Next; in MM_GetForce()
809 XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); in MM_GetForce()
813 /* init a new busy block */ in MM_GetForce()
814 if ((p_NewBusyB = CreateBusyBlock(base, size, name)) == NULL) in MM_GetForce()
816 XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); in MM_GetForce()
821 if ( CutFree ( p_MM, base, base+size ) != E_OK ) in MM_GetForce()
823 XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); in MM_GetForce()
828 /* Decreasing the allocated memory size from free memory size */ in MM_GetForce()
829 p_MM->freeMemSize -= size; in MM_GetForce()
831 /* insert the new busy block into the list of busy blocks */ in MM_GetForce()
833 XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); in MM_GetForce()
839 uint64_t MM_GetForceMin(t_Handle h_MM, uint64_t size, uint64_t alignment, uint64_t min, char* name) in MM_GetForceMin() argument
850 required size is multiple of the given alignment. */ in MM_GetForceMin()
862 intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock); in MM_GetForceMin()
863 p_FreeB = p_MM->freeBlocks[i]; in MM_GetForceMin()
865 /* look for the first block that contains the minimum in MM_GetForceMin()
866 base address. If the whole required size may be fit in MM_GetForceMin()
867 into it, use that block, otherwise look for the next in MM_GetForceMin()
868 block of size greater or equal to the required size. */ in MM_GetForceMin()
869 while ( p_FreeB && (min >= p_FreeB->end)) in MM_GetForceMin()
870 p_FreeB = p_FreeB->p_Next; in MM_GetForceMin()
872 /* If such block is found */ in MM_GetForceMin()
875 XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); in MM_GetForceMin()
879 /* if this block is large enough, use this block */ in MM_GetForceMin()
880 holdBase = ( min <= p_FreeB->base ) ? p_FreeB->base : min; in MM_GetForceMin()
881 if ((holdBase + size) <= p_FreeB->end ) in MM_GetForceMin()
883 holdEnd = holdBase + size; in MM_GetForceMin()
887 p_FreeB = p_FreeB->p_Next; in MM_GetForceMin()
888 while ( p_FreeB && ((p_FreeB->end - p_FreeB->base) < size) ) in MM_GetForceMin()
889 p_FreeB = p_FreeB->p_Next; in MM_GetForceMin()
891 /* If such block is found */ in MM_GetForceMin()
894 XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); in MM_GetForceMin()
898 holdBase = p_FreeB->base; in MM_GetForceMin()
899 holdEnd = holdBase + size; in MM_GetForceMin()
902 /* init a new busy block */ in MM_GetForceMin()
903 if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL) in MM_GetForceMin()
905 XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); in MM_GetForceMin()
912 XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); in MM_GetForceMin()
917 /* Decreasing the allocated memory size from free memory size */ in MM_GetForceMin()
918 p_MM->freeMemSize -= size; in MM_GetForceMin()
920 /* insert the new busy block into the list of busy blocks */ in MM_GetForceMin()
922 XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); in MM_GetForceMin()
932 uint64_t size; in MM_Put() local
937 /* Look for a busy block that have the given base value. in MM_Put()
938 * That block will be returned back to the memory. in MM_Put()
942 intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock); in MM_Put()
943 p_BusyB = p_MM->busyBlocks; in MM_Put()
944 while ( p_BusyB && base != p_BusyB->base ) in MM_Put()
947 p_BusyB = p_BusyB->p_Next; in MM_Put()
952 XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); in MM_Put()
956 if ( AddFree( p_MM, p_BusyB->base, p_BusyB->end ) != E_OK ) in MM_Put()
958 XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); in MM_Put()
962 /* removes a busy block form the list of busy blocks */ in MM_Put()
964 p_PrevBusyB->p_Next = p_BusyB->p_Next; in MM_Put()
966 p_MM->busyBlocks = p_BusyB->p_Next; in MM_Put()
968 size = p_BusyB->end - p_BusyB->base; in MM_Put()
970 /* Adding the deallocated memory size to free memory size */ in MM_Put()
971 p_MM->freeMemSize += size; in MM_Put()
974 XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); in MM_Put()
976 return (size); in MM_Put()
980 uint64_t MM_PutForce(t_Handle h_MM, uint64_t base, uint64_t size) in MM_PutForce() argument
983 uint64_t end = base + size; in MM_PutForce()
988 intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock); in MM_PutForce()
992 XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); in MM_PutForce()
998 XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); in MM_PutForce()
1002 /* Adding the deallocated memory size to free memory size */ in MM_PutForce()
1003 p_MM->freeMemSize += size; in MM_PutForce()
1005 XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); in MM_PutForce()
1007 return (size); in MM_PutForce()
1011 t_Error MM_Add(t_Handle h_MM, uint64_t base, uint64_t size) in MM_Add() argument
1020 /* find a last block in the list of memory blocks to insert a new in MM_Add()
1021 * memory block in MM_Add()
1023 intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock); in MM_Add()
1025 p_MemB = p_MM->memBlocks; in MM_Add()
1026 while ( p_MemB->p_Next ) in MM_Add()
1028 if ( base >= p_MemB->base && base < p_MemB->end ) in MM_Add()
1030 XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); in MM_Add()
1033 p_MemB = p_MemB->p_Next; in MM_Add()
1035 /* check for a last memory block */ in MM_Add()
1036 if ( base >= p_MemB->base && base < p_MemB->end ) in MM_Add()
1038 XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); in MM_Add()
1042 /* create a new memory block */ in MM_Add()
1043 if ((p_NewMemB = CreateNewBlock(base, size)) == NULL) in MM_Add()
1045 XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); in MM_Add()
1049 /* append a new memory block to the end of the list of memory blocks */ in MM_Add()
1050 p_MemB->p_Next = p_NewMemB; in MM_Add()
1052 /* add a new free block to the free lists */ in MM_Add()
1053 errCode = AddFree(p_MM, base, base+size); in MM_Add()
1056 XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); in MM_Add()
1057 p_MemB->p_Next = 0; in MM_Add()
1062 /* Adding the new block size to free memory size */ in MM_Add()
1063 p_MM->freeMemSize += size; in MM_Add()
1065 XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags); in MM_Add()
1079 p_MemBlock = p_MM->memBlocks; in MM_GetMemBlock()
1081 p_MemBlock = p_MemBlock->p_Next; in MM_GetMemBlock()
1084 return (p_MemBlock->base); in MM_GetMemBlock()
1097 p_MemBlock = p_MM->memBlocks; in MM_GetBase()
1098 return p_MemBlock->base; in MM_GetBase()
1109 p_MemBlock = p_MM->memBlocks; in MM_InRange()
1111 if ((addr >= p_MemBlock->base) && (addr < p_MemBlock->end)) in MM_InRange()
1124 return p_MM->freeMemSize; in MM_GetFreeMemSize()
1135 p_BusyB = p_MM->busyBlocks; in MM_Dump()
1139 …_Print("\t0x%p: (%s: b=0x%llx, e=0x%llx)\n", p_BusyB, p_BusyB->name, p_BusyB->base, p_BusyB->end ); in MM_Dump()
1140 p_BusyB = p_BusyB->p_Next; in MM_Dump()
1147 p_FreeB = p_MM->freeBlocks[i]; in MM_Dump()
1150 XX_Print("\t0x%p: (b=0x%llx, e=0x%llx)\n", p_FreeB, p_FreeB->base, p_FreeB->end); in MM_Dump()
1151 p_FreeB = p_FreeB->p_Next; in MM_Dump()