1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: os_StackMemoryBlock.cpp
4
5 Copyright (C)2009-2012 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: 46347 $
14 *---------------------------------------------------------------------------*/
15
16 #include <nn/config.h>
17 #if NN_PLATFORM_HAS_MMU
18
19 #include <nn/os/os_StackMemoryBlock.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 <nn/os/os_ErrorHandlerSelect.h>
30 #include "os_AddressSpaceManager.h"
31
32 //---------------------------------------------------------------------------
33
34 using namespace nn;
35 using namespace nn::svc;
36
37 namespace nn{ namespace os{
38
39 namespace
40 {
GetPageAlignedSize(size_t size)41 size_t GetPageAlignedSize(size_t size)
42 {
43 return (size + NN_OS_MEMORY_PAGE_SIZE - 1) & ~(NN_OS_MEMORY_PAGE_SIZE - 1);
44 }
45 }
46
47 namespace detail
48 {
Switch(StackMemoryBlock * pTo,StackMemoryBlock * pFrom)49 void Switch(StackMemoryBlock* pTo, StackMemoryBlock* pFrom)
50 {
51 Switch( reinterpret_cast<MemoryBlock*>(pTo),
52 reinterpret_cast<MemoryBlock*>(pFrom) );
53 }
54 }
55
56
57 // Allocate a memory block from the stack region.
Initialize(size_t size)58 void StackMemoryBlock::Initialize(size_t size)
59 {
60 // Check that the memory block has been initialized and that this instance is not initialized.
61 NN_TASSERTMSG_(os::detail::IsMemoryBlockEnabled(), "InitializeMemoryBlock is not called.\n");
62 NN_TASSERTMSG_(GetAddress() == 0, "This StackMemoryBlock instance has already been initialized.\n");
63 if ( !os::detail::IsMemoryBlockEnabled() || GetAddress() != 0 )
64 {
65 return;
66 }
67
68 size = GetPageAlignedSize(size);
69
70 // Get memory from the virtual address space.
71 uptr addr = os::detail::AllocateFromMemoryBlockSpace(this, size);
72 if (addr == NULL)
73 {
74 NN_OS_ERROR_IF_FAILED(ResultNoAddressSpace());
75 }
76 }
77
Finalize()78 void StackMemoryBlock::Finalize()
79 {
80 if ( GetAddress() != NULL )
81 {
82 os::detail::FreeToMemoryBlockSpace(this);
83 }
84 }
85
86 }} // namespace nn::os
87
88
89 #include <new>
90 using namespace nn::os;
91
92 extern "C" {
93
94 // StackMemoryBlock
95
nnosStackMemoryBlockInitialize(nnosStackMemoryBlock * p)96 void nnosStackMemoryBlockInitialize(nnosStackMemoryBlock* p)
97 {
98 new (p) StackMemoryBlock();
99 }
100
nnosStackMemoryBlockAllocate(nnosStackMemoryBlock * p,size_t size)101 void nnosStackMemoryBlockAllocate(nnosStackMemoryBlock* p, size_t size)
102 {
103 NN_TASSERT_(os::detail::IsMemoryBlockEnabled());
104 new (p) StackMemoryBlock(size);
105 }
106
nnosStackMemoryBlockFree(nnosStackMemoryBlock * p)107 void nnosStackMemoryBlockFree(nnosStackMemoryBlock* p)
108 {
109 StackMemoryBlock* pStackMemoryBlock = reinterpret_cast<StackMemoryBlock*>(p);
110 pStackMemoryBlock->~StackMemoryBlock();
111 }
112
nnosStackMemoryBlockGetAddress(nnosStackMemoryBlock * p)113 uptr nnosStackMemoryBlockGetAddress(nnosStackMemoryBlock* p)
114 {
115 StackMemoryBlock* pStackMemoryBlock = reinterpret_cast<StackMemoryBlock*>(p);
116 return pStackMemoryBlock->GetAddress();
117 }
118
nnosStackMemoryBlockGetSize(nnosStackMemoryBlock * p)119 size_t nnosStackMemoryBlockGetSize(nnosStackMemoryBlock* p)
120 {
121 StackMemoryBlock* pStackMemoryBlock = reinterpret_cast<StackMemoryBlock*>(p);
122 return pStackMemoryBlock->GetSize();
123 }
124
nnosStackMemoryBlockGetStackBottom(nnosStackMemoryBlock * p)125 uptr nnosStackMemoryBlockGetStackBottom(nnosStackMemoryBlock* p)
126 {
127 StackMemoryBlock* pStackMemoryBlock = reinterpret_cast<StackMemoryBlock*>(p);
128 return pStackMemoryBlock->GetStackBottom();
129 }
130
131 }
132 #endif // if NN_PLATFORM_HAS_MMU
133