diff --git a/Makefile.griffin b/Makefile.griffin index a0ad0f3201..715ef7a17d 100644 --- a/Makefile.griffin +++ b/Makefile.griffin @@ -212,7 +212,8 @@ else ifeq ($(platform), vita) WANT_ZLIB := 1 INCLUDE += -Ideps/libvita2d/include INCLUDE += -Ideps/zlib - PLATCFLAGS := -mthumb -mfloat-abi=hard -ffast-math -fsingle-precision-constant -mword-relocations + PLATCFLAGS := -mthumb -mfloat-abi=hard -fsingle-precision-constant \ + -mword-relocations -fno-unwind-tables -fno-asynchronous-unwind-tables -ftree-vectorize -funroll-loops LIBS += -lSceKernel_stub -lSceDisplay_stub -lSceGxm_stub -lSceNet_stub -lSceNetCtl_stub\ -lSceSysmodule_stub -lSceCtrl_stub -lSceAudio_stub -lSceFiber_stub\ -lScePower_stub -lSceRtc_stub -lSceCommonDialog_stub -lScePgf_stub \ diff --git a/bootstrap/vita/sbrk.c b/bootstrap/vita/sbrk.c new file mode 100644 index 0000000000..e960060b66 --- /dev/null +++ b/bootstrap/vita/sbrk.c @@ -0,0 +1,96 @@ +#include +#include + +static int _newlib_heap_memblock; +static unsigned _newlib_heap_size; +static char *_newlib_heap_base, *_newlib_heap_end, *_newlib_heap_cur; +static char _newlib_sbrk_mutex[32] __attribute__ ((aligned (8))); + +static int _newlib_vm_memblock; + +extern int _newlib_vm_size_user __attribute__((weak)); + +void * _sbrk_r(struct _reent *reent, ptrdiff_t incr) { + if (sceKernelLockLwMutex(_newlib_sbrk_mutex, 1, 0) < 0) + goto fail; + if (!_newlib_heap_base || _newlib_heap_cur + incr >= _newlib_heap_end) { + sceKernelUnlockLwMutex(_newlib_sbrk_mutex, 1); +fail: + reent->_errno = ENOMEM; + return -1; + } + + char *prev_heap_end = _newlib_heap_cur; + _newlib_heap_cur += incr; + + sceKernelUnlockLwMutex(_newlib_sbrk_mutex, 1); + return (void*) prev_heap_end; +} + +void _init_vita_heap(void) { + + int _newlib_vm_size = 0; + if (&_newlib_vm_size_user != NULL) { + _newlib_vm_size = _newlib_vm_size_user; + _newlib_vm_memblock = sceKernelAllocMemBlockForVM("code", _newlib_vm_size_user); + + if (_newlib_vm_memblock < 0){ + sceClibPrintf("sceKernelAllocMemBlockForVM failed\n"); + goto failure; + } + }else{ + _newlib_vm_memblock = 0; + } + + + // Create a mutex to use inside _sbrk_r + if (sceKernelCreateLwMutex(_newlib_sbrk_mutex, "sbrk mutex", 0, 0, 0) < 0) { + goto failure; + } + if (&_newlib_heap_size_user != NULL) { + _newlib_heap_size = _newlib_heap_size_user; + } else { + // Create a memblock for the heap memory, 32MB + _newlib_heap_size = 32 * 1024 * 1024; + } + + _newlib_heap_size -= _newlib_vm_size; + + _newlib_heap_memblock = sceKernelAllocMemBlock("Newlib heap", 0x0c20d060, _newlib_heap_size, 0); + if (_newlib_heap_memblock < 0) { + goto failure; + } + if (sceKernelGetMemBlockBase(_newlib_heap_memblock, &_newlib_heap_base) < 0) { + goto failure; + } + _newlib_heap_end = _newlib_heap_base + _newlib_heap_size; + _newlib_heap_cur = _newlib_heap_base; + + return; +failure: + _newlib_vm_memblock = 0; + _newlib_heap_memblock = 0; + _newlib_heap_base = 0; + _newlib_heap_cur = 0; +} + +int getVMBlock(){ + return _newlib_vm_memblock; +} + +void _free_vita_heap(void) { + + // Destroy the sbrk mutex + sceKernelDeleteLwMutex(_newlib_sbrk_mutex); + + // Free the heap memblock to avoid memory leakage. + sceKernelFreeMemBlock(_newlib_heap_memblock); + + if(_newlib_vm_memblock) + sceKernelFreeMemBlock(_newlib_vm_memblock); + + _newlib_vm_memblock = 0; + _newlib_heap_memblock = 0; + _newlib_heap_base = 0; + _newlib_heap_cur = 0; +} diff --git a/frontend/drivers/platform_psp.c b/frontend/drivers/platform_psp.c index 32ca741476..3574a9cf96 100644 --- a/frontend/drivers/platform_psp.c +++ b/frontend/drivers/platform_psp.c @@ -28,6 +28,11 @@ #include #include #include + +int _newlib_heap_size_user = 192 * 1024 * 1024; + +#include "../../bootstrap/vita/sbrk.c" + #else #include #include @@ -56,7 +61,6 @@ #ifdef VITA PSP2_MODULE_INFO(0, 0, "RetroArch"); -int _newlib_heap_size_user = 192 * 1024 * 1024; #else PSP_MODULE_INFO("RetroArch", 0, 1, 1); PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER|THREAD_ATTR_VFPU);