1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: os_MemoryBlock.cpp
4
5 Copyright (C)2009 Nintendo Co., Ltd. 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 $Rev: 17610 $
14 *---------------------------------------------------------------------------*/
15
16 #include <nn/config.h>
17 #if NN_PLATFORM_HAS_MMU
18
19
20 #include <nn/assert.h>
21 #include <nn/dbg/dbg_Logger.h>
22 #include <nn/os/os_CriticalSection.h>
23 #include <nn/os/os_Memory.h>
24 #include <nn/os/os_MemoryBlock.h>
25 #include <nn/os/os_MemoryMapSelect.h>
26 #include <nn/os/os_Result.h>
27 #include <nn/os/os_StackMemoryBlock.h>
28 #include <nn/svc/svc_Stub.h>
29 #include <nn/util/util_Result.h>
30
31 #include "os_AddressSpaceManager.h"
32
33 //---------------------------------------------------------------------------
34
35 using namespace nn;
36 using namespace nn::svc;
37
38 namespace nn{ namespace os{
39
40 namespace
41 {
42 nnosAddressSpaceManager s_SpaceManager;
43 bool s_IsMemoryBlockEnabled = false;
44 }
45
46 namespace detail
47 {
AllocateFromMemoryBlockSpace(MemoryBlockBase * p,size_t s)48 uptr AllocateFromMemoryBlockSpace(MemoryBlockBase* p, size_t s)
49 {
50 AddressSpaceManager* pManager = reinterpret_cast<AddressSpaceManager*>(&s_SpaceManager);
51 return pManager->Allocate(p, s, 0);
52 }
FreeToMemoryBlockSpace(MemoryBlockBase * p)53 void FreeToMemoryBlockSpace(MemoryBlockBase* p)
54 {
55 AddressSpaceManager* pManager = reinterpret_cast<AddressSpaceManager*>(&s_SpaceManager);
56 pManager->Free(p);
57 }
Switch(MemoryBlock * pTo,MemoryBlock * pFrom)58 void Switch(MemoryBlock* pTo, MemoryBlock* pFrom)
59 {
60 nnosAddressSpaceManagerSwitch(&s_SpaceManager, ConvertToC(pTo), ConvertToC(pFrom));
61 }
62
IsMemoryBlockEnabled()63 bool IsMemoryBlockEnabled()
64 {
65 return s_IsMemoryBlockEnabled;
66 }
67 }
68
Initialize(size_t size)69 void MemoryBlock::Initialize(size_t size)
70 {
71 // 未初期化であることをチェックします。
72 NN_TASSERT_(detail::IsMemoryBlockEnabled());
73 NN_TASSERT_(!GetAddress());
74
75 // 仮想アドレス空間からメモリを取得します。
76 size = GetPageAlignedSize(size);
77 uptr addr = detail::AllocateFromMemoryBlockSpace(this, size);
78 if (addr == 0)
79 {
80 NN_TPANIC_("Out Of Memory.");
81 }
82 this->MemoryBlockBase::SetReadOnly(false);
83 }
84
Finalize()85 void MemoryBlock::Finalize()
86 {
87 if (GetAddress())
88 {
89 // メモリブロックを仮想メモリ空間に戻します。
90 detail::FreeToMemoryBlockSpace(this);
91 }
92 }
93
94 // 読み込み専用属性を設定します。
SetReadOnly(bool readOnly)95 void MemoryBlock::SetReadOnly(bool readOnly)
96 {
97 NN_TASSERT_(GetAddress());
98 if (IsReadOnly() == readOnly)
99 {
100 return;
101 }
102 this->MemoryBlockBase::SetReadOnly(readOnly);
103 }
104
105
106
InitializeMemoryBlock(uptr begin,size_t size)107 void InitializeMemoryBlock(uptr begin, size_t size)
108 {
109 s_IsMemoryBlockEnabled = true;
110 nnosAddressSpaceManagerInitialize(&s_SpaceManager, begin, size);
111 }
112
113
114 }} // namespace nn::os
115
116
117 #include <new>
118 using namespace nn::os;
119
120 extern "C" {
121
122 // MemoryBlock
123
nnosMemoryBlockAllocate(nnosMemoryBlock * p,size_t size)124 void nnosMemoryBlockAllocate(nnosMemoryBlock* p, size_t size)
125 {
126 NN_TASSERT_(detail::IsMemoryBlockEnabled());
127 new (p) MemoryBlock(size);
128 }
129
nnosMemoryBlockSetReadOnly(nnosMemoryBlock * p,bool readOnly)130 void nnosMemoryBlockSetReadOnly(nnosMemoryBlock* p, bool readOnly)
131 {
132 MemoryBlock* pMemoryBlock = reinterpret_cast<MemoryBlock*>(p);
133 pMemoryBlock->SetReadOnly(readOnly);
134 }
135
nnosMemoryBlockFree(nnosMemoryBlock * p)136 void nnosMemoryBlockFree(nnosMemoryBlock* p)
137 {
138 MemoryBlock* pMemoryBlock = reinterpret_cast<MemoryBlock*>(p);
139 pMemoryBlock->~MemoryBlock();
140 }
141
nnosMemoryBlockGetAddress(nnosMemoryBlock * p)142 uptr nnosMemoryBlockGetAddress(nnosMemoryBlock* p)
143 {
144 MemoryBlock* pMemoryBlock = reinterpret_cast<MemoryBlock*>(p);
145 return pMemoryBlock->GetAddress();
146 }
147
nnosMemoryBlockGetSize(nnosMemoryBlock * p)148 size_t nnosMemoryBlockGetSize(nnosMemoryBlock* p)
149 {
150 MemoryBlock* pMemoryBlock = reinterpret_cast<MemoryBlock*>(p);
151 return pMemoryBlock->GetSize();
152 }
153
nnosMemoryBlockIsReadOnly(nnosMemoryBlock * p)154 bool nnosMemoryBlockIsReadOnly(nnosMemoryBlock* p)
155 {
156 MemoryBlock* pMemoryBlock = reinterpret_cast<MemoryBlock*>(p);
157 return pMemoryBlock->IsReadOnly();
158 }
159
160
161 }
162 #endif // if NN_PLATFORM_HAS_MMU
163