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