]> Chaos Git - corbenik/ctrulib.git/commitdiff
Refactor linear heap code (formerly known as GSP heap)
authorfincs <fincs.alt1@gmail.com>
Wed, 27 Aug 2014 21:44:38 +0000 (23:44 +0200)
committerfincs <fincs.alt1@gmail.com>
Wed, 27 Aug 2014 21:44:38 +0000 (23:44 +0200)
examples/gpu/source/main.c
libctru/include/3ds.h
libctru/include/3ds/gfx.h
libctru/include/3ds/linear.h [new file with mode: 0644]
libctru/source/gfx.c
libctru/source/initSystem.c
libctru/source/linear.c [new file with mode: 0644]
libctru/source/services/gsp.c

index 40c46e04e9e1b9c894961b94f0196ac843882022..97d0ff40991e096e65e50e351eef72d5afec6df5 100644 (file)
@@ -161,12 +161,12 @@ int main()
        GPU_Init(NULL);
 
        u32 gpuCmdSize=0x40000;
-       u32* gpuCmd=(u32*)gfxAllocLinear(gpuCmdSize*4);
+       u32* gpuCmd=(u32*)linearAlloc(gpuCmdSize*4);
 
        GPU_Reset(gxCmdBuf, gpuCmd, gpuCmdSize);
 
-       vertArray=(float*)gfxAllocLinear(0x100000);
-       texData=(u32*)gfxAllocLinear(0x100000);
+       vertArray=(float*)linearAlloc(0x100000);
+       texData=(u32*)linearAlloc(0x100000);
 
        memcpy(texData, test_png_bin, test_png_bin_size);
        memcpy(vertArray, mdlData, sizeof(mdlData));
index 6628e69d113f75c79712ac8850cf171f6675df9c..f2a9367417971396282edad392bb958e1ca381b6 100644 (file)
@@ -8,6 +8,7 @@ extern "C" {
 #include <3ds/types.h>
 #include <3ds/svc.h>
 #include <3ds/srv.h>
+#include <3ds/linear.h>
 #include <3ds/os.h>
 #include <3ds/gfx.h>
 
index 27923a935bacc2e8201cc170ee49e1c73eea076e..a0533c6beb3d98223a8c8e9fb7fbcdacc3f3a6c6 100644 (file)
@@ -26,7 +26,6 @@ void gfxSwapBuffersGpu();
 
 //helper stuff
 u8* gfxGetFramebuffer(gfxScreen_t screen, gfx3dSide_t side, u16* width, u16* height);
-void* gfxAllocLinear(size_t size);
 
 //global variables
 extern u8* gfxTopLeftFramebuffers[2];
diff --git a/libctru/include/3ds/linear.h b/libctru/include/3ds/linear.h
new file mode 100644 (file)
index 0000000..f42a8b9
--- /dev/null
@@ -0,0 +1,6 @@
+#pragma once
+
+// Functions for allocating/deallocating memory from linear heap
+void* linearAlloc(size_t size);
+void* linearRealloc(void* mem, size_t size);
+void linearFree(void* mem);
index 0f7596ba3ac8a5f12019d78615a685ecb0a580ba..8c8b79b5a07e84a91f95d25016d591c4502cda5e 100644 (file)
@@ -17,25 +17,7 @@ bool enable3d;
 
 Handle gspEvent, gspSharedMemHandle;
 
-u8* gspHeap;
 u32* gxCmdBuf;
-extern u32 __gsp_heap_size;
-
-// TODO: this function is not thread-safe and you cannot 'free' this memory.
-void* gfxAllocLinear(size_t size)
-{
-    static size_t currentOffset = 0;
-    size_t free = __gsp_heap_size - currentOffset;
-
-    if(free >= size)
-    {
-        currentOffset += size;
-        return (void*) &gspHeap[currentOffset - size];
-    }
-
-    return NULL;
-}
-
 
 void gfxSet3D(bool enable)
 {
@@ -90,9 +72,6 @@ void gfxInit()
        GSPGPU_RegisterInterruptRelayQueue(NULL, gspEvent, 0x1, &gspSharedMemHandle, &gfxThreadID);
        svcMapMemoryBlock(gspSharedMemHandle, (u32)gfxSharedMemory, 0x3, 0x10000000);
 
-       //map GSP heap
-       svcControlMemory((u32*)&gspHeap, 0x0, 0x0, __gsp_heap_size, 0x10003, 0x3);
-
        // default gspHeap configuration :
        //              topleft1  0x00000000-0x00046500
        //              topleft2  0x00046500-0x0008CA00
@@ -102,12 +81,12 @@ void gfxInit()
        //              topright1 0x000FD200-0x00143700
        //              topright2 0x00143700-0x00189C00
 
-       gfxTopLeftFramebuffers[0]=gfxAllocLinear(0x46500);
-       gfxTopLeftFramebuffers[1]=gfxAllocLinear(0x46500);
-       gfxBottomFramebuffers[0]=gfxAllocLinear(0x38400);
-       gfxBottomFramebuffers[1]=gfxAllocLinear(0x38400);
-       gfxTopRightFramebuffers[0]=gfxAllocLinear(0x46500);
-       gfxTopRightFramebuffers[1]=gfxAllocLinear(0x46500);
+       gfxTopLeftFramebuffers[0]=linearAlloc(0x46500);
+       gfxTopLeftFramebuffers[1]=linearAlloc(0x46500);
+       gfxBottomFramebuffers[0]=linearAlloc(0x38400);
+       gfxBottomFramebuffers[1]=linearAlloc(0x38400);
+       gfxTopRightFramebuffers[0]=linearAlloc(0x46500);
+       gfxTopRightFramebuffers[1]=linearAlloc(0x46500);
        enable3d=false;
 
        //initialize framebuffer info structures
@@ -129,8 +108,13 @@ void gfxExit()
        // Exit event handler
        gspExitEventHandler();
 
-       //free GSP heap
-       svcControlMemory((u32*)&gspHeap, (u32)gspHeap, 0x0, __gsp_heap_size, MEMOP_FREE, 0x0);
+       // Free framebuffers (let's pretend linearFree is actually implemented...)
+       linearFree(gfxTopRightFramebuffers[1]);
+       linearFree(gfxTopRightFramebuffers[0]);
+       linearFree(gfxBottomFramebuffers[1]);
+       linearFree(gfxBottomFramebuffers[0]);
+       linearFree(gfxTopLeftFramebuffers[1]);
+       linearFree(gfxTopLeftFramebuffers[0]);
 
        //unmap GSP shared mem
        svcUnmapMemoryBlock(gspSharedMemHandle, 0x10002000);
index b1ad1468c412273566f15a8b372aeb28f8f4be89..0179a7d5371aa72c82c3463f01d070b9f58bfc00 100644 (file)
@@ -6,10 +6,11 @@
 int __system_argc;
 char** __system_argv;
 void (*__system_retAddr)(void);
+u32 __linear_heap;
 
 // Data from _prm structure
 extern void* __service_ptr; // used to detect if we're run from a homebrew launcher
-extern u32 __heap_size;
+extern u32 __heap_size, __linear_heap_size;
 extern const char* __system_arglist;
 
 // newlib definitions we need
@@ -27,7 +28,10 @@ void __attribute__((noreturn)) __ctru_exit(int rc)
 
        // TODO: APT exit goes here
 
-       // Unmap the heap
+       // Unmap the linear heap
+       svcControlMemory(&__linear_heap, __linear_heap, 0x0, __linear_heap_size, MEMOP_FREE, 0x0);
+
+       // Unmap the application heap
        svcControlMemory(&heapBase, heapBase, 0x0, __heap_size, MEMOP_FREE, 0x0);
 
        // Jump to the loader if it provided a callback
@@ -48,6 +52,9 @@ void initSystem(void (*retAddr)(void))
        heapBase = 0x08000000;
        svcControlMemory(&heapBase, heapBase, 0x0, __heap_size, MEMOP_ALLOC, 0x3);
 
+       // Allocate the linear heap
+       svcControlMemory(&__linear_heap, 0x0, 0x0, __linear_heap_size, MEMOP_ALLOC_LINEAR, 0x3);
+
        // Set up newlib heap
        fake_heap_start = (char*)heapBase;
        fake_heap_end = fake_heap_start + __heap_size;
diff --git a/libctru/source/linear.c b/libctru/source/linear.c
new file mode 100644 (file)
index 0000000..ba78f40
--- /dev/null
@@ -0,0 +1,32 @@
+#include <3ds.h>
+
+extern u32 __linear_heap, __linear_heap_size;
+
+// TODO: this allocator sucks! It is not thread-safe and you cannot 'free' this memory.
+void* linearAlloc(size_t size)
+{
+    static size_t currentOffset = 0;
+    size_t free = __linear_heap_size - currentOffset;
+
+       // Enforce 8-byte alignment
+       size = (size + 7) &~ 7;
+
+       void* mem = NULL;
+    if (free >= size)
+    {
+               mem = (void*)(__linear_heap + currentOffset);
+        currentOffset += size;
+    }
+
+    return mem;
+}
+
+void* linearRealloc(void* mem, size_t size)
+{
+       return NULL; // TODO
+}
+
+void linearFree(void* mem)
+{
+       // TODO
+}
index d92d7ea01e891feb607aa8e542c131e7042ea5b3..f0f72d3c9dc9af562aeea9f099c46900d9f6f639 100644 (file)
@@ -358,7 +358,7 @@ Result GSPGPU_SubmitGxCommand(u32* sharedGspCmdBuf, u32 gxCommand[0x8], Handle*
        svcClearEvent(gspEvent);
 
        u32 cmdBufHeader;
-       __asm__ ("ldrex %[result], [%[adr]]" : [result] "=r" (cmdBufHeader) : [adr] "r" (sharedGspCmdBuf));
+       __asm__ __volatile__ ("ldrex %[result], [%[adr]]" : [result] "=r" (cmdBufHeader) : [adr] "r" (sharedGspCmdBuf));
 
        u8 commandIndex=cmdBufHeader&0xFF;
        u8 totalCommands=(cmdBufHeader>>8)&0xFF;
@@ -370,17 +370,17 @@ Result GSPGPU_SubmitGxCommand(u32* sharedGspCmdBuf, u32 gxCommand[0x8], Handle*
        memcpy(dst, gxCommand, 0x20);
 
        u32 mcrVal=0x0;
-       __asm__ ("mcr p15, 0, %[val], c7, c10, 4" :: [val] "r" (mcrVal)); //Data Synchronization Barrier Register
+       __asm__ __volatile__ ("mcr p15, 0, %[val], c7, c10, 4" :: [val] "r" (mcrVal)); //Data Synchronization Barrier Register
        totalCommands++;
        cmdBufHeader=((cmdBufHeader)&0xFFFF00FF)|(((u32)totalCommands)<<8);
 
        while(1)
        {
                u32 strexResult;
-               __asm__ ("strex %[result], %[val], [%[adr]]" : [result] "=&r" (strexResult) : [adr] "r" (sharedGspCmdBuf), [val] "r" (cmdBufHeader));
+               __asm__ __volatile__ ("strex %[result], %[val], [%[adr]]" : [result] "=&r" (strexResult) : [adr] "r" (sharedGspCmdBuf), [val] "r" (cmdBufHeader));
                if(!strexResult)break;
 
-               __asm__ ("ldrex %[result], [%[adr]]" : [result] "=r" (cmdBufHeader) : [adr] "r" (sharedGspCmdBuf));
+               __asm__ __volatile__ ("ldrex %[result], [%[adr]]" : [result] "=r" (cmdBufHeader) : [adr] "r" (sharedGspCmdBuf));
                totalCommands=((cmdBufHeader&0xFF00)>>8)+1;
                cmdBufHeader=((cmdBufHeader)&0xFFFF00FF)|((totalCommands<<8)&0xFF00);
        }