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