1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: os_TransferMemoryBlock.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: 38846 $
14 *---------------------------------------------------------------------------*/
15
16 #include <nn/config.h>
17 #if NN_PLATFORM_HAS_MMU
18
19 #include <nn/svc.h>
20 #include <nn/util/util_Result.h>
21 #include <nn/os/os_Result.h>
22 #include <nn/os/os_TransferMemoryBlock.h>
23 #include <nn/os/os_SharedMemory.h>
24 #include <nn/os/os_MemoryMapSelect.h>
25 #include <nn/os/os_ErrorHandlerSelect.h>
26 #include "os_AddressSpaceManager.h"
27
28 namespace nn { namespace os {
29
Initialize(void * p,size_t size,bit32 myPermission,bit32 otherPermission)30 void TransferMemoryBlock::Initialize(
31 void* p,
32 size_t size,
33 bit32 myPermission,
34 bit32 otherPermission )
35 {
36 NN_OS_ERROR_IF_FAILED(TryInitialize(p, size, myPermission, otherPermission));
37 }
38
TryInitialize(void * p,size_t size,bit32 myPermission,bit32 otherPermission)39 Result TransferMemoryBlock::TryInitialize(
40 void* p,
41 size_t size,
42 bit32 myPermission,
43 bit32 otherPermission )
44 {
45 // Check that it is uninitialized.
46 NN_TASSERTMSG_( GetAddress() == NULL, "This TransferMemoryBlock instance has been already initialized.\n" );
47 if ( GetAddress() )
48 {
49 return ResultAlreadyInitialized();
50 }
51
52 // Check alignment.
53 if ( (reinterpret_cast<uptr>(p) % NN_OS_MEMORY_PAGE_SIZE ) != 0 )
54 {
55 return ResultMisalignedAddress();
56 }
57 if ( ( size % NN_OS_MEMORY_PAGE_SIZE ) != 0 )
58 {
59 return ResultMisalignedSize();
60 }
61
62 Handle handle;
63 Result result;
64 result = nn::svc::CreateMemoryBlock(&handle, reinterpret_cast<uptr>(p), size, myPermission, otherPermission);
65 NN_UTIL_RETURN_IF_FAILED(result);
66 this->SetHandle(handle);
67
68 SetAddressAndSize(reinterpret_cast<uptr>(p), size);
69 return result;
70 }
71
Finalize()72 void TransferMemoryBlock::Finalize()
73 {
74 if (this->IsValid())
75 {
76 Unmap();
77 this->HandleObject::Close();
78 }
79 }
80
81
82
83
AttachAndMap(Handle handle,size_t size,bit32 otherPermission,bit32 myPermission)84 Result TransferMemoryBlock::AttachAndMap(
85 Handle handle,
86 size_t size,
87 bit32 otherPermission,
88 bit32 myPermission )
89 {
90 // Check alignment.
91 if ( ( size % NN_OS_MEMORY_PAGE_SIZE ) != 0 )
92 {
93 return ResultMisalignedSize();
94 }
95
96 this->SetHandle(handle);
97 return Map(size, otherPermission, myPermission);
98 }
99
Map(size_t size,bit32 otherPermission,bit32 myPermission)100 Result TransferMemoryBlock::Map(
101 size_t size,
102 bit32 otherPermission,
103 bit32 myPermission )
104 {
105 // Check that it is uninitialized.
106 NN_TASSERT_( GetAddress() == NULL );
107 if ( GetAddress() )
108 {
109 return ResultAlreadyInitialized();
110 }
111
112 // Check alignment.
113 if ( ( size % NN_OS_MEMORY_PAGE_SIZE ) != 0 )
114 {
115 return ResultMisalignedSize();
116 }
117
118 // Get memory from the virtual address space.
119 uptr addr = detail::AllocateFromSharedMemorySpace(this, size);
120 if (addr == NULL)
121 {
122 return ResultNoAddressSpace();
123 }
124
125 this->MemoryBlockBase::SetReadOnly((myPermission & os::MEMORY_PERMISSION_WRITE) == 0);
126
127 Result result = nn::svc::MapMemoryBlock(GetHandle(), addr, myPermission, otherPermission);
128 if( result.IsFailure() )
129 {
130 return result;
131 }
132
133 m_SpaceAllocated = true;
134 return result;
135 }
136
Unmap()137 void TransferMemoryBlock::Unmap()
138 {
139 if (GetAddress() != NULL)
140 {
141 if( m_SpaceAllocated )
142 {
143 nn::svc::UnmapMemoryBlock(GetHandle(), GetAddress());
144 detail::FreeToSharedMemorySpace(this);
145 }
146 else
147 {
148 SetAddressAndSize(0, 0);
149 }
150 }
151 }
152
153
154 }}
155
156 #endif // if NN_PLATFORM_HAS_MMU
157