1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: init_Alloc.cpp
4 Copyright (C)2009 Nintendo Co., Ltd. All rights reserved.
5 These coded instructions, statements, and computer programs contain
6 proprietary information of Nintendo of America Inc. and/or Nintendo
7 Company Ltd., and are protected by Federal copyright law. They may
8 not be disclosed to third parties or copied or duplicated in any form,
9 in whole or in part, without the prior written consent of Nintendo.
10 $Rev: 20442 $
11 *---------------------------------------------------------------------------
12
13
14 */
15
16 //---------------------------------------------------------------------------
17
18 #include <new>
19 #include <nn/Result.h>
20 #include <nn/config.h>
21 #include <nn/assert.h>
22 #include <nn/fnd/fnd_ExpHeap.h>
23 #include <nn/init/init_Allocator.h>
24 #include <nn/os/os_LockPolicy.h>
25 #include <nn/os/os_Memory.h>
26 #include <nn/os/os_MemoryMapSelect.h>
27 #include <nn/os/os_CriticalSection.h>
28 #include <nn/svc/svc_stub.h>
29 #include <nn/util/util_Result.h>
30 #include <nn/util/util_TypeTraits.h>
31
32 using namespace nn::os;
33
34 typedef nn::fnd::ExpHeapTemplate<nn::os::LockPolicy::Object<nn::os::CriticalSection> > SystemExpHeap;
35
36 namespace
37 {
38 SystemExpHeap* s_pSystemHeap = 0; //
39 nn::util::aligned_storage<sizeof(SystemExpHeap::Allocator), nn::util::alignment_of<SystemExpHeap::Allocator>::value >::type s_SystemAllocatorBuffer;
40 SystemExpHeap::Allocator* s_pSystemAllocator = 0; //! Allocator for the system heap
41
42 #if NN_PLATFORM_HAS_MMU
43 nnosMemoryBlock s_HeapMemoryBlock;
44 #endif // if NN_PLATFORM_HAS_MMU
45 }
46
47 extern "C"{
48
49 // ABI override
malloc(size_t size)50 NN_WEAK_SYMBOL void* malloc(size_t size)
51 {
52 return s_pSystemHeap->Allocate(size);
53 }
54
55 // ABI override
free(void * p)56 NN_WEAK_SYMBOL void free(void* p)
57 {
58 if (p)
59 {
60 s_pSystemHeap->Free(p);
61 }
62 }
63
64 } // extern "C"
65
66
operator new(size_t size,const::std::nothrow_t &)67 NN_WEAK_SYMBOL void* operator new (size_t size, const ::std::nothrow_t&) throw()
68 {
69 return malloc(size);
70 }
71
operator new[](size_t size,const::std::nothrow_t &)72 NN_WEAK_SYMBOL void* operator new[] (size_t size, const ::std::nothrow_t&) throw()
73 {
74 return operator new(size, ::std::nothrow_t());
75 }
76
operator delete(void * p)77 NN_WEAK_SYMBOL void operator delete (void* p) throw()
78 {
79 free(p);
80 }
81
operator delete[](void * p)82 NN_WEAK_SYMBOL void operator delete[] (void* p) throw()
83 {
84 operator delete(p);
85 }
86
87 //NN_WEAK_SYMBOL void operator delete (void* p, const ::std::nothrow_t) throw()
88 //{
89 // if( p != 0 )
90 // {
91 // free(p);
92 // }
93 //}
94
95 //NN_WEAK_SYMBOL void operator delete[] (void* p, const ::std::nothrow_t) throw()
96 //{
97 // if( p != 0 )
98 // {
99 // free(p);
100 // }
101 //}
102
103 namespace nn { namespace init {
104
105 // Note
106 // Some functions around here are called from initStartup.
107 // Since initStartup is called before static initializer, if a static object of the non-POD class is initialized with a function here, the static initializer is reinitialized causing a malfunction.
108 //
109 //
110 // Implement with aligned_storage + placement new.
111
112 // Create system heap
InitializeAllocator(uptr addr,size_t size)113 void InitializeAllocator(uptr addr, size_t size)
114 {
115 NN_TASSERT_(size >= sizeof(SystemExpHeap));
116 const size_t alignment = nn::util::alignment_of<SystemExpHeap>::value;
117 uptr heapAddr = (((addr - 1) / alignment) + 1) * alignment;
118 uptr headAddr = heapAddr + sizeof(SystemExpHeap);
119 s_pSystemHeap = new (reinterpret_cast<void*>(heapAddr)) SystemExpHeap(headAddr, addr + size - headAddr);
120 s_pSystemAllocator = new (&s_SystemAllocatorBuffer) SystemExpHeap::Allocator(*s_pSystemHeap);
121 }
122
123 #if NN_PLATFORM_HAS_MMU
InitializeAllocator(size_t size)124 void InitializeAllocator(size_t size)
125 {
126 nnosMemoryBlockAllocate(&s_HeapMemoryBlock, size);
127 NN_TASSERT_(nnosMemoryBlockGetSize(&s_HeapMemoryBlock) == size);
128 InitializeAllocator(nnosMemoryBlockGetAddress(&s_HeapMemoryBlock), size);
129 }
130 #endif // if NN_PLATFORM_HAS_MMU
131
GetAllocator(void)132 nn::fnd::IAllocator* GetAllocator(void)
133 {
134 return s_pSystemAllocator;
135 }
136
137 }} // namespace nn::init
138
139