]> Chaos Git - corbenik/ctrulib.git/commitdiff
Dynamically allocate shared memory.
authorSteven Smith <Steveice10@gmail.com>
Sat, 3 Oct 2015 23:33:48 +0000 (16:33 -0700)
committerSteven Smith <Steveice10@gmail.com>
Sun, 4 Oct 2015 15:03:23 +0000 (08:03 -0700)
libctru/include/3ds/mappable.h [new file with mode: 0644]
libctru/include/3ds/services/csnd.h
libctru/include/3ds/services/hid.h
libctru/include/3ds/services/irrst.h
libctru/source/allocator/mappable.cpp [new file with mode: 0644]
libctru/source/gfx.c
libctru/source/services/csnd.c
libctru/source/services/hid.c
libctru/source/services/irrst.c
libctru/source/system/appInit.c

diff --git a/libctru/include/3ds/mappable.h b/libctru/include/3ds/mappable.h
new file mode 100644 (file)
index 0000000..5df8c5e
--- /dev/null
@@ -0,0 +1,6 @@
+#pragma once
+
+// Functions for allocating/deallocating mappable memory
+void* mappableAlloc(size_t size); // returns a page-aligned address
+void mappableFree(void* mem);
+u32 mappableSpaceFree(); // get free mappable space in bytes
index e3258a04398ecf5de3a51ac78d639c6230a773b7..16ad2bef1fd5a69e0072b7e1246ba2fd83922936 100644 (file)
@@ -2,7 +2,6 @@
 #include <3ds/types.h>
 
 #define CSND_NUM_CHANNELS 32
-#define CSND_SHAREDMEM_DEFAULT 0x10004000
 
 #define CSND_TIMER(n) (0x3FEC3FC / ((u32)(n)))
 
index 87a99cf9c745f8ae35dadde4360c3105e138ff8d..dafc009810710498d24ac9e7de96d3e02b636aaf 100644 (file)
@@ -2,8 +2,6 @@
 
 //See also: http://3dbrew.org/wiki/HID_Services http://3dbrew.org/wiki/HID_Shared_Memory
 
-#define HID_SHAREDMEM_DEFAULT (0x10000000)
-
 typedef enum
 {
        KEY_A       = BIT(0),
@@ -75,7 +73,7 @@ typedef enum
 extern Handle hidMemHandle;
 extern vu32* hidSharedMem;
 
-Result hidInit(u32* sharedMem);
+Result hidInit();
 void hidExit();
 
 void hidScanInput();
index 2390eb4b07c2db0e7f49a1f3894dba15d3d606f7..cf2085e3741de894c59206631aacb0b61fb2e905 100644 (file)
@@ -4,12 +4,10 @@
 
 #include "3ds/services/hid.h" // for circlePosition definition
 
-#define IRRST_SHAREDMEM_DEFAULT (0x1000A000)
-
 extern Handle irrstMemHandle;
 extern vu32* irrstSharedMem;
 
-Result irrstInit(u32* sharedMem);
+Result irrstInit();
 void irrstExit();
 
 void irrstScanInput();
diff --git a/libctru/source/allocator/mappable.cpp b/libctru/source/allocator/mappable.cpp
new file mode 100644 (file)
index 0000000..f0c7ba5
--- /dev/null
@@ -0,0 +1,61 @@
+extern "C"
+{
+       #include <3ds/types.h>
+       #include <3ds/mappable.h>
+       #include <3ds/util/rbtree.h>
+}
+
+#include "mem_pool.h"
+#include "addrmap.h"
+
+static MemPool sMappablePool;
+
+static bool mappableInit()
+{
+       auto blk = MemBlock::Create((u8*)0x10000000, 0x04000000);
+       if (blk)
+       {
+               sMappablePool.AddBlock(blk);
+               rbtree_init(&sAddrMap, addrMapNodeComparator);
+               return true;
+       }
+       return false;
+}
+
+void* mappableAlloc(size_t size)
+{
+       // Initialize the pool if it is not ready
+       if (!sMappablePool.Ready() && !mappableInit())
+               return nullptr;
+
+       // Allocate the chunk
+       MemChunk chunk;
+       if (!sMappablePool.Allocate(chunk, size, 12))
+               return nullptr;
+
+       auto node = newNode(chunk);
+       if (!node)
+       {
+               sMappablePool.Deallocate(chunk);
+               return nullptr;
+       }
+       if (rbtree_insert(&sAddrMap, &node->node));
+       return chunk.addr;
+}
+
+void mappableFree(void* mem)
+{
+       auto node = getNode(mem);
+       if (!node) return;
+
+       // Free the chunk
+       sMappablePool.Deallocate(node->chunk);
+
+       // Free the node
+       delNode(node);
+}
+
+u32 mappableSpaceFree()
+{
+       return sMappablePool.GetFreeSpace();
+}
index 06888048a414b2fb6cb7bb2518a5c64c0fceaa07..f0b68a378364929c08555ce1c8e5661740d2056a 100644 (file)
@@ -5,6 +5,7 @@
 #include <3ds/gfx.h>
 #include <3ds/svc.h>
 #include <3ds/linear.h>
+#include <3ds/mappable.h>
 #include <3ds/vram.h>
 
 GSP_FramebufferInfo topFramebufferInfo, bottomFramebufferInfo;
@@ -116,7 +117,7 @@ void gfxInit(GSP_FramebufferFormats topFormat, GSP_FramebufferFormats bottomForm
 
        gspInit();
 
-       gfxSharedMemory=(u8*)0x10002000;
+       gfxSharedMemory=(u8*)mappableAlloc(0x1000);
 
        GSPGPU_AcquireRight(NULL, 0x0);
 
@@ -191,6 +192,12 @@ void gfxExit()
        GSPGPU_UnregisterInterruptRelayQueue(NULL);
 
        svcCloseHandle(gspSharedMemHandle);
+       if(gfxSharedMemory != NULL)
+       {
+               mappableFree(gfxSharedMemory);
+               gfxSharedMemory = NULL;
+       }
+
        svcCloseHandle(gspEvent);
 
        GSPGPU_ReleaseRight(NULL);
index d034237490a27b21fb075c75854d2c52b61e0674..283206247c3b71a97a22e2cea144ca375df01ee7 100644 (file)
@@ -3,6 +3,7 @@
 #include <3ds/types.h>
 #include <3ds/svc.h>
 #include <3ds/srv.h>
+#include <3ds/mappable.h>
 #include <3ds/os.h>
 #include <3ds/services/csnd.h>
 
@@ -118,7 +119,6 @@ Result CSND_Reset(void)
 Result csndInit(void)
 {
        Result ret=0;
-       csndSharedMem = (vu32*)CSND_SHAREDMEM_DEFAULT;
 
        // TODO: proper error handling!
 
@@ -133,17 +133,33 @@ Result csndInit(void)
        csndSharedMemSize = csndOffsets[3] + 0x3C;                 // Total size of the CSND shared memory
 
        ret = CSND_Initialize();
-       if (ret != 0) return ret;
+       if (ret != 0) goto cleanup1;
+
+       csndSharedMem = (vu32*)mappableAlloc(csndSharedMemSize);
+       if(!csndSharedMem)
+       {
+               ret = -1;
+               goto cleanup1;
+       }
 
        ret = svcMapMemoryBlock(csndSharedMemBlock, (u32)csndSharedMem, 3, 0x10000000);
-       if (ret != 0) return ret;
+       if (ret != 0) goto cleanup2;
 
        memset((void*)csndSharedMem, 0, csndSharedMemSize);
 
        ret = CSND_AcquireSoundChannels(&csndChannels);
-       if (ret != 0) return ret;
+       if (!ret) return 0;
 
-       return 0;
+cleanup2:
+       svcCloseHandle(csndSharedMemBlock);
+       if(csndSharedMem != NULL)
+       {
+               mappableFree((void*) csndSharedMem);
+               csndSharedMem = NULL;
+       }
+cleanup1:
+       svcCloseHandle(csndHandle);
+       return ret;
 }
 
 Result csndExit(void)
@@ -161,6 +177,13 @@ Result csndExit(void)
 
        ret = CSND_Shutdown();
        svcCloseHandle(csndHandle);
+       
+       if(csndSharedMem != NULL)
+       {
+               mappableFree((void*) csndSharedMem);
+               csndSharedMem = NULL;
+       }
+
        return ret;
 }
 
index 7eeb29d2a7b786d251805fbbf508b65099418850..1be6050228023d31a23ae0977867363fe57ac278 100644 (file)
@@ -6,6 +6,7 @@
 #include <3ds/types.h>
 #include <3ds/svc.h>
 #include <3ds/srv.h>
+#include <3ds/mappable.h>
 #include <3ds/services/apt.h>
 #include <3ds/services/hid.h>
 #include <3ds/services/irrst.h>
@@ -25,30 +26,34 @@ static angularRate gRate;
 
 static bool hidInitialised;
 
-Result hidInit(u32* sharedMem)
+Result hidInit()
 {
        u8 val=0;
        Result ret=0;
 
        if(hidInitialised) return ret;
 
-       if(!sharedMem)sharedMem=(u32*)HID_SHAREDMEM_DEFAULT;
-
        // Request service.
        if((ret=srvGetServiceHandle(&hidHandle, "hid:USER")) && (ret=srvGetServiceHandle(&hidHandle, "hid:SPVR")))return ret;
 
        // Get sharedmem handle.
        if((ret=HIDUSER_GetHandles(&hidMemHandle, &hidEvents[HIDEVENT_PAD0], &hidEvents[HIDEVENT_PAD1], &hidEvents[HIDEVENT_Accel], &hidEvents[HIDEVENT_Gyro], &hidEvents[HIDEVENT_DebugPad]))) goto cleanup1;
 
-       // Map HID shared memory at addr "sharedMem".
-       hidSharedMem=sharedMem;
+       // Map HID shared memory.
+       hidSharedMem=(vu32*)mappableAlloc(0x2b0);
+       if(!hidSharedMem)
+       {
+               ret = -1;
+               goto cleanup1;
+       }
+
        if((ret=svcMapMemoryBlock(hidMemHandle, (u32)hidSharedMem, MEMPERM_READ, 0x10000000)))goto cleanup2;
 
        APT_CheckNew3DS(NULL, &val);
 
        if(val)
        {
-               ret = irrstInit(NULL);
+               ret = irrstInit();
        }
 
        // Reset internal state.
@@ -58,6 +63,11 @@ Result hidInit(u32* sharedMem)
 
 cleanup2:
        svcCloseHandle(hidMemHandle);
+       if(hidSharedMem != NULL)
+       {
+               mappableFree((void*) hidSharedMem);
+               hidSharedMem = NULL;
+       }
 cleanup1:
        svcCloseHandle(hidHandle);
        return ret;
@@ -80,6 +90,12 @@ void hidExit()
        {
                irrstExit();
        }
+
+       if(hidSharedMem != NULL)
+       {
+               mappableFree((void*) hidSharedMem);
+               hidSharedMem = NULL;
+       }
        
        hidInitialised = false;
 }
index 14abbcbd014b31f7b44191f8f9f0ed0b7bfef5f3..083d2a67ce227896e0b3612ee8b68309c6e59674 100644 (file)
@@ -6,6 +6,7 @@
 #include <3ds/types.h>
 #include <3ds/svc.h>
 #include <3ds/srv.h>
+#include <3ds/mappable.h>
 #include <3ds/services/irrst.h>
 
 // used to determine whether or not we should do IRRST_Initialize
@@ -21,11 +22,10 @@ static u32 kHeld;
 static circlePosition csPos;
 static bool irrstUsed = false;
 
-Result irrstInit(u32* sharedMem)
+Result irrstInit()
 {
        if(irrstUsed)return 0;
 
-       if(!sharedMem)sharedMem=(u32*)IRRST_SHAREDMEM_DEFAULT;
        Result ret=0;
 
        // Request service.
@@ -37,8 +37,14 @@ Result irrstInit(u32* sharedMem)
        // Initialize ir:rst
        if(__get_handle_from_list("ir:rst")==0)ret=IRRST_Initialize(10, 0);
 
-       // Map ir:rst shared memory at addr "sharedMem".
-       irrstSharedMem=sharedMem;
+       // Map ir:rst shared memory.
+       irrstSharedMem=(vu32*)mappableAlloc(0x98);
+       if(!irrstSharedMem)
+       {
+               ret = -1;
+               goto cleanup1;
+       }
+
        if((ret=svcMapMemoryBlock(irrstMemHandle, (u32)irrstSharedMem, MEMPERM_READ, 0x10000000)))goto cleanup2;
 
        // Reset internal state.
@@ -48,6 +54,11 @@ Result irrstInit(u32* sharedMem)
 
 cleanup2:
        svcCloseHandle(irrstMemHandle);
+       if(irrstSharedMem != NULL)
+       {
+               mappableFree((void*) irrstSharedMem);
+               irrstSharedMem = NULL;
+       }
 cleanup1:
        svcCloseHandle(irrstHandle);
        return ret;
@@ -64,6 +75,12 @@ void irrstExit()
        if(__get_handle_from_list("ir:rst")==0) IRRST_Shutdown();
        svcCloseHandle(irrstMemHandle);
        svcCloseHandle(irrstHandle);
+
+       if(irrstSharedMem != NULL)
+       {
+               mappableFree((void*) irrstSharedMem);
+               irrstSharedMem = NULL;
+       }
 }
 
 void irrstWaitForEvent(bool nextEvent)
index ac90ae653bff049e4907a4ef1b9fe888742939cd..c3213e05aa7e8d81d7a2955bfa46a6f2cca50de2 100644 (file)
@@ -10,7 +10,7 @@ void __attribute__((weak)) __appInit() {
        // Initialize services
        srvInit();
        aptInit();
-       hidInit(NULL);
+       hidInit();
 
        fsInit();
        sdmcInit();