1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     os_StackMemoryBlock.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: 17558 $
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 "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     {
GetPageAlignedSize(size_t size)40         size_t GetPageAlignedSize(size_t size)
41         {
42             return (size + NN_OS_MEMORY_PAGE_SIZE - 1) & ~(NN_OS_MEMORY_PAGE_SIZE - 1);
43         }
44     }
45 
46     namespace detail
47     {
Switch(StackMemoryBlock * pTo,StackMemoryBlock * pFrom)48         void Switch(StackMemoryBlock* pTo, StackMemoryBlock* pFrom)
49         {
50             Switch( reinterpret_cast<MemoryBlock*>(pTo),
51                     reinterpret_cast<MemoryBlock*>(pFrom) );
52         }
53     }
54 
55 
56 // スタック領域からメモリブロックを確保します。
Initialize(size_t size)57 void StackMemoryBlock::Initialize(size_t size)
58 {
59     NN_TASSERT_(detail::IsMemoryBlockEnabled());
60     // 未初期化であることをチェックします。
61     NN_TASSERT_( GetAddress() == NULL );
62 
63     size = GetPageAlignedSize(size);
64 
65     // 仮想アドレス空間からメモリを取得します。
66     uptr addr = detail::AllocateFromMemoryBlockSpace(this, size);
67     if (addr == NULL)
68     {
69         NN_TPANIC_("failed to allocate address space.");
70     }
71 }
72 
Finalize()73 void StackMemoryBlock::Finalize()
74 {
75     if ( GetAddress() != NULL )
76     {
77         detail::FreeToMemoryBlockSpace(this);
78     }
79 }
80 
81 }} // namespace nn::os
82 
83 
84 #include <new>
85 using namespace nn::os;
86 
87 extern "C" {
88 
89 // StackMemoryBlock
90 
nnosStackMemoryBlockInitialize(nnosStackMemoryBlock * p)91 void nnosStackMemoryBlockInitialize(nnosStackMemoryBlock* p)
92 {
93     new (p) StackMemoryBlock();
94 }
95 
nnosStackMemoryBlockAllocate(nnosStackMemoryBlock * p,size_t size)96 void nnosStackMemoryBlockAllocate(nnosStackMemoryBlock* p, size_t size)
97 {
98     NN_TASSERT_(detail::IsMemoryBlockEnabled());
99     new (p) StackMemoryBlock(size);
100 }
101 
nnosStackMemoryBlockFree(nnosStackMemoryBlock * p)102 void nnosStackMemoryBlockFree(nnosStackMemoryBlock* p)
103 {
104     StackMemoryBlock* pStackMemoryBlock = reinterpret_cast<StackMemoryBlock*>(p);
105     pStackMemoryBlock->~StackMemoryBlock();
106 }
107 
nnosStackMemoryBlockGetAddress(nnosStackMemoryBlock * p)108 uptr nnosStackMemoryBlockGetAddress(nnosStackMemoryBlock* p)
109 {
110     StackMemoryBlock* pStackMemoryBlock = reinterpret_cast<StackMemoryBlock*>(p);
111     return pStackMemoryBlock->GetAddress();
112 }
113 
nnosStackMemoryBlockGetSize(nnosStackMemoryBlock * p)114 size_t nnosStackMemoryBlockGetSize(nnosStackMemoryBlock* p)
115 {
116     StackMemoryBlock* pStackMemoryBlock = reinterpret_cast<StackMemoryBlock*>(p);
117     return pStackMemoryBlock->GetSize();
118 }
119 
nnosStackMemoryBlockGetStackBottom(nnosStackMemoryBlock * p)120 uptr nnosStackMemoryBlockGetStackBottom(nnosStackMemoryBlock* p)
121 {
122     StackMemoryBlock* pStackMemoryBlock = reinterpret_cast<StackMemoryBlock*>(p);
123     return pStackMemoryBlock->GetStackBottom();
124 }
125 
126 }
127 #endif  // if NN_PLATFORM_HAS_MMU
128