1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     demo_Memory.cpp
4 
5   Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Revision: 23247 $
14  *---------------------------------------------------------------------------*/
15 
16 #include <nw/types.h>
17 #include <nw/os.h>
18 #include <nw/ut/ut_Inlines.h>
19 #include <nw/demo.h>
20 #include <nw/demo/demo_Memory.h>
21 #include <nn/os.h>
22 #include <nn/fnd.h>
23 #include <stdlib.h>
24 
25 
26 namespace nw {
27 namespace demo {
28 
29 static nn::os::MemoryBlock s_MemoryBlock;
30 static nn::fnd::ExpHeap    s_MainMemoryHeap;
31 static bool                s_IsInitialized = false;
32 
33 /*!--------------------------------------------------------------------------*
34   @brief       確保したメモリのアライメントを調整します。
35 
36   @param[in]   memory  確保されたメモリの先頭ポインタです。
37   @param[in]   align   アライメント値です。
38 
39   @return      アラインされたアドレスを返します。
40  *---------------------------------------------------------------------------*/
41 static void*
AlignMemory_(void * memory,u8 align)42 AlignMemory_( void* memory, u8 align )
43 {
44     void* top = nw::ut::AddOffsetToPtr( memory, 1 );
45     top = nw::ut::RoundUp( top, align );
46 
47     u8* head = reinterpret_cast<u8*>( nw::ut::AddOffsetToPtr( top, - 1 ) );
48 
49     size_t offset = nw::ut::GetOffsetFromPtr( memory, top );
50     NW_U8_RANGE_ASSERT( offset );
51 
52     *head = static_cast<u8>( offset );
53     return top;
54 }
55 
56 //--------------------------------------------------------------------------
57 void
InitializeDemoAllocator(DemoAllocator * allocator,size_t size,bit32 option)58 InitializeDemoAllocator( DemoAllocator* allocator, size_t size, bit32 option /* = 0 */ )
59 {
60     void* memory = nw::demo::Alloc(size);
61     uptr address = reinterpret_cast<uptr>(memory);
62     allocator->Initialize(address, size, option);
63 }
64 
65 //--------------------------------------------------------------------------
66 void
FinalizeDemoAllocator(DemoAllocator * allocator)67 FinalizeDemoAllocator( DemoAllocator* allocator )
68 {
69     nw::demo::Free(reinterpret_cast<void*>(allocator->GetStartAddress()));
70     allocator->Finalize();
71 }
72 
73 //--------------------------------------------------------------------------
74 void
InitializeDemoMemory()75 InitializeDemoMemory()
76 {
77     if ( s_IsInitialized )
78     {
79         return;
80     }
81     s_IsInitialized = true;
82 
83     // デバイスメモリのサイズを指定します。
84     // 現在は 32MB を指定していますが、今後SDKの仕様に合わせて変更します。
85     const size_t DEMO_MAIN_MEMORY_SIZE = 0x2000000; // 32MB
86 
87     nn::os::SetDeviceMemorySize(DEMO_MAIN_MEMORY_SIZE);
88 
89     uptr address = nn::os::GetDeviceMemoryAddress();
90 
91     nwosPrintf(
92         "################# Device Memory : 0x%x - 0x%x #################\n",
93         (uint)address,
94         ((uint)address + DEMO_MAIN_MEMORY_SIZE));
95 
96     s_MainMemoryHeap.Initialize(address, DEMO_MAIN_MEMORY_SIZE, nn::os::ALLOCATE_OPTION_LINEAR);
97 }
98 
99 //--------------------------------------------------------------------------
100 void*
UnAlignMemory(void * memory)101 UnAlignMemory( void* memory )
102 {
103     u8* head = reinterpret_cast<u8*>( nw::ut::AddOffsetToPtr( memory, -1 ) );
104 
105     u8 offset = *head;
106 
107     return nw::ut::AddOffsetToPtr( memory, -offset );
108 }
109 
110 //--------------------------------------------------------------------------
111 void*
Alloc(size_t size,u8 alignment)112 Alloc(size_t size, u8 alignment)
113 {
114     // 2のべき乗のチェック
115     NW_ASSERT( (alignment & (alignment - 1)) == 0 );
116 
117     if ( alignment == 0 ) { alignment = 1; }
118 
119     InitializeDemoMemory(); // 未初期化の場合にはデフォルト設定で初期化。
120 
121     void* memory = s_MainMemoryHeap.Allocate( size + alignment );
122 
123     return AlignMemory_( memory, alignment );
124 }
125 
126 //--------------------------------------------------------------------------
127 void
Free(void * memory)128 Free(void* memory)
129 {
130     memory = UnAlignMemory( memory );
131 
132     s_MainMemoryHeap.Free( memory );
133 }
134 
135 //--------------------------------------------------------------------------
Dump()136 void Dump()
137 {
138     s_MainMemoryHeap.Dump();
139 }
140 
141 
142 //--------------------------------------------------------------------------
143 void
Initialize(uptr startAddress,size_t size,bit32 option)144 DemoAllocator::Initialize(uptr startAddress, size_t size, bit32 option)
145 {
146     m_StartAddress = startAddress;
147     m_Heap.Initialize(m_StartAddress, size, option);
148 }
149 
150 //--------------------------------------------------------------------------
151 void
Finalize()152 DemoAllocator::Finalize()
153 {
154     m_Heap.Finalize();
155 }
156 
157 //--------------------------------------------------------------------------
158 size_t
GetFreeSize()159 DemoAllocator::GetFreeSize()
160 {
161     return m_Heap.GetTotalFreeSize();
162 }
163 
164 //--------------------------------------------------------------------------
165 size_t
GetMemoryBlockSize(void * address)166 DemoAllocator::GetMemoryBlockSize(void* address)
167 {
168     return m_Heap.GetSizeOf(address);
169 }
170 
171 //--------------------------------------------------------------------------
172 void
Dump()173 DemoAllocator::Dump()
174 {
175     m_Heap.Dump();
176 }
177 
178 } /* namespace demo */
179 } /* namespace nw   */
180