/*---------------------------------------------------------------------------* Project: NitroSDK - OS File: os_arena.c Copyright 2003-2006 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. $Log: os_arena.c,v $ Revision 1.44 2006/01/18 05:46:04 okubata_ryoma do-indentの修正 Revision 1.43 2006/01/18 02:11:30 kitase_hirotake do-indent Revision 1.42 2005/10/18 10:42:36 yada modified about getting arena HI of PREV_WRAM in ARM7 Revision 1.41 2005/09/06 04:57:41 yada fix arena default hi address on DTCM Revision 1.40 2005/08/26 11:49:31 yada ARENALO is considered for DTCM, ITCM, MAINEX autoload Revision 1.39 2005/05/25 04:03:05 terui MB 子機の場合でもメインメモリを8MBに設定できるように修正 Revision 1.38 2005/04/14 06:46:13 yasu Multiboot 子機の場合、使用可能メモリを 4MB に制限するようにした Revision 1.37 2005/04/13 13:00:10 terui OS_InitArenaEx関数内で、4M設定時にARM7専用リージョンの位置を0x027e0000 から 0x023e0000に変更するように修正。 Revision 1.36 2005/02/28 09:57:43 seiki_masashi fix a debug message. Revision 1.35 2005/02/28 05:26:28 yosizaki do-indent. Revision 1.34 2004/12/21 11:24:27 yada add OS_EnableMainExArena() / OS_DisableMainExArena() Revision 1.33 2004/11/02 11:58:22 yada fix a little Revision 1.32 2004/10/04 06:16:53 yada protection region for MainRAM is set to 4MB if specified Revision 1.31 2004/08/31 01:02:51 yada add functions to get/set initial setting in specified arena Revision 1.30 2004/08/18 02:45:44 yada change sub-processor private arena of mainRAM Revision 1.29 2004/07/29 07:25:56 yada remove OS_Printf() in OS_GetArenaLo() Revision 1.28 2004/07/20 11:41:23 yada in case sysStack=0 (means maximum size), DTCM arena lo was set to HW_DTCM. fix to SDK_AUTOLOAD_DTCM_BSS_END. Revision 1.27 2004/07/12 12:25:21 yasu Fix arena setting Revision 1.26 2004/07/10 04:07:56 yasu Add short comment Revision 1.25 2004/07/08 02:22:21 yada add OS_InitArenaEx(), setting for extended mainRam arena Revision 1.24 2004/07/01 09:40:31 yasu add TARGET_ROM Revision 1.23 2004/05/27 04:40:25 yada change setting arena rule for ARM7 Revision 1.22 2004/04/14 00:07:33 yada add checkcode in allocation memory from arena Revision 1.21 2004/02/20 12:23:47 yada 初期化バグ修正 Revision 1.20 2004/02/19 08:41:41 yada ARM7 と ARM9 の初期化を分けた Revision 1.19 2004/02/16 09:39:46 yada Sysスタック修正 Revision 1.18 2004/02/14 08:23:12 yasu comment out TCM arena setting code on ARM7 due to pass nightly build Revision 1.17 2004/02/14 07:05:47 yasu fix indent level Revision 1.16 2004/02/13 10:38:26 yada ARENAを6個から9個に Revision 1.15 2004/02/13 04:05:36 yada ARM9とAMR7 の場合わけ考慮 Revision 1.14 2004/02/05 07:09:02 yasu change SDK prefix iris -> nitro Revision 1.13 2004/01/18 01:25:40 yada インデント等の整形のみ Revision 1.12 2004/01/16 11:47:20 yada arena情報の位置を動かしたことによる修正 Revision 1.11 2004/01/16 08:10:03 yada DTCMアリーナ設定のASSERT修正 Revision 1.10 2004/01/16 07:25:26 yada arena の initialized フラグ位置修正 Revision 1.9 2004/01/16 04:07:39 yada idle Thread のスタックを lcf定義から取るように変更 Revision 1.8 2004/01/15 12:13:55 yada SystemWork にアリーナ構造体を取るようにした Revision 1.7 2004/01/15 10:07:25 yasu Use SDK_MAIN_ARENA_LO from LCF to resolve arena region Revision 1.6 2004/01/07 02:52:04 yada 小変更 Revision 1.5 2004/01/07 01:42:40 yada arena初期化部分の変更 Revision 1.4 2004/01/05 04:28:24 yada 各アリーナの仮初期化を入れた Revision 1.3 2003/12/26 08:21:13 yada Assert 中の不具合修正 Revision 1.2 2003/12/26 08:11:35 yada IDの型を int -> OSArenaId に Revision 1.1 2003/12/26 06:42:33 yada 初版 $NoKeywords: $ *---------------------------------------------------------------------------*/ #include #define OSi_TRUNC(n, a) (((u32) (n)) & ~((a) - 1)) #define OSi_ROUND(n, a) (((u32) (n) + (a) - 1) & ~((a) - 1)) #define OS_ERR_GETARENAHI_INIT "OS_GetArenaHi: init in advance" #define OS_ERR_GETARENAHI_INVALID "OS_GetArenaHi: invalid arena (hi (u32)HW_PRV_WRAM) { sysStackLo = (u32)SDK_WRAM_ARENA_LO; } if (OSi_SYS_STACKSIZE == 0) // maximum SysStack in SURPRIV-WRAM { // do nothing } else if (OSi_SYS_STACKSIZE < 0) { sysStackLo -= OSi_SYS_STACKSIZE; } else { sysStackLo = irqStackLo - OSi_SYS_STACKSIZE; } SDK_ASSERT((u32)HW_PRV_WRAM <= sysStackLo && sysStackLo < irqStackLo); return (void *)sysStackLo; } #endif default: SDK_WARNING(0, "Bad arena id"); } return NULL; } /*---------------------------------------------------------------------------* Name: OS_GetInitArenaLo Description: Get the initial low boundary of the arena Arguments: id : arena ID Returns: the initial low boundary of the arena *---------------------------------------------------------------------------*/ void *OS_GetInitArenaLo(OSArenaId id) { SDK_ASSERT(OSi_Initialized); SDK_ARENAID_ASSERT(id); switch (id) { #ifdef SDK_ARM9 case OS_ARENA_MAIN: return (void *)OSi_MAIN_ARENA_LO_DEFAULT; case OS_ARENA_MAINEX: if (!OSi_MainExArenaEnabled || ((OS_GetConsoleType() & OS_CONSOLE_SIZE_MASK) == OS_CONSOLE_SIZE_4MB)) { return (void *)0; } else { return (void *)OSi_MAINEX_ARENA_LO_DEFAULT; } case OS_ARENA_ITCM: return (void *)OSi_ITCM_ARENA_LO_DEFAULT; case OS_ARENA_DTCM: return (void *)OSi_DTCM_ARENA_LO_DEFAULT; case OS_ARENA_SHARED: return (void *)HW_SHARED_ARENA_LO_DEFAULT; case OS_ARENA_WRAM_MAIN: return (void *)OSi_WRAM_MAIN_ARENA_LO_DEFAULT; #else case OS_ARENA_MAIN_SUBPRIV: return (void *)OSi_MAIN_SUBPRIV_ARENA_LO_DEFAULT; case OS_ARENA_WRAM_SUB: { u32 wramSubLo = OSi_WRAM_SUB_ARENA_LO_DEFAULT; #if 0 if ((u32)HW_WRAM_END < (u32)wramSubLo) { wramSubLo = (u32)HW_WRAM_END; } #endif return (void *)wramSubLo; } case OS_ARENA_WRAM_SUBPRIV: { u32 privWramLo = OSi_WRAM_SUBPRIV_ARENA_LO_DEFAULT; #if 0 if ((u32)SDK_WRAM_ARENA_LO > (u32)privWramLo) { privWramLo = (u32)SDK_WRAM_ARENA_LO; } #endif return (void *)privWramLo; } #endif default: SDK_WARNING(0, "Bad arena id"); } return NULL; } //================================================================================ // SET ARENA INFO //================================================================================ /*---------------------------------------------------------------------------* Name: OS_SetArenaHi Description: Set the high boundary of the arena Arguments: id : arena ID newHi : New high boundary of the arena. Returns: None. *---------------------------------------------------------------------------*/ void OS_SetArenaHi(OSArenaId id, void *newHi) { SDK_ASSERT(OSi_Initialized); SDK_ARENAID_ASSERT(id); OSi_GetArenaInfo().hi[id] = newHi; } /*---------------------------------------------------------------------------* Name: OS_GetArenaLo Description: Set the low boundary of the arena Arguments: id : arena ID newLo : New low boundary of the arena. Returns: None. *---------------------------------------------------------------------------*/ void OS_SetArenaLo(OSArenaId id, void *newLo) { SDK_ASSERT(OSi_Initialized); SDK_ARENAID_ASSERT(id); OSi_GetArenaInfo().lo[id] = newLo; } //================================================================================ // ALLOC //================================================================================ /*---------------------------------------------------------------------------* Name: OS_AllocFromArenaLo Description: Allocates /size/ bytes from the low boundary of the arena. Some additional memory will also be consumed from arena for the alignment. Arguments: id : arena ID size : Size of object to be allocated align : Alignment of object and new arena boundary to be set (must be power of 2). Returns: a pointer to the allocated space aligned with /align/ bytes boundaries. The new low boundary of the arena is also aligned with /align/ bytes boundaries. NULL if cannot allocate. *---------------------------------------------------------------------------*/ void *OS_AllocFromArenaLo(OSArenaId id, u32 size, u32 align) { void *ptr; u8 *arenaLo; ptr = OS_GetArenaLo(id); if (!ptr) { return NULL; } arenaLo = ptr = (void *)OSi_ROUND(ptr, align); arenaLo += size; arenaLo = (u8 *)OSi_ROUND(arenaLo, align); if (arenaLo > OS_GetArenaHi(id)) { return NULL; } OS_SetArenaLo(id, arenaLo); return ptr; } /*---------------------------------------------------------------------------* Name: OS_AllocFromArenaHi Description: Allocates /size/ bytes from the high boundary of the arena. Some additional memory will also be consumed from arena for the alignment. Arguments: id : arena ID size : Size of object to be allocated align : Alignment of object and new arena boundary to be set (must be power of 2). Returns: a pointer to the allocated space aligned with /align/ bytes boundaries. The new high boundary of the arena is also aligned with /align/ bytes boundaries. NULL if cannot allocate. *---------------------------------------------------------------------------*/ void *OS_AllocFromArenaHi(OSArenaId id, u32 size, u32 align) { void *ptr; u8 *arenaHi; arenaHi = OS_GetArenaHi(id); if (!arenaHi) { return NULL; } arenaHi = (u8 *)OSi_TRUNC(arenaHi, align); arenaHi -= size; arenaHi = ptr = (void *)OSi_TRUNC(arenaHi, align); if (arenaHi < OS_GetArenaLo(id)) { return NULL; } OS_SetArenaHi(id, arenaHi); return ptr; } #ifdef SDK_ARM9 /*---------------------------------------------------------------------------* Name: OS_EnableMainExArena Description: Set extended main memory arena enable. This function should be called before OS_Init(). Arguments: None Returns: None *---------------------------------------------------------------------------*/ void OS_EnableMainExArena(void) { SDK_ASSERT(!OSi_Initialized); OSi_MainExArenaEnabled = TRUE; } /*---------------------------------------------------------------------------* Name: OS_DisableMainExArena Description: Set extended main memory arena disable. This function should be called before OS_Init(). Arguments: None Returns: None *---------------------------------------------------------------------------*/ void OS_DisableMainExArena(void) { SDK_ASSERT(!OSi_Initialized); OSi_MainExArenaEnabled = FALSE; } #endif