1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: os_StackMemory.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 #include <nn/os/os_StackMemory.h>
20 #include <nn/os/os_MemoryBlock.h>
21 #include <nn/os/os_Result.h>
22 #include <nn/assert.h>
23 #include <nn/svc/svc_Stub.h>
24 #include <nn/dbg/dbg_Logger.h>
25 #include <nn/util/util_Result.h>
26 #include <nn/os/os_Memory.h>
27 #include <nn/os/os_CriticalSection.h>
28 #include <nn/os/os_MemoryMapSelect.h>
29 #include "os_AddressSpaceManager.h"
30
31 //---------------------------------------------------------------------------
32
33 using namespace nn;
34 using namespace nn::svc;
35
36 namespace nn{ namespace os{
37
38 namespace
39 {
40 nnosAddressSpaceManager s_SpaceManager;
41 }
42
43 namespace detail
44 {
InitializeStackMemory()45 void InitializeStackMemory()
46 {
47 nnosAddressSpaceManagerInitialize(&s_SpaceManager, NN_OS_ADDR_STACK_BEGIN, NN_OS_ADDR_STACK_SIZE);
48 }
49 }
50
51
Initialize(void * pMem,size_t size)52 void StackMemory::Initialize(void* pMem, size_t size)
53 {
54 // 未初期化であることをチェックします。
55 NN_TASSERT_( GetAddress() == NULL );
56 NN_ALIGN_TASSERT_( pMem, NN_OS_MEMORY_PAGE_SIZE );
57 NN_ALIGN_TASSERT_( size, NN_OS_MEMORY_PAGE_SIZE );
58
59
60 // 仮想アドレス空間からメモリを取得します。
61 uptr addr = nnosAddressSpaceManagerAllocate(&s_SpaceManager, detail::ConvertToC(this), size, NN_OS_MEMORY_PAGE_SIZE);
62 if (addr == NULL)
63 {
64 NN_TPANIC_("failed to allocate address space.");
65 }
66
67 m_MemoryAddress = reinterpret_cast<uptr>(pMem);
68
69 Result result;
70 uptr dummy;
71 result = nn::svc::ControlMemory( &dummy,
72 addr,
73 m_MemoryAddress,
74 size,
75 nn::os::MEMORY_OPERATION_MAP,
76 nn::os::MEMORY_PERMISSION_READ_WRITE );
77 NN_UTIL_PANIC_IF_FAILED(result);
78
79 result = nn::svc::ControlMemory( &dummy,
80 m_MemoryAddress,
81 NULL,
82 size,
83 nn::os::MEMORY_OPERATION_PROTECT,
84 nn::os::MEMORY_PERMISSION_NONE );
85 NN_UTIL_PANIC_IF_FAILED(result);
86 }
87
Finalize()88 void* StackMemory::Finalize()
89 {
90 if ( GetAddress() != NULL )
91 {
92 const uptr addr = GetAddress();
93 const size_t size = GetSize();
94 const uptr memAddr = m_MemoryAddress;
95
96 nnosAddressSpaceManagerFree(&s_SpaceManager, detail::ConvertToC(this));
97
98 Result result;
99 uptr dummy;
100 result = nn::svc::ControlMemory( &dummy,
101 addr,
102 NULL,
103 size,
104 nn::os::MEMORY_OPERATION_FREE,
105 nn::os::MEMORY_PERMISSION_READ_WRITE );
106 NN_UTIL_PANIC_IF_FAILED(result);
107 // これ以降 this にアクセスしてはいけない
108
109 result = nn::svc::ControlMemory( &dummy,
110 memAddr,
111 NULL,
112 size,
113 nn::os::MEMORY_OPERATION_PROTECT,
114 nn::os::MEMORY_PERMISSION_READ_WRITE );
115 NN_UTIL_PANIC_IF_FAILED(result);
116
117 return reinterpret_cast<void*>(memAddr);
118 }
119
120 return NULL;
121 }
122
MoveFrom(StackMemory * pFrom)123 void StackMemory::MoveFrom(StackMemory* pFrom)
124 {
125 reinterpret_cast<AddressSpaceManager*>(&s_SpaceManager)->Switch(this, pFrom);
126 this->m_MemoryAddress = pFrom->m_MemoryAddress;
127 pFrom->m_MemoryAddress = NULL;
128 }
129
130
131 }} // namespace nn::os
132
133
134 #include <new>
135 using namespace nn::os;
136
137 extern "C" {
138
139 // StackMemory
140
nnosStackMemoryProtect(nnosStackMemory * p,void * pMem,size_t size)141 void nnosStackMemoryProtect(nnosStackMemory* p, void* pMem, size_t size)
142 {
143 new (p) StackMemory(pMem, size);
144 }
145
nnosStackMemoryUnprotect(nnosStackMemory * p)146 void nnosStackMemoryUnprotect(nnosStackMemory* p)
147 {
148 StackMemory* pStackMemory = reinterpret_cast<StackMemory*>(p);
149 pStackMemory->~StackMemory();
150 }
151
nnosStackMemoryGetAddress(nnosStackMemory * p)152 uptr nnosStackMemoryGetAddress(nnosStackMemory* p)
153 {
154 StackMemory* pStackMemory = reinterpret_cast<StackMemory*>(p);
155 return pStackMemory->GetAddress();
156 }
157
nnosStackMemoryGetSize(nnosStackMemory * p)158 size_t nnosStackMemoryGetSize(nnosStackMemory* p)
159 {
160 StackMemory* pStackMemory = reinterpret_cast<StackMemory*>(p);
161 return pStackMemory->GetSize();
162 }
163
nnosStackMemoryGetStackBottom(nnosStackMemory * p)164 uptr nnosStackMemoryGetStackBottom(nnosStackMemory* p)
165 {
166 StackMemory* pStackMemory = reinterpret_cast<StackMemory*>(p);
167 return pStackMemory->GetStackBottom();
168 }
169
170 }
171 #endif // if NN_PLATFORM_HAS_MMU
172