mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-27 01:40:06 +00:00
Implemented SharedMemory Objects
This commit is contained in:
parent
f18ae9892a
commit
5f6fa13af6
@ -29,29 +29,70 @@ public:
|
|||||||
// TODO(bravia): ImplementMe
|
// TODO(bravia): ImplementMe
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void Read(T &var, const u32 addr);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void Write(T &var, const u32 addr);
|
||||||
|
|
||||||
|
u32 size;
|
||||||
|
u8* mem_ptr = NULL;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
SharedMemory* CreateSharedMemory(Handle& handle, u32 size) {
|
||||||
* 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* mem = new SharedMemory;
|
SharedMemory* mem = new SharedMemory;
|
||||||
handle = Kernel::g_object_pool.Create(mem);
|
handle = Kernel::g_object_pool.Create(mem);
|
||||||
|
mem->size = size;
|
||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Handle CreateSharedMemory(u32 size) {
|
||||||
Handle CreateSharedMemory() {
|
|
||||||
Handle handle;
|
Handle handle;
|
||||||
SharedMemory* mem = CreateSharedMemory(handle);
|
SharedMemory* mem = CreateSharedMemory(handle, size);
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 GetSharedMemorySize(Handle handle) {
|
||||||
|
SharedMemory* mem = Kernel::g_object_pool.GetFast<SharedMemory>(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<SharedMemory>(handle);
|
||||||
|
_assert_msg_(KERNEL, (mem != nullptr), "called, but mem is nullptr!");
|
||||||
|
mem->mem_ptr = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void ReadSharedMemory(Handle handle, T &var, const u32 addr) {
|
||||||
|
SharedMemory* mem = Kernel::g_object_pool.GetFast<SharedMemory>(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 <typename T>
|
||||||
|
inline void WriteSharedMemory(Handle handle, const T data, const u32 addr) {
|
||||||
|
SharedMemory* mem = Kernel::g_object_pool.GetFast<SharedMemory>(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<u64>(Handle handle, const u64 data, const u32 addr);
|
||||||
|
template void WriteSharedMemory<u32>(Handle handle, const u32 data, const u32 addr);
|
||||||
|
template void WriteSharedMemory<u16>(Handle handle, const u16 data, const u32 addr);
|
||||||
|
template void WriteSharedMemory<u8>(Handle handle, const u8 data, const u32 addr);
|
||||||
|
|
||||||
|
template void ReadSharedMemory<u64>(Handle handle, u64 &var, const u32 addr);
|
||||||
|
template void ReadSharedMemory<u32>(Handle handle, u32 &var, const u32 addr);
|
||||||
|
template void ReadSharedMemory<u16>(Handle handle, u16 &var, const u32 addr);
|
||||||
|
template void ReadSharedMemory<u8>(Handle handle, u8 &var, const u32 addr);
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -15,6 +15,16 @@ namespace Kernel {
|
|||||||
* @param handle Reference to handle for the newly created mutex
|
* @param handle Reference to handle for the newly created mutex
|
||||||
* @param
|
* @param
|
||||||
*/
|
*/
|
||||||
Handle CreateSharedMemory();
|
Handle CreateSharedMemory(u32 size);
|
||||||
|
|
||||||
|
u32 GetSharedMemorySize(Handle handle);
|
||||||
|
|
||||||
|
void SetSharedMemoryPointer(Handle handle, u8* ptr);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void ReadSharedMemory(Handle handle, T &var, const u32 addr);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void WriteSharedMemory(Handle handle, const T data, const u32 addr);
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "core/mem_map.h"
|
#include "core/mem_map.h"
|
||||||
#include "core/hle/hle.h"
|
#include "core/hle/hle.h"
|
||||||
#include "core/hle/kernel/event.h"
|
#include "core/hle/kernel/event.h"
|
||||||
|
#include "core/hle/kernel/shared_memory.h"
|
||||||
#include "core/hle/service/gsp.h"
|
#include "core/hle/service/gsp.h"
|
||||||
|
|
||||||
#include "core/hw/gpu.h"
|
#include "core/hw/gpu.h"
|
||||||
@ -20,6 +21,9 @@
|
|||||||
// Main graphics debugger object - TODO: Here is probably not the best place for this
|
// Main graphics debugger object - TODO: Here is probably not the best place for this
|
||||||
GraphicsDebugger g_debugger;
|
GraphicsDebugger g_debugger;
|
||||||
|
|
||||||
|
//Handle to irq memory
|
||||||
|
Handle memIRQ;
|
||||||
|
|
||||||
/// GSP shared memory GX command buffer header
|
/// GSP shared memory GX command buffer header
|
||||||
union GX_CmdBufferHeader {
|
union GX_CmdBufferHeader {
|
||||||
u32 hex;
|
u32 hex;
|
||||||
@ -121,7 +125,9 @@ void RegisterInterruptRelayQueue(Service::Interface* self) {
|
|||||||
Kernel::SetPermanentLock(event_handle, true);
|
Kernel::SetPermanentLock(event_handle, true);
|
||||||
|
|
||||||
cmd_buff[2] = g_thread_id; // ThreadID
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,10 +13,12 @@
|
|||||||
|
|
||||||
namespace HID_User {
|
namespace HID_User {
|
||||||
|
|
||||||
|
Handle memIPC;
|
||||||
|
|
||||||
void GetIPCHandles(Service::Interface* self) {
|
void GetIPCHandles(Service::Interface* self) {
|
||||||
u32* cmd_buff = Service::GetCommandBuffer();
|
u32* cmd_buff = Service::GetCommandBuffer();
|
||||||
Handle memHandle = Kernel::CreateSharedMemory();
|
memIPC = Kernel::CreateSharedMemory(0x1000); //page size for now
|
||||||
cmd_buff[3] = memHandle; //TODO: return something coherent along with RegisterInterruptRelayQueue for mem handles
|
cmd_buff[3] = memIPC; //TODO: return something coherent along with RegisterInterruptRelayQueue for mem handles
|
||||||
}
|
}
|
||||||
|
|
||||||
const Interface::FunctionInfo FunctionTable[] = {
|
const Interface::FunctionInfo FunctionTable[] = {
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#include "core/mem_map.h"
|
#include "core/mem_map.h"
|
||||||
#include "core/hw/hw.h"
|
#include "core/hw/hw.h"
|
||||||
#include "hle/hle.h"
|
#include "hle/hle.h"
|
||||||
|
#include "hle/kernel/kernel.h"
|
||||||
|
#include "hle/kernel/shared_memory.h"
|
||||||
#include "hle/config_mem.h"
|
#include "hle/config_mem.h"
|
||||||
|
|
||||||
namespace Memory {
|
namespace Memory {
|
||||||
@ -71,8 +73,15 @@ inline void _Read(T &var, const u32 addr) {
|
|||||||
|
|
||||||
// Shared memory
|
// Shared memory
|
||||||
} else if ((vaddr >= SHARED_MEMORY_VADDR) && (vaddr < SHARED_MEMORY_VADDR_END)) {
|
} else if ((vaddr >= SHARED_MEMORY_VADDR) && (vaddr < SHARED_MEMORY_VADDR_END)) {
|
||||||
var = *((const T*)&g_shared_mem[vaddr & SHARED_MEMORY_MASK]);
|
for (std::map<u32, MemoryBlock>::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<T>(handle, var, addr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ERROR_LOG(MEMMAP, "Read from unknown shared mapping : Read%d @ 0x%08X", sizeof(var) * 8, vaddr);
|
||||||
// System memory
|
// System memory
|
||||||
} else if ((vaddr >= SYSTEM_MEMORY_VADDR) && (vaddr < SYSTEM_MEMORY_VADDR_END)) {
|
} else if ((vaddr >= SYSTEM_MEMORY_VADDR) && (vaddr < SYSTEM_MEMORY_VADDR_END)) {
|
||||||
var = *((const T*)&g_system_mem[vaddr & SYSTEM_MEMORY_MASK]);
|
var = *((const T*)&g_system_mem[vaddr & SYSTEM_MEMORY_MASK]);
|
||||||
@ -117,6 +126,15 @@ inline void _Write(u32 addr, const T data) {
|
|||||||
|
|
||||||
// Shared memory
|
// Shared memory
|
||||||
} else if ((vaddr >= SHARED_MEMORY_VADDR) && (vaddr < SHARED_MEMORY_VADDR_END)) {
|
} else if ((vaddr >= SHARED_MEMORY_VADDR) && (vaddr < SHARED_MEMORY_VADDR_END)) {
|
||||||
|
for (std::map<u32, MemoryBlock>::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<T>(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;
|
*(T*)&g_shared_mem[vaddr & SHARED_MEMORY_MASK] = data;
|
||||||
|
|
||||||
// System memory
|
// System memory
|
||||||
@ -187,6 +205,7 @@ u32 MapBlock_Shared(u32 handle, u32 addr,u32 permissions) {
|
|||||||
MemoryBlock block;
|
MemoryBlock block;
|
||||||
|
|
||||||
block.handle = handle;
|
block.handle = handle;
|
||||||
|
block.size = Kernel::GetSharedMemorySize(handle);
|
||||||
block.base_address = addr;
|
block.base_address = addr;
|
||||||
block.permissions = permissions;
|
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;
|
const MemoryBlock last_block = g_shared_map.rbegin()->second;
|
||||||
block.address = last_block.address + last_block.size;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user