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 // Check that it is not initialized.
72 NN_TASSERT_(detail::IsMemoryBlockEnabled());
73 NN_TASSERT_(!GetAddress());
74
75 // Get memory from the virtual address space.
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 // Returns the memory block to the virtual memory space.
90 detail::FreeToMemoryBlockSpace(this);
91 }
92 }
93
94 // Sets the read only attribute.
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