mirror of
https://github.com/rvtr/ctr_eFuse.git
synced 2025-11-02 00:11:04 -04:00
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_eFuse@1 ff987cc8-cf2f-4642-8568-d52cce064691
478 lines
10 KiB
C
478 lines
10 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
|
|
typedef int BOOL;
|
|
typedef signed char s8;
|
|
typedef unsigned char u8;
|
|
typedef unsigned short u16;
|
|
typedef unsigned long u32;
|
|
typedef unsigned long long u64;
|
|
|
|
#include "cr_alloc.h"
|
|
|
|
#define OFFSET(n, a) (((u32) (n)) & ((a) - 1))
|
|
#define TRUNC(n, a) (((u32) (n)) & ~((a) - 1))
|
|
#define ROUND(n, a) (((u32) (n) + (a) - 1) & ~((a) - 1))
|
|
|
|
#define ALIGNMENT 32 // alignment in bytes
|
|
#define MINOBJSIZE (HEADERSIZE + ALIGNMENT) // smallest object
|
|
#define HEADERSIZE ROUND(sizeof(Cell), ALIGNMENT)
|
|
|
|
//---- InRange(): True if a <= targ < b
|
|
#define InRange(targ, a, b) \
|
|
((u32)(a) <= (u32)(targ) && (u32)(targ) < (u32)(b))
|
|
|
|
//---- RangeOverlap(): True if the ranges a and b overlap in any way.
|
|
#define RangeOverlap(aStart, aEnd, bStart, bEnd) \
|
|
(((u32)(bStart) <= (u32)(aStart)) && ((u32)(aStart) < (u32)(bEnd)) || \
|
|
((u32)(bStart) < (u32)(aEnd)) && ((u32)(aEnd) <= (u32)(bEnd)) )
|
|
|
|
//---- RangeSubset(): True if range a is a subset of range b
|
|
// Assume (aStart < aEnd) and (bStart < bEnd)
|
|
#define RangeSubset(aStart, aEnd, bStart, bEnd) \
|
|
((u32)(bStart) <= (u32)(aStart) && (u32)(aEnd) <= (u32)(bEnd))
|
|
|
|
typedef struct Cell Cell;
|
|
typedef struct HeapDesc HeapDesc;
|
|
|
|
struct Cell {
|
|
struct Cell *prev;
|
|
struct Cell *next;
|
|
long size; // size of object plus HEADERSIZE
|
|
};
|
|
|
|
struct HeapDesc {
|
|
long size; // if -1 then heap is free. Note OS_AllocFixed()
|
|
// could make a heap empty.
|
|
Cell *free; // pointer to the first free cell
|
|
Cell *allocated; // pointer to the first used cell
|
|
};
|
|
|
|
|
|
typedef struct {
|
|
// volatile because some functions use this as hidden macro parameter
|
|
void *arenaStart;
|
|
void *arenaEnd;
|
|
HeapDesc *heapArray;
|
|
} OSHeapInfo;
|
|
|
|
/*
|
|
-- heapInfo - arenaStart
|
|
(OSHeapInfo)
|
|
-- heapArray --
|
|
(HeapDesc)
|
|
-- arenaStart --
|
|
*/
|
|
|
|
|
|
|
|
static OSHeapInfo *_sys_heapInfo;
|
|
|
|
|
|
static Cell *DLAddFront(Cell * list, Cell * cell)
|
|
{
|
|
cell->next = list;
|
|
cell->prev = NULL;
|
|
if (list)
|
|
{
|
|
list->prev = cell;
|
|
}
|
|
return cell;
|
|
}
|
|
|
|
static Cell *DLExtract(Cell * list, Cell * cell)
|
|
{
|
|
if (cell->next)
|
|
{
|
|
cell->next->prev = cell->prev;
|
|
}
|
|
|
|
if (cell->prev == NULL)
|
|
{
|
|
return cell->next;
|
|
}
|
|
else
|
|
{
|
|
cell->prev->next = cell->next;
|
|
return list;
|
|
}
|
|
}
|
|
|
|
static Cell *DLInsert(Cell * list, Cell * cell)
|
|
{
|
|
Cell *prev;
|
|
Cell *next;
|
|
|
|
for (next = list, prev = NULL; next; prev = next, next = next->next)
|
|
{
|
|
if (cell <= next)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
cell->next = next;
|
|
cell->prev = prev;
|
|
if (next)
|
|
{
|
|
next->prev = cell;
|
|
if ((char *)cell + cell->size == (char *)next)
|
|
{
|
|
//---- Coalesce forward
|
|
cell->size += next->size;
|
|
cell->next = next = next->next;
|
|
if (next)
|
|
{
|
|
next->prev = cell;
|
|
}
|
|
}
|
|
}
|
|
if (prev)
|
|
{
|
|
prev->next = cell;
|
|
if ((char *)prev + prev->size == (char *)cell)
|
|
{
|
|
//---- Coalesce back
|
|
prev->size += cell->size;
|
|
prev->next = next;
|
|
if (next)
|
|
{
|
|
next->prev = prev;
|
|
}
|
|
}
|
|
return list;
|
|
}
|
|
else
|
|
{
|
|
return cell; // cell becomes new head of list
|
|
}
|
|
}
|
|
|
|
|
|
static void *cr_alloc_Alloc( u32 size)
|
|
{
|
|
OSHeapInfo *heapInfo;
|
|
HeapDesc *hd;
|
|
Cell *cell; // candidate block
|
|
Cell *newCell; // ptr to leftover block
|
|
long leftoverSize; // size of any leftover
|
|
|
|
heapInfo = _sys_heapInfo;
|
|
|
|
hd = heapInfo->heapArray;
|
|
|
|
// printf("heapArray 2 0x%p\n", hd);
|
|
|
|
// Enlarge size to smallest possible cell size
|
|
size += HEADERSIZE;
|
|
size = ROUND(size, ALIGNMENT);
|
|
|
|
// Search for block large enough
|
|
for (cell = hd->free; cell != NULL; cell = cell->next)
|
|
{
|
|
if ((long)size <= cell->size)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (cell == NULL)
|
|
{
|
|
// miya printf("%s %d\n",__FUNCTION__,__LINE__);
|
|
return NULL;
|
|
}
|
|
|
|
leftoverSize = cell->size - (long)size;
|
|
if (leftoverSize < MINOBJSIZE)
|
|
{
|
|
//---- Just extract this cell out since it's too small to split
|
|
hd->free = DLExtract(hd->free, cell);
|
|
}
|
|
else
|
|
{
|
|
//---- cell is large enough to split into two pieces
|
|
cell->size = (long)size;
|
|
|
|
//---- Create a new cell
|
|
newCell = (Cell *) ((char *)cell + size);
|
|
newCell->size = leftoverSize;
|
|
|
|
//---- Leave newCell in free, and take cell away
|
|
newCell->prev = cell->prev;
|
|
newCell->next = cell->next;
|
|
|
|
if (newCell->next != NULL)
|
|
{
|
|
newCell->next->prev = newCell;
|
|
}
|
|
|
|
if (newCell->prev != NULL)
|
|
{
|
|
newCell->prev->next = newCell;
|
|
}
|
|
else
|
|
{
|
|
// SDK_TASSERTMSG(hd->free == cell, OS_ERR_ALLOCFROMHEAP_BROKENHEAP);
|
|
hd->free = newCell;
|
|
}
|
|
}
|
|
|
|
//---- Add to allocated list
|
|
hd->allocated = DLAddFront(hd->allocated, cell);
|
|
|
|
return (void *)((char *)cell + HEADERSIZE);
|
|
}
|
|
|
|
|
|
static void cr_alloc_Free( void *ptr)
|
|
{
|
|
OSHeapInfo *heapInfo;
|
|
HeapDesc *hd;
|
|
Cell *cell;
|
|
|
|
heapInfo = _sys_heapInfo;
|
|
|
|
cell = (Cell *) ((char *)ptr - HEADERSIZE);
|
|
hd = heapInfo->heapArray;
|
|
|
|
hd->allocated = DLExtract(hd->allocated, cell);
|
|
|
|
hd->free = DLInsert(hd->free, cell);
|
|
}
|
|
|
|
|
|
u32 OSi_GetTotalAllocSize(BOOL isHeadInclude)
|
|
{
|
|
OSHeapInfo *heapInfo;
|
|
Cell *cell;
|
|
u32 sum = 0;
|
|
|
|
heapInfo = _sys_heapInfo;
|
|
|
|
if (isHeadInclude)
|
|
{
|
|
for (cell = heapInfo->heapArray->allocated; cell; cell = cell->next)
|
|
{
|
|
sum += (u32)(cell->size);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (cell = heapInfo->heapArray->allocated; cell; cell = cell->next)
|
|
{
|
|
sum += (u32)(cell->size - HEADERSIZE);
|
|
}
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
u32 cr_alloc_GetTotalFreeSize(void)
|
|
{
|
|
OSHeapInfo *heapInfo;
|
|
Cell *cell;
|
|
u32 sum = 0;
|
|
|
|
heapInfo = _sys_heapInfo;
|
|
|
|
for (cell = heapInfo->heapArray->free; cell; cell = cell->next)
|
|
{
|
|
sum += (u32)(cell->size - HEADERSIZE);
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
u32 cr_alloc_GetMaxFreeSize(void)
|
|
{
|
|
OSHeapInfo *heapInfo;
|
|
Cell *cell;
|
|
u32 candidate = 0;
|
|
|
|
heapInfo = _sys_heapInfo;
|
|
|
|
for (cell = heapInfo->heapArray->free; cell; cell = cell->next)
|
|
{
|
|
u32 size = (u32)(cell->size - HEADERSIZE);
|
|
if (size > candidate)
|
|
{
|
|
candidate = size;
|
|
}
|
|
}
|
|
return candidate;
|
|
}
|
|
|
|
|
|
static void *cr_alloc_InitAlloc(void *arenaStart, void *arenaEnd)
|
|
{
|
|
OSHeapInfo *heapInfo;
|
|
HeapDesc *hd;
|
|
Cell *cell;
|
|
|
|
|
|
heapInfo = arenaStart;
|
|
_sys_heapInfo = heapInfo;
|
|
|
|
|
|
heapInfo->heapArray = (void *)((u32)arenaStart + sizeof(OSHeapInfo));
|
|
|
|
/*
|
|
-- heapInfo - arenaStart
|
|
(OSHeapInfo)
|
|
-- heapArray --
|
|
(HeapDesc)
|
|
-- arenaStart --
|
|
*/
|
|
|
|
hd = heapInfo->heapArray;
|
|
|
|
hd->size = -1;
|
|
hd->free = hd->allocated = NULL;
|
|
|
|
//---- Set OSi_CurrentHeap to an invalid value
|
|
|
|
//---- Reset arenaStart to the nearest reasonable location
|
|
arenaStart = (void *)((char *)heapInfo->heapArray + sizeof(HeapDesc) );
|
|
arenaStart = (void *)ROUND(arenaStart, ALIGNMENT);
|
|
|
|
heapInfo->arenaStart = arenaStart;
|
|
heapInfo->arenaEnd = (void *)TRUNC(arenaEnd, ALIGNMENT);
|
|
|
|
|
|
hd = heapInfo->heapArray;
|
|
|
|
if (hd->size < 0) {
|
|
// hd->size = (char *)end - (char *)start;
|
|
hd->size = (char *)(heapInfo->arenaEnd)- (char *)(heapInfo->arenaStart);
|
|
|
|
// cell = (Cell *) start;
|
|
cell = (Cell *)(heapInfo->arenaStart);
|
|
cell->prev = NULL;
|
|
cell->next = NULL;
|
|
cell->size = hd->size;
|
|
hd->free = cell;
|
|
hd->allocated = 0;
|
|
}
|
|
return heapInfo->arenaStart;
|
|
}
|
|
|
|
|
|
/* */
|
|
|
|
static int alloc_counter = 0;
|
|
static int alloc_counter2 = 0;
|
|
|
|
//#define TSIZE_KERNEL_BUFFER 0x30000
|
|
#define TSIZE_KERNEL_BUFFER 0x20000
|
|
|
|
static u32 __kernel_bufmgr_buffer[TSIZE_KERNEL_BUFFER/sizeof(u32)];
|
|
|
|
|
|
int cr_mem_get_counter(void)
|
|
{
|
|
return alloc_counter;
|
|
}
|
|
|
|
int cr_mem_get_counter2(void)
|
|
{
|
|
return alloc_counter2;
|
|
}
|
|
|
|
|
|
void cr_mem_bufmgr_initialize(void)
|
|
{
|
|
//miya printf("%s %d\n",__FUNCTION__,__LINE__);
|
|
memset(__kernel_bufmgr_buffer, 0, TSIZE_KERNEL_BUFFER);
|
|
(void)cr_alloc_InitAlloc((void *)__kernel_bufmgr_buffer,
|
|
(void *)&(__kernel_bufmgr_buffer[TSIZE_KERNEL_BUFFER/sizeof(u32)]));
|
|
alloc_counter = 0;
|
|
alloc_counter2 = 0;
|
|
}
|
|
|
|
|
|
|
|
void *cr_mem_malloc(size_t size)
|
|
{
|
|
void *p_blk;
|
|
|
|
alloc_counter++;
|
|
|
|
p_blk = cr_alloc_Alloc( size );
|
|
|
|
if( NULL == p_blk ) {
|
|
//miya fprintf(stderr, "Error:%s %d\n",__FUNCTION__,__LINE__);
|
|
return NULL;
|
|
}
|
|
memset( p_blk, 0 , size);
|
|
return p_blk;
|
|
}
|
|
|
|
void cr_mem_free(void *ptr)
|
|
{
|
|
cr_alloc_Free( ptr );
|
|
alloc_counter--;
|
|
}
|
|
|
|
void *cr_mem_calloc(size_t nmemb, size_t size)
|
|
{
|
|
void *p_blk;
|
|
|
|
alloc_counter++;
|
|
|
|
p_blk = cr_alloc_Alloc( size * nmemb );
|
|
|
|
if( NULL == p_blk ) {
|
|
//miya fprintf(stderr, "Error:%s %d\n",__FUNCTION__,__LINE__);
|
|
return NULL;
|
|
}
|
|
|
|
return p_blk;
|
|
}
|
|
|
|
|
|
|
|
void *cr_mem_realloc(void *ptr, size_t size)
|
|
{
|
|
void *p_blk;
|
|
|
|
// OSHeapInfo *heapInfo;
|
|
// HeapDesc *hd;
|
|
// heapInfo = _sys_heapInfo;
|
|
// hd = heapInfo->heapArray;
|
|
|
|
// KMEMB *hdr;
|
|
Cell *cell;
|
|
|
|
p_blk = cr_alloc_Alloc( size );
|
|
|
|
if( NULL == p_blk ) {
|
|
//miya fprintf(stderr, "Error:call realloc error %d\n",alloc_counter);
|
|
return NULL;
|
|
}
|
|
|
|
// hdr = (KMEMB *)ptr - 1;
|
|
cell = (Cell *) ((char *)ptr - HEADERSIZE);
|
|
|
|
#if 0
|
|
if( hdr->size > size ) {
|
|
memcpy(p_blk, ptr, size);
|
|
}
|
|
else {
|
|
memcpy(p_blk, ptr, hdr->size);
|
|
}
|
|
#else
|
|
if( cell->size > size ) {
|
|
memcpy(p_blk, ptr, size);
|
|
}
|
|
else {
|
|
memcpy(p_blk, ptr, cell->size);
|
|
}
|
|
#endif
|
|
|
|
|
|
cr_alloc_Free( ptr );
|
|
|
|
return p_blk;
|
|
}
|
|
|