diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index 9824d55ac..66594f0fc 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -29,29 +29,70 @@ public: // TODO(bravia): ImplementMe return 0; } + + template + inline void Read(T &var, const u32 addr); + + template + inline void Write(T &var, const u32 addr); + + u32 size; + u8* mem_ptr = NULL; }; //////////////////////////////////////////////////////////////////////////////////////////////////// -/** -* Creates a mutex -* @param handle Reference to handle for the newly created mutex -* @param initial_locked Specifies if the mutex should be locked initially -*/ -SharedMemory* CreateSharedMemory(Handle& handle) { +SharedMemory* CreateSharedMemory(Handle& handle, u32 size) { SharedMemory* mem = new SharedMemory; handle = Kernel::g_object_pool.Create(mem); - + mem->size = size; return mem; } - -Handle CreateSharedMemory() { +Handle CreateSharedMemory(u32 size) { Handle handle; - SharedMemory* mem = CreateSharedMemory(handle); + SharedMemory* mem = CreateSharedMemory(handle, size); return handle; } +u32 GetSharedMemorySize(Handle handle) { + SharedMemory* mem = Kernel::g_object_pool.GetFast(handle); + _assert_msg_(KERNEL, (mem != nullptr), "called, but mem is nullptr!"); + return mem->size; +} + +void SetSharedMemoryPointer(Handle handle, u8* ptr) { + SharedMemory* mem = Kernel::g_object_pool.GetFast(handle); + _assert_msg_(KERNEL, (mem != nullptr), "called, but mem is nullptr!"); + mem->mem_ptr = ptr; +} + +template +inline void ReadSharedMemory(Handle handle, T &var, const u32 addr) { + SharedMemory* mem = Kernel::g_object_pool.GetFast(handle); + _assert_msg_(KERNEL, (mem != nullptr), "called, but mem is nullptr!"); + if (mem->mem_ptr!=NULL) + var = *((const T*)&mem->mem_ptr[addr & (mem->size - 1)]); +} + +template +inline void WriteSharedMemory(Handle handle, const T data, const u32 addr) { + SharedMemory* mem = Kernel::g_object_pool.GetFast(handle); + _assert_msg_(KERNEL, (mem != nullptr), "called, but mem is nullptr!"); + if (mem->mem_ptr != NULL) + *(T*)&mem->mem_ptr[addr & (mem->size - 1)] = data; +} + +template void WriteSharedMemory(Handle handle, const u64 data, const u32 addr); +template void WriteSharedMemory(Handle handle, const u32 data, const u32 addr); +template void WriteSharedMemory(Handle handle, const u16 data, const u32 addr); +template void WriteSharedMemory(Handle handle, const u8 data, const u32 addr); + +template void ReadSharedMemory(Handle handle, u64 &var, const u32 addr); +template void ReadSharedMemory(Handle handle, u32 &var, const u32 addr); +template void ReadSharedMemory(Handle handle, u16 &var, const u32 addr); +template void ReadSharedMemory(Handle handle, u8 &var, const u32 addr); + } // namespace diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index 993e0a856..85a39a337 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h @@ -15,6 +15,16 @@ namespace Kernel { * @param handle Reference to handle for the newly created mutex * @param */ -Handle CreateSharedMemory(); +Handle CreateSharedMemory(u32 size); + +u32 GetSharedMemorySize(Handle handle); + +void SetSharedMemoryPointer(Handle handle, u8* ptr); + +template +inline void ReadSharedMemory(Handle handle, T &var, const u32 addr); + +template +inline void WriteSharedMemory(Handle handle, const T data, const u32 addr); } // namespace diff --git a/src/core/hle/service/gsp.cpp b/src/core/hle/service/gsp.cpp index 3f0de3221..6999ce4b5 100644 --- a/src/core/hle/service/gsp.cpp +++ b/src/core/hle/service/gsp.cpp @@ -9,6 +9,7 @@ #include "core/mem_map.h" #include "core/hle/hle.h" #include "core/hle/kernel/event.h" +#include "core/hle/kernel/shared_memory.h" #include "core/hle/service/gsp.h" #include "core/hw/gpu.h" @@ -20,6 +21,9 @@ // Main graphics debugger object - TODO: Here is probably not the best place for this GraphicsDebugger g_debugger; +//Handle to irq memory +Handle memIRQ; + /// GSP shared memory GX command buffer header union GX_CmdBufferHeader { u32 hex; @@ -121,7 +125,9 @@ void RegisterInterruptRelayQueue(Service::Interface* self) { Kernel::SetPermanentLock(event_handle, true); cmd_buff[2] = g_thread_id; // ThreadID - //TODO(bravia): Implement shared memory handling + cmd_buff[3] = 0x0; //specified to be zero + memIRQ = Kernel::CreateSharedMemory(0x1000); //page size for now + cmd_buff[4] = memIRQ; } diff --git a/src/core/hle/service/hid.cpp b/src/core/hle/service/hid.cpp index c6ae64d50..fd2c6c80d 100644 --- a/src/core/hle/service/hid.cpp +++ b/src/core/hle/service/hid.cpp @@ -13,10 +13,12 @@ namespace HID_User { +Handle memIPC; + void GetIPCHandles(Service::Interface* self) { u32* cmd_buff = Service::GetCommandBuffer(); - Handle memHandle = Kernel::CreateSharedMemory(); - cmd_buff[3] = memHandle; //TODO: return something coherent along with RegisterInterruptRelayQueue for mem handles + memIPC = Kernel::CreateSharedMemory(0x1000); //page size for now + cmd_buff[3] = memIPC; //TODO: return something coherent along with RegisterInterruptRelayQueue for mem handles } const Interface::FunctionInfo FunctionTable[] = { diff --git a/src/core/mem_map_funcs.cpp b/src/core/mem_map_funcs.cpp index ab014a596..e596e0984 100644 --- a/src/core/mem_map_funcs.cpp +++ b/src/core/mem_map_funcs.cpp @@ -9,6 +9,8 @@ #include "core/mem_map.h" #include "core/hw/hw.h" #include "hle/hle.h" +#include "hle/kernel/kernel.h" +#include "hle/kernel/shared_memory.h" #include "hle/config_mem.h" namespace Memory { @@ -71,8 +73,15 @@ inline void _Read(T &var, const u32 addr) { // Shared memory } else if ((vaddr >= SHARED_MEMORY_VADDR) && (vaddr < SHARED_MEMORY_VADDR_END)) { - var = *((const T*)&g_shared_mem[vaddr & SHARED_MEMORY_MASK]); - + for (std::map::iterator it = g_shared_map.begin(); it != g_shared_map.end(); it++) { + MemoryBlock block = it->second; + if ((vaddr >= block.base_address) && (vaddr < block.GetVirtualAddress())) { + Handle handle = block.handle; + Kernel::ReadSharedMemory(handle, var, addr); + return; + } + } + ERROR_LOG(MEMMAP, "Read from unknown shared mapping : Read%d @ 0x%08X", sizeof(var) * 8, vaddr); // System memory } else if ((vaddr >= SYSTEM_MEMORY_VADDR) && (vaddr < SYSTEM_MEMORY_VADDR_END)) { var = *((const T*)&g_system_mem[vaddr & SYSTEM_MEMORY_MASK]); @@ -117,6 +126,15 @@ inline void _Write(u32 addr, const T data) { // Shared memory } else if ((vaddr >= SHARED_MEMORY_VADDR) && (vaddr < SHARED_MEMORY_VADDR_END)) { + for (std::map::iterator it = g_shared_map.begin(); it != g_shared_map.end(); it++) { + MemoryBlock block = it->second; + if ((vaddr >= block.base_address) && (vaddr < block.GetVirtualAddress())) { + Handle handle = block.handle; + Kernel::WriteSharedMemory(handle, data, addr); + return; + } + } + ERROR_LOG(MEMMAP, "Write to unknown shared mapping : Write%d 0x%08X @ 0x%08X", sizeof(data) * 8, data, vaddr); *(T*)&g_shared_mem[vaddr & SHARED_MEMORY_MASK] = data; // System memory @@ -185,8 +203,9 @@ u8 *GetPointer(const u32 addr) { */ u32 MapBlock_Shared(u32 handle, u32 addr,u32 permissions) { MemoryBlock block; - + block.handle = handle; + block.size = Kernel::GetSharedMemorySize(handle); block.base_address = addr; block.permissions = permissions; @@ -194,9 +213,14 @@ u32 MapBlock_Shared(u32 handle, u32 addr,u32 permissions) { const MemoryBlock last_block = g_shared_map.rbegin()->second; block.address = last_block.address + last_block.size; } - g_shared_map[block.GetVirtualAddress()] = block; - return block.GetVirtualAddress(); + u32 vaddr = block.GetVirtualAddress(); + + g_shared_map[vaddr] = block; + + Kernel::SetSharedMemoryPointer(handle, &g_shared_mem[vaddr & SHARED_MEMORY_MASK]); + + return vaddr; } /**