mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-26 23:30:09 +00:00
Implemented SharedMemory Objects
This commit is contained in:
parent
f18ae9892a
commit
5f6fa13af6
@ -29,29 +29,70 @@ public:
|
||||
// TODO(bravia): ImplementMe
|
||||
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;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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<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
|
||||
|
@ -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 <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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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[] = {
|
||||
|
@ -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<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
|
||||
} 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<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;
|
||||
|
||||
// System memory
|
||||
@ -187,6 +205,7 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user