mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-25 18:10:14 +00:00
Kernel: Capture SharedMemory attributes at creation, not when mapping
This commit is contained in:
parent
088f6ae2c6
commit
c96f22490a
@ -12,11 +12,15 @@ namespace Kernel {
|
|||||||
SharedMemory::SharedMemory() {}
|
SharedMemory::SharedMemory() {}
|
||||||
SharedMemory::~SharedMemory() {}
|
SharedMemory::~SharedMemory() {}
|
||||||
|
|
||||||
SharedPtr<SharedMemory> SharedMemory::Create(std::string name) {
|
SharedPtr<SharedMemory> SharedMemory::Create(u32 size, MemoryPermission permissions,
|
||||||
|
MemoryPermission other_permissions, std::string name) {
|
||||||
SharedPtr<SharedMemory> shared_memory(new SharedMemory);
|
SharedPtr<SharedMemory> shared_memory(new SharedMemory);
|
||||||
|
|
||||||
shared_memory->name = std::move(name);
|
shared_memory->name = std::move(name);
|
||||||
shared_memory->base_address = 0x0;
|
shared_memory->base_address = 0x0;
|
||||||
|
shared_memory->size = size;
|
||||||
|
shared_memory->permissions = permissions;
|
||||||
|
shared_memory->other_permissions = other_permissions;
|
||||||
|
|
||||||
return shared_memory;
|
return shared_memory;
|
||||||
}
|
}
|
||||||
@ -24,7 +28,7 @@ SharedPtr<SharedMemory> SharedMemory::Create(std::string name) {
|
|||||||
ResultCode SharedMemory::Map(VAddr address, MemoryPermission permissions,
|
ResultCode SharedMemory::Map(VAddr address, MemoryPermission permissions,
|
||||||
MemoryPermission other_permissions) {
|
MemoryPermission other_permissions) {
|
||||||
|
|
||||||
if (address < Memory::SHARED_MEMORY_VADDR || address >= Memory::SHARED_MEMORY_VADDR_END) {
|
if (address < Memory::SHARED_MEMORY_VADDR || address + size >= Memory::SHARED_MEMORY_VADDR_END) {
|
||||||
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X outside of shared mem bounds!",
|
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X outside of shared mem bounds!",
|
||||||
GetObjectId(), address);
|
GetObjectId(), address);
|
||||||
// TODO: Verify error code with hardware
|
// TODO: Verify error code with hardware
|
||||||
@ -32,21 +36,19 @@ ResultCode SharedMemory::Map(VAddr address, MemoryPermission permissions,
|
|||||||
ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
|
ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Test permissions
|
||||||
|
|
||||||
this->base_address = address;
|
this->base_address = address;
|
||||||
this->permissions = permissions;
|
|
||||||
this->other_permissions = other_permissions;
|
|
||||||
|
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<u8*> SharedMemory::GetPointer(u32 offset) {
|
u8* SharedMemory::GetPointer(u32 offset) {
|
||||||
if (base_address != 0)
|
if (base_address != 0)
|
||||||
return MakeResult<u8*>(Memory::GetPointer(base_address + offset));
|
return Memory::GetPointer(base_address + offset);
|
||||||
|
|
||||||
LOG_ERROR(Kernel_SVC, "memory block id=%u not mapped!", GetObjectId());
|
LOG_ERROR(Kernel_SVC, "memory block id=%u not mapped!", GetObjectId());
|
||||||
// TODO(yuriks): Verify error code.
|
return nullptr;
|
||||||
return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel,
|
|
||||||
ErrorSummary::InvalidState, ErrorLevel::Permanent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -27,11 +27,16 @@ class SharedMemory final : public Object {
|
|||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Creates a shared memory object
|
* Creates a shared memory object
|
||||||
* @param name Optional object name, used only for debugging purposes.
|
* @param size Size of the memory block. Must be page-aligned.
|
||||||
|
* @param permissions Permission restrictions applied to the process which created the block.
|
||||||
|
* @param other_permissions Permission restrictions applied to other processes mapping the block.
|
||||||
|
* @param name Optional object name, used for debugging purposes.
|
||||||
*/
|
*/
|
||||||
static SharedPtr<SharedMemory> Create(std::string name = "Unknown");
|
static SharedPtr<SharedMemory> Create(u32 size, MemoryPermission permissions,
|
||||||
|
MemoryPermission other_permissions, std::string name = "Unknown");
|
||||||
|
|
||||||
std::string GetTypeName() const override { return "SharedMemory"; }
|
std::string GetTypeName() const override { return "SharedMemory"; }
|
||||||
|
std::string GetName() const override { return name; }
|
||||||
|
|
||||||
static const HandleType HANDLE_TYPE = HandleType::SharedMemory;
|
static const HandleType HANDLE_TYPE = HandleType::SharedMemory;
|
||||||
HandleType GetHandleType() const override { return HANDLE_TYPE; }
|
HandleType GetHandleType() const override { return HANDLE_TYPE; }
|
||||||
@ -49,12 +54,18 @@ public:
|
|||||||
* @param offset Offset from the start of the shared memory block to get pointer
|
* @param offset Offset from the start of the shared memory block to get pointer
|
||||||
* @return Pointer to the shared memory block from the specified offset
|
* @return Pointer to the shared memory block from the specified offset
|
||||||
*/
|
*/
|
||||||
ResultVal<u8*> GetPointer(u32 offset = 0);
|
u8* GetPointer(u32 offset = 0);
|
||||||
|
|
||||||
VAddr base_address; ///< Address of shared memory block in RAM
|
/// Address of shared memory block in the process.
|
||||||
MemoryPermission permissions; ///< Permissions of shared memory block (SVC field)
|
VAddr base_address;
|
||||||
MemoryPermission other_permissions; ///< Other permissions of shared memory block (SVC field)
|
/// Size of the memory block. Page-aligned.
|
||||||
std::string name; ///< Name of shared memory object (optional)
|
u32 size;
|
||||||
|
/// Permission restrictions applied to the process which created the block.
|
||||||
|
MemoryPermission permissions;
|
||||||
|
/// Permission restrictions applied to other processes mapping the block.
|
||||||
|
MemoryPermission other_permissions;
|
||||||
|
/// Name of shared memory object.
|
||||||
|
std::string name;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SharedMemory();
|
SharedMemory();
|
||||||
|
@ -304,7 +304,9 @@ void Init() {
|
|||||||
file.ReadBytes(shared_font.data(), (size_t)file.GetSize());
|
file.ReadBytes(shared_font.data(), (size_t)file.GetSize());
|
||||||
|
|
||||||
// Create shared font memory object
|
// Create shared font memory object
|
||||||
shared_font_mem = Kernel::SharedMemory::Create("APT_U:shared_font_mem");
|
using Kernel::MemoryPermission;
|
||||||
|
shared_font_mem = Kernel::SharedMemory::Create(3 * 1024 * 1024, // 3MB
|
||||||
|
MemoryPermission::ReadWrite, MemoryPermission::Read, "APT_U:shared_font_mem");
|
||||||
} else {
|
} else {
|
||||||
LOG_WARNING(Service_APT, "Unable to load shared font: %s", filepath.c_str());
|
LOG_WARNING(Service_APT, "Unable to load shared font: %s", filepath.c_str());
|
||||||
shared_font_mem = nullptr;
|
shared_font_mem = nullptr;
|
||||||
|
@ -35,8 +35,7 @@ u32 g_thread_id = 1;
|
|||||||
|
|
||||||
/// Gets a pointer to a thread command buffer in GSP shared memory
|
/// Gets a pointer to a thread command buffer in GSP shared memory
|
||||||
static inline u8* GetCommandBuffer(u32 thread_id) {
|
static inline u8* GetCommandBuffer(u32 thread_id) {
|
||||||
ResultVal<u8*> ptr = g_shared_memory->GetPointer(0x800 + (thread_id * sizeof(CommandBuffer)));
|
return g_shared_memory->GetPointer(0x800 + (thread_id * sizeof(CommandBuffer)));
|
||||||
return ptr.ValueOr(nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline FrameBufferUpdate* GetFrameBufferInfo(u32 thread_id, u32 screen_index) {
|
static inline FrameBufferUpdate* GetFrameBufferInfo(u32 thread_id, u32 screen_index) {
|
||||||
@ -44,14 +43,14 @@ static inline FrameBufferUpdate* GetFrameBufferInfo(u32 thread_id, u32 screen_in
|
|||||||
|
|
||||||
// For each thread there are two FrameBufferUpdate fields
|
// For each thread there are two FrameBufferUpdate fields
|
||||||
u32 offset = 0x200 + (2 * thread_id + screen_index) * sizeof(FrameBufferUpdate);
|
u32 offset = 0x200 + (2 * thread_id + screen_index) * sizeof(FrameBufferUpdate);
|
||||||
ResultVal<u8*> ptr = g_shared_memory->GetPointer(offset);
|
u8* ptr = g_shared_memory->GetPointer(offset);
|
||||||
return reinterpret_cast<FrameBufferUpdate*>(ptr.ValueOr(nullptr));
|
return reinterpret_cast<FrameBufferUpdate*>(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a pointer to the interrupt relay queue for a given thread index
|
/// Gets a pointer to the interrupt relay queue for a given thread index
|
||||||
static inline InterruptRelayQueue* GetInterruptRelayQueue(u32 thread_id) {
|
static inline InterruptRelayQueue* GetInterruptRelayQueue(u32 thread_id) {
|
||||||
ResultVal<u8*> ptr = g_shared_memory->GetPointer(sizeof(InterruptRelayQueue) * thread_id);
|
u8* ptr = g_shared_memory->GetPointer(sizeof(InterruptRelayQueue) * thread_id);
|
||||||
return reinterpret_cast<InterruptRelayQueue*>(ptr.ValueOr(nullptr));
|
return reinterpret_cast<InterruptRelayQueue*>(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -288,7 +287,10 @@ static void RegisterInterruptRelayQueue(Service::Interface* self) {
|
|||||||
|
|
||||||
g_interrupt_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[3]);
|
g_interrupt_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[3]);
|
||||||
ASSERT_MSG((g_interrupt_event != nullptr), "handle is not valid!");
|
ASSERT_MSG((g_interrupt_event != nullptr), "handle is not valid!");
|
||||||
g_shared_memory = Kernel::SharedMemory::Create("GSPSharedMem");
|
|
||||||
|
using Kernel::MemoryPermission;
|
||||||
|
g_shared_memory = Kernel::SharedMemory::Create(0x1000, MemoryPermission::ReadWrite,
|
||||||
|
MemoryPermission::ReadWrite, "GSPSharedMem");
|
||||||
|
|
||||||
Handle shmem_handle = Kernel::g_handle_table.Create(g_shared_memory).MoveFrom();
|
Handle shmem_handle = Kernel::g_handle_table.Create(g_shared_memory).MoveFrom();
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ static u32 next_touch_index;
|
|||||||
// * Set PadData.current_state.circle_right = 1 if current PadEntry.circle_pad_y <= -41
|
// * Set PadData.current_state.circle_right = 1 if current PadEntry.circle_pad_y <= -41
|
||||||
|
|
||||||
void Update() {
|
void Update() {
|
||||||
SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer().ValueOr(nullptr));
|
SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer());
|
||||||
const PadState state = VideoCore::g_emu_window->GetPadState();
|
const PadState state = VideoCore::g_emu_window->GetPadState();
|
||||||
|
|
||||||
if (mem == nullptr) {
|
if (mem == nullptr) {
|
||||||
@ -163,7 +163,9 @@ void Init() {
|
|||||||
AddService(new HID_U_Interface);
|
AddService(new HID_U_Interface);
|
||||||
AddService(new HID_SPVR_Interface);
|
AddService(new HID_SPVR_Interface);
|
||||||
|
|
||||||
shared_mem = SharedMemory::Create("HID:SharedMem");
|
using Kernel::MemoryPermission;
|
||||||
|
shared_mem = SharedMemory::Create(0x1000, MemoryPermission::ReadWrite,
|
||||||
|
MemoryPermission::Read, "HID:SharedMem");
|
||||||
|
|
||||||
next_pad_index = 0;
|
next_pad_index = 0;
|
||||||
next_touch_index = 0;
|
next_touch_index = 0;
|
||||||
|
@ -34,7 +34,9 @@ void Init() {
|
|||||||
AddService(new IR_U_Interface);
|
AddService(new IR_U_Interface);
|
||||||
AddService(new IR_User_Interface);
|
AddService(new IR_User_Interface);
|
||||||
|
|
||||||
shared_memory = SharedMemory::Create("IR:SharedMemory");
|
using Kernel::MemoryPermission;
|
||||||
|
shared_memory = SharedMemory::Create(0x1000, Kernel::MemoryPermission::ReadWrite,
|
||||||
|
Kernel::MemoryPermission::ReadWrite, "IR:SharedMemory");
|
||||||
|
|
||||||
// Create event handle(s)
|
// Create event handle(s)
|
||||||
handle_event = Event::Create(RESETTYPE_ONESHOT, "IR:HandleEvent");
|
handle_event = Event::Create(RESETTYPE_ONESHOT, "IR:HandleEvent");
|
||||||
|
@ -601,7 +601,9 @@ static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32
|
|||||||
using Kernel::SharedMemory;
|
using Kernel::SharedMemory;
|
||||||
// TODO(Subv): Implement this function
|
// TODO(Subv): Implement this function
|
||||||
|
|
||||||
SharedPtr<SharedMemory> shared_memory = SharedMemory::Create();
|
using Kernel::MemoryPermission;
|
||||||
|
SharedPtr<SharedMemory> shared_memory = SharedMemory::Create(size,
|
||||||
|
(MemoryPermission)my_permission, (MemoryPermission)other_permission);
|
||||||
CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(shared_memory)));
|
CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(shared_memory)));
|
||||||
|
|
||||||
LOG_WARNING(Kernel_SVC, "(STUBBED) called addr=0x%08X", addr);
|
LOG_WARNING(Kernel_SVC, "(STUBBED) called addr=0x%08X", addr);
|
||||||
|
Loading…
Reference in New Issue
Block a user