(shirait) buddyアロケータ追加(OSにヒープ機能が出来るまでのつなぎ)

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_firmware@277 b871894f-2f95-9b40-918c-086798483c85
This commit is contained in:
(no author) 2009-02-12 11:20:53 +00:00
parent ba4a3554cf
commit 4ec6c49ec0
6 changed files with 644 additions and 0 deletions

View File

@ -0,0 +1,46 @@
#! make -f
#----------------------------------------------------------------------------
# Project: CtrBrom - libraries - mi
# File: Makefile
#
# Copyright 2008-2009 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev$
# $Author$
#----------------------------------------------------------------------------
SUBDIRS =
SUBMAKES =
#----------------------------------------------------------------------------
# build ARM & THUMB libraries
FIRM_CODEGEN_ALL ?= TRUE
SRCDIR = . ../common
SRCS = \
buddy_allocator.c \
TARGET_LIB = libheap$(FIRM_LIBSUFFIX).a
include $(CTRFIRM_ROOT)/build/buildtools/commondefs
INSTALL_TARGETS = $(TARGETS)
INSTALL_DIR = $(FIRM_INSTALL_LIBDIR)
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(CTRFIRM_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,54 @@
#! make -f
#----------------------------------------------------------------------------
# Project: CtrBrom - libraries_sp - mi
# File: Makefile
#
# Copyright 2008-2009 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev$
# $Author$
#----------------------------------------------------------------------------
SUBDIRS =
#SUBMAKES = Makefile.CALLTRACE \
# Makefile.FUNCTIONCOST
#----------------------------------------------------------------------------
# build ARM & THUMB libraries
FIRM_CODEGEN_ALL ?= TRUE
# Codegen for sub processer
FIRM_PROC = ARM9
SRCDIR = . ../common
SRCS = \
buddy_allocator.c \
TARGET_LIB = libheap_sp$(FIRM_LIBSUFFIX).a
#----------------------------------------------------------------------------
include $(CTRFIRM_ROOT)/build/buildtools/commondefs
INSTALL_TARGETS = $(TARGETS)
INSTALL_DIR = $(FIRM_INSTALL_LIBDIR)
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(CTRFIRM_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,34 @@
#! make -f
#----------------------------------------------------------------------------
# Project: CtrBrom - libraries - mi
# File: Makefile
#
# Copyright 2008 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev$
# $Author$
#----------------------------------------------------------------------------
include $(CTRFIRM_ROOT)/build/buildtools/commondefs
#----------------------------------------------------------------------------
SUBDIRS = ARM11
#ifdef CTR_WITH_ARM9
SUBDIRS += ARM9
#endif
#----------------------------------------------------------------------------
include $(CTRFIRM_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,445 @@
#include <brom.h>
/*---------------------------------------------------------------------------*
*---------------------------------------------------------------------------*/
#define MIN_ORDER 1 /* たぶん意味なし */
#define MAX_ORDER 14 /* このシステムが管理できるメモリ容量が(2のMAX_ORDER乗)*PAGE_SIZEバイトになる */
#define PAGE_SIZE 512 /* 最小管理単位(バイト) */
/*---------------------------------------------------------------------------*
*---------------------------------------------------------------------------*/
#define CHECK(exp) ((void)0)
#define i_osAlign(x, a) (((x)+(a)-1)&~((a)-1)) /*アラインメントを取る*/
#define o2num( order ) (1 << (order)) /*2のorder乗*/
/*---------------------------------------------------------------------------*
*---------------------------------------------------------------------------*/
typedef unsigned int uint;
typedef unsigned char byte;
/*---------------------------------------------------------------------------*
*---------------------------------------------------------------------------*/
typedef struct {
uint max_order; /* Buddyシステムで扱うサイズを2のsize_order乗として表したもの */
/* max_order=14なら16384バイト */
uint page_size; /* 最小管理単位のサイズ */
void *map; /* 二分木ビットマップへのポインタ */
/* 1バイト以上かつ(2のmax_order乗)*2/8 バイト以上必要 */
/* max_order=14なら4096 Byte */
void *mem; /* Buddyシステムが管理するメモリへのポインタ */
/* (2のmax_order乗)*page_size バイト必要 */
/* max_order=14,page_size=4なら65536 Byte */
} Buddy;
/*---------------------------------------------------------------------------*
static変数
*---------------------------------------------------------------------------*/
static Buddy my_buddy; //実体
static Buddy *buddy = &my_buddy; //これを使う
//static byte map[4096];
//static byte mem[16384 * PAGE_SIZE];
/*---------------------------------------------------------------------------*
static関数
*---------------------------------------------------------------------------*/
static void mapclr( void *map, uint i );
static void mapset( void *map, uint i );
static int mapget( void *map, uint i );
//static uint map_search( void *map, uint index_order );
static uint map_alloc( void *map, uint index_order );
static void map_free( void *map, uint i );
static void *buddy_alloc( Buddy *buddy, uint order );
static void buddy_free( Buddy *buddy, uint order, void *ptr );
static BOOL buddy_init( Buddy *buddy, uint max_order, uint page_size, void *map, void *mem );
asm u32 i_clz( u32 r0);
asm uint map_search( u32 map, u32 i); //こちらのmap_searchの方が6.7倍速い
/*---------------------------------------------------------------------------*
*---------------------------------------------------------------------------*/
/* map の i番目のビットを0(使用中)にする */
static void mapclr( void *map, uint i )
{
u32 *temp_ptr;
u32 word_count;
u32 bit_count;
// osTPrintf("%s n=%d\n",__FUNCTION__,i);
word_count = i / 32;
bit_count = 31 - (i % 32);
temp_ptr = (u32 *)map + word_count;
*temp_ptr &= ~(1 << bit_count);
}
/* map の i番目のビットを1(未使用)にする */
static void mapset( void *map, uint i )
{
u32 *temp_ptr;
u32 word_count;
u32 bit_count;
// osTPrintf("%s n=%d\n",__FUNCTION__,i);
word_count = i / 32;
bit_count = 31 - (i % 32);
temp_ptr = (u32 *)map + word_count;
*temp_ptr |= (1 << bit_count);
}
/* map の i番目のビットを取得する */
static int mapget( void *map, uint i )
{
u32 *temp_ptr;
u32 word_count;
u32 bit_count;
word_count = i / 32;
bit_count = 31 - (i % 32);
temp_ptr = (u32 *)map + word_count;
if( *temp_ptr & (1 << bit_count) ) {
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*
Name: map_search
Description: mapの何番目にあるかを返す
0調
Arguments: map :
index_order : Bitmap中の 2 index_order
Returns:
*---------------------------------------------------------------------------*/
#if 0
static uint map_search( void *map, uint index_order )
{
uint num, end_of_num;
uint i;
/*search開始位置を求める*/
num = ( 1 << index_order);
/* num から空き(ビット1)を探す */
end_of_num = (num << 1) - 1;
while( 1 ) {
if( mapget( map, num ) ) {
return num;
}
num++;
if( num > end_of_num ) {
break;
}
}
return 0;
}
#else
#include <brom/code32.h>
asm uint map_search( u32 map, u32 index_order)
{
mov r2, #1
mov r2, r2, lsl r1 //r2:num = 1 << index_order; 以降r1壊してOK
mov r3, r2, lsl #1 //
sub r3, r3, #1 //r3:end_of_num = (num << 1) - 1;
mov r1, r2, lsr #5 //r1:word_count = num/32;
mov r1, r1, lsl #2 //r1:byte_count = word_count*4
add r1, r1, r0 //r1:word_adr = byte_count+ map; 以降r0壊してOK
_ms2_loop
ldr r12, [r1] //r12:temp_ptr = *(u32*)(word_adr);
and r0, r2, #31 //オーダー開始ビット位置がword倍数でない場合は
mov r12, r12, lsl r0 //予めシフトしておく
clz r12, r12
subs r0, r12, #32 //r0:r12-32
bne _ms2_found //if( r0!=0) jump; //見つかったらジャンプ
add r2, r2, #32 //num += 32;
add r1, r1, #4 //word_adr += 4;
subs r0, r3, r2 //r0:end_of_num - num
bcc _ms2_notfound //ボロー時ジャンプ
b _ms2_loop //繰り返し
_ms2_found
add r2, r2, r12 //r2:num=num+r12
subs r0, r3, r2 //r0:end_of_num - num
bcc _ms2_notfound //ボロー時ジャンプ
mov r0, r2
bx lr
_ms2_notfound
mov r0, #0;
bx lr
}
#include <brom/codereset.h>
#endif
/*---------------------------------------------------------------------------*
Name: map_alloc
Description:
()
0
Arguments: map :
index_order : Bitmap中の 2 index_order
Returns:
*---------------------------------------------------------------------------*/
static uint map_alloc( void *map, uint index_order )
{
uint found;
uint i;
// osTPrintf( "map_search:0x%x\n", index_order);
found = map_search( (u32)map, index_order );
if( found == 0 ) {
if( index_order == 0 ) {
return 0;
}
i = map_alloc( map, index_order - 1 );
if( i == 0 ) {
return 0 ;
}
found = i*2;
mapset( map, i*2+1 );
}
mapclr( map, found );
return found;
}
/*---------------------------------------------------------------------------*
Name: map_free
Description: map_alloc iにあたる領域を開放する
Arguments: map :
i :
Returns:
*---------------------------------------------------------------------------*/
static void map_free( void *map, uint i )
{
/*(i^1)は相棒を表す*/
if( mapget( map, i^1)) {
mapclr( map, i^1);
map_free( map, i/2);
}else {
mapset( map, i);
}
}
/*---------------------------------------------------------------------------*
Name: buddy_alloc
Description:
map_alloc
Arguments: buddy :
order :
Returns:
*---------------------------------------------------------------------------*/
static void *buddy_alloc( Buddy *buddy, uint order )
{
uint found, offset;
if( buddy->max_order < order ) {
return NULL;
}
found = map_alloc( buddy->map, buddy->max_order - order ); //オーダーが0max_orderになる
if( found == 0 ) {
return NULL;
}
CHECK( (found >= o2num(buddy->max_order - order)) );
offset = (found - o2num(buddy->max_order - order)) * o2num(order);
return (void *)((uint)(buddy->mem) + offset * buddy->page_size);
}
/*---------------------------------------------------------------------------*
Name: buddy_free
Description:
map map_freeで解放する
Arguments: buddy :
order :
Returns:
*---------------------------------------------------------------------------*/
static void buddy_free( Buddy *buddy, uint order, void *ptr )
{
uint i, offset;
CHECK( ptr >= buddy->mem );
offset = ((uint)ptr - (uint)buddy->mem) / buddy->page_size;
i = offset / o2num(order) + o2num(buddy->max_order - order);
map_free( buddy->map, i );
}
/*---------------------------------------------------------------------------*
Name: buddy_init
Description:
Arguments:
Returns: TRUE / FALSE
*---------------------------------------------------------------------------*/
static BOOL buddy_init( Buddy *buddy, uint max_order, uint page_size, void *map, void *mem )
{
if ( (max_order < MIN_ORDER) && (MAX_ORDER < max_order) ) {
return FALSE;
}
miCpuFill8( map, 0, o2num(max_order) * 2 / 8 ); //8で割ってバイト単位にする
mapset( map, 1 );
buddy->max_order = max_order;
buddy->page_size = page_size;
buddy->map = map;
buddy->mem = mem;
return TRUE;
}
/*ここからAPI*/
/*---------------------------------------------------------------------------*
Name: buddy_allocator_init
Description:
sizeによっては使heap領域が大きくなることに注意
Arguments: none
Returns: none
*---------------------------------------------------------------------------*/
BOOL buddy_allocator_init( void* heap, u32 size)
{
u32 map;
u32 mem;
u32 aligned_size;
u32 max_order;
u32 mult_of_2;
u32 map_size, mem_size;
/*heapアドレスとサイズから、管理領域とメモリ領域を算出*/
map = i_osAlign( (u32)(heap), 4);
if( (map - (u32)(heap)) >= size) {
return( FALSE);
}
aligned_size = size - (map - (u32)(heap));
mult_of_2 = (8 * aligned_size) / (8 * PAGE_SIZE + 2);
max_order = 31 - i_clz( mult_of_2);
map_size = ((1 << max_order) * 2) / 8;
mem = map + map_size;
mem_size = ((1 << max_order) * PAGE_SIZE);
/* Buddy *buddy, uint max_order, uint page_size, void *map, void *mem */
if( buddy_init( buddy, (uint)max_order, (uint)PAGE_SIZE, (void *)map, (void *)mem)) {
osTPrintf( "buddy allocator init success!\n");
osTPrintf( "heap address : 0x%x, heap size : 0x%x\n", heap, size);
osTPrintf( "map address : 0x%x, map size : 0x%x\n", map, map_size);
osTPrintf( "mem address : 0x%x, mem size : 0x%x\n", mem, mem_size);
osTPrintf( "max order : 0x%x\n", max_order);
return( TRUE);
}else {
osTPrintf( "buddy allocator init fail!\n");
return( FALSE);
}
}
#include <brom/code32.h>
asm u32 i_clz( u32 r0)
{
clz r0, r0
bx lr
}
#include <brom/codereset.h>
/*---------------------------------------------------------------------------*
Name: malloc
Description:
Arguments: size :
Returns: void* :
*---------------------------------------------------------------------------*/
void *osAlloc( uint size )
{
void *ptr;
uint order;
/*指定のサイズに一番近いオーダーを探す*/
for( order=0; order<=MAX_ORDER; order++) {
if( (size + sizeof(uint)) <= (o2num(order) * PAGE_SIZE) ) {
break;
}
}
if( order > MAX_ORDER ) {
return NULL;
}
ptr = buddy_alloc( buddy, order ); //order は 0MAX_ORDER
if( ptr == NULL ) {
return NULL;
}
/*
* order
*/
*(*(uint**)&ptr) = order;
*(uint*)&ptr += sizeof(uint);
return ptr;
}
/*---------------------------------------------------------------------------*
Name: free
Description:
Arguments: mem :
Returns: none
*---------------------------------------------------------------------------*/
void osFree( void *mem )
{
void *ptr;
uint order;
/*order を得る*/
ptr = (void *)((uint)mem - sizeof(uint));
order = *(uint*)ptr;
buddy_free( buddy, order, ptr );
}

View File

@ -0,0 +1,25 @@
#ifndef _BUDDY_ALLOCATOR_H_
#define _BUDDY_ALLOCATOR_H_
#ifdef __cplusplus
extern "C" {
#endif
/*===========================================================================*/
extern BOOL buddy_allocator_init( void* heap, u32 size);
extern void *osAlloc( unsigned int size );
extern void osFree( void *mem );
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _BUDDY_ALLOCATOR_H_ */
/*---------------------------------------------------------------------------*
End of file
*---------------------------------------------------------------------------*/

View File

@ -0,0 +1,40 @@
/*---------------------------------------------------------------------------*
Project: TwlSDK - STD - include
File: string.h
Copyright 2005-2008 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#ifndef FIRM_HEAP_HEAP_H_
#define FIRM_HEAP_HEAP_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <brom/misc.h>
#include <brom/types.h>
#include <brom/mi/memory.h>
typedef int OSHeapHandle;
extern BOOL buddy_allocator_init( void* heap, u32 size);
extern void *osAlloc( unsigned int size );
extern void osFree( void *mem );
#ifdef __cplusplus
} /* extern "C" */
#endif
/* FIRM_HEAP_HEAP_H_ */
#endif