📄 mem.c
字号:
/*-----------------------------------------------------------------------------
$File: //hodad/usblink/3.4/source/hostctrl/otg242/mem.c $
$DateTime: 2003/11/21 14:48:39 $
$Revision: #3 $
Purpose: OTG242 on chip memory allocation methods.
CONFIDENTIAL AND PROPRIETARY INFORMATION OF SOFTCONNEX TECHNOLOGIES, INC.
THIS NOTICE IS NOT TO BE DELETED, MODIFIED, MOVED OR CHANGED IN ANY WAY.
Copyright (c) 1999 - 2003 by SoftConnex Technologies, Inc.
This software is protected by copyright laws and international copyright
treaties, as well as other intellectual property laws and treaties. This
software is a CONFIDENTIAL, unpublished work of authorship, and with portions
constituting TRADE SECRETS of SoftConnex Technologies, Inc., a Delaware USA
corporation. Any unauthorized use, disclosure, and/or reproduction of this
software, or any part of this software; or distribution of this software in any
form or by any means; or storage of this software in any database or retrieval
system, without the express written consent of, and license from, SoftConnex
Technologies, Inc. is strictly prohibited. This software is protected under the
copyright and/or trade secret laws in other countries in addition to USA. All
Rights Reserved. Failure to abide by the use, disclosure and/or reproduction
restrictions may result in civil and /or criminal penalties, and will be
prosecuted to the maximum extent of the law.
-----------------------------------------------------------------------------*/
#include "usblink.h"
#include "top.h"
SctStatus OTG242MEM_Create(Otg242Mem *mem)
{
U32 limit;
U32 i;
Otg242MemBlock *block;
U32 start;
U32 size;
U32 begin;
U32 length;
begin = OTG242MEM_START;
length = OTG242MEM_START + OTG242MEM_SIZE;
start = (begin + OTG242MEM_BLOCK_SIZE - 1) & ~(OTG242MEM_BLOCK_SIZE - 1);
size = length & ~(OTG242MEM_BLOCK_SIZE - 1);
#ifdef DEBUG_OTG_CHIP
info("Init: start=0x%0x size=0x%0x", start, size);
#endif
limit = OTG242MEM_START + OTG242MEM_SIZE;
if (start < OTG242MEM_START || start >= limit)
{
OS_DEBUG_MSG2(OS_ZONE_ERR, "Out of range of start %d", start);
return SCC_FALSE;
}
if (size < OTG242MEM_BLOCK_SIZE || size > OTG242MEM_SIZE)
{
OS_DEBUG_MSG2(OS_ZONE_ERR, "bad size %d", size);
return SCC_FALSE;
}
mem->start = start;
mem->blocks = (size >> OTG242MEM_BLOCK_MAGNITUDE) - 1;
block = mem->memBlocks;
for (i = 0; i <= mem->blocks; i++)
{
block->status = 0;
block++;
}
OTG242MEM_SET_BLOCKS(mem->memBlocks, mem->blocks);
OTG242MEM_SET_BLOCKS(&mem->memBlocks[mem->blocks], mem->blocks);
return SCC_TRUE;
}
SctStatus OTG242MEM_Initialize(Otg242Mem *mem)
{
return SCC_TRUE;
}
void OTG242MEM_Delete(Otg242Mem *mem)
{
}
static Otg242MemBlock *
otg_mem_FindFirstFit(Otg242Mem *mem, S32 blks, S32 backward)
{
Otg242MemBlock *block;
Otg242MemBlock *end;
if (!backward)
{
block = mem->memBlocks;
end = block + mem->blocks;
while (block <= end)
{
if (!(block->status & OTG242MEM_BLOCK_USED) &&
(block->size >= blks))
{
return block;
}
block += block->size + 1;
}
}
else
{
end = mem->memBlocks;
block = end + mem->blocks;
while (block >= end)
{
if (!(block->status & OTG242MEM_BLOCK_USED) &&
(block->size >= blks))
{
return block;
}
block -= block->size + 1;
}
}
return 0;
}
S32 OTG242MEM_Allocate(Otg242Mem* mem, S32 size)
{
Otg242MemBlock *found_block;
Otg242MemBlock *old;
S32 blks;
S32 new_size;
#ifdef DEBUG_OTG_CHIP
info("Allocate: mem=%p size=0x%0x", mem, size);
#endif
blks = OTG242MEM_BYTE_TO_BLOCK(size) - 1;
if (size > 64)
{
found_block = otg_mem_FindFirstFit(mem, blks, 0);
}
else
{
found_block = otg_mem_FindFirstFit(mem, blks, 1);
}
if (!found_block)
{
OS_DEBUG_MSG2(OS_ZONE_ERR, "Can't allocate host controller memory of size %d", size);
return -1;
}
if (size > 64)
{
/* Forward allocating */
if (found_block->size != blks)
{
/* split the block */
new_size = found_block->size - blks - 1;
old = found_block + found_block->size;
OTG242MEM_SET_BLOCKS(old, new_size);
OTG242MEM_SET_BLOCKS(found_block + blks + 1, new_size);
(found_block + blks + 1)->status &= ~OTG242MEM_BLOCK_USED;
OTG242MEM_SET_BLOCKS(found_block, blks);
OTG242MEM_SET_BLOCKS(found_block + blks, blks);
}
found_block->status |= OTG242MEM_BLOCK_USED;
(found_block + blks)->status |= OTG242MEM_BLOCK_USED;
#ifdef DEBUG_OTG_CHIP
info("Allocate: found block 0x%0x", found_block - mem->memBlocks);
#endif
return OTG242MEM_BLOCK_TO_ADDR(mem, found_block - mem->memBlocks);
}
else
{
/* Backward allocating */
if (found_block->size != blks)
{
new_size = found_block->size - blks - 1;
old = found_block - found_block->size;
OTG242MEM_SET_BLOCKS(old, new_size);
OTG242MEM_SET_BLOCKS(found_block - blks - 1, new_size);
(found_block - blks - 1)->status &= ~OTG242MEM_BLOCK_USED;
OTG242MEM_SET_BLOCKS(found_block, blks);
OTG242MEM_SET_BLOCKS(found_block - blks, blks);
}
found_block->status |= OTG242MEM_BLOCK_USED;
(found_block - blks)->status |= OTG242MEM_BLOCK_USED;
#ifdef DEBUG_OTG_CHIP
info("Allocate: found block 0x%0x", found_block - mem->memBlocks - blks);
#endif
return OTG242MEM_BLOCK_TO_ADDR(mem, found_block - mem->memBlocks - blks);
}
}
void OTG242MEM_Free(Otg242Mem* mem, U32 addr)
{
Otg242MemBlock *block;
Otg242MemBlock *other;
S32 blks;
S32 new_blks;
block = OTG242MEM_ADDR_TO_BLOCK(mem, addr);
if (!(block->status & OTG242MEM_BLOCK_USED))
{
OS_DEBUG_MSG2(OS_ZONE_ERR, "Try to deallocate unallocated memory chunk %d", addr);
return;
}
blks = block->size;
block->status &= ~OTG242MEM_BLOCK_USED;
if (block > mem->memBlocks)
{
other = block - 1;
new_blks = other->size + blks + 1;
if (!(other->status & OTG242MEM_BLOCK_USED))
{
other -= other->size;
OTG242MEM_SET_BLOCKS(other, new_blks);
OTG242MEM_SET_BLOCKS(block + blks, new_blks);
block = other;
blks = new_blks;
}
}
block += blks;
block->status &= ~OTG242MEM_BLOCK_USED;
if (block < (mem->memBlocks + mem->blocks))
{
other = block + 1;
new_blks = other->size + blks + 1;
if (!(other->status & OTG242MEM_BLOCK_USED))
{
other += other->size;
OTG242MEM_SET_BLOCKS(other, new_blks);
OTG242MEM_SET_BLOCKS(block - blks, new_blks);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -