diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/shared_memory.cpp | 28 | ||||
| -rw-r--r-- | src/core/hle/kernel/shared_memory.h | 25 | ||||
| -rw-r--r-- | src/core/hle/service/apt/apt.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/service/gsp_gpu.cpp | 30 | ||||
| -rw-r--r-- | src/core/hle/service/hid/hid.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/service/ir/ir.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/svc.cpp | 4 |
7 files changed, 67 insertions, 34 deletions
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index cb5c16696..0c59f4876 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <cstring> | ||
| 6 | |||
| 5 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 6 | 8 | ||
| 7 | #include "core/mem_map.h" | 9 | #include "core/mem_map.h" |
| @@ -12,11 +14,15 @@ namespace Kernel { | |||
| 12 | SharedMemory::SharedMemory() {} | 14 | SharedMemory::SharedMemory() {} |
| 13 | SharedMemory::~SharedMemory() {} | 15 | SharedMemory::~SharedMemory() {} |
| 14 | 16 | ||
| 15 | SharedPtr<SharedMemory> SharedMemory::Create(std::string name) { | 17 | SharedPtr<SharedMemory> SharedMemory::Create(u32 size, MemoryPermission permissions, |
| 18 | MemoryPermission other_permissions, std::string name) { | ||
| 16 | SharedPtr<SharedMemory> shared_memory(new SharedMemory); | 19 | SharedPtr<SharedMemory> shared_memory(new SharedMemory); |
| 17 | 20 | ||
| 18 | shared_memory->name = std::move(name); | 21 | shared_memory->name = std::move(name); |
| 19 | shared_memory->base_address = 0x0; | 22 | shared_memory->base_address = 0x0; |
| 23 | shared_memory->size = size; | ||
| 24 | shared_memory->permissions = permissions; | ||
| 25 | shared_memory->other_permissions = other_permissions; | ||
| 20 | 26 | ||
| 21 | return shared_memory; | 27 | return shared_memory; |
| 22 | } | 28 | } |
| @@ -24,7 +30,7 @@ SharedPtr<SharedMemory> SharedMemory::Create(std::string name) { | |||
| 24 | ResultCode SharedMemory::Map(VAddr address, MemoryPermission permissions, | 30 | ResultCode SharedMemory::Map(VAddr address, MemoryPermission permissions, |
| 25 | MemoryPermission other_permissions) { | 31 | MemoryPermission other_permissions) { |
| 26 | 32 | ||
| 27 | if (address < Memory::SHARED_MEMORY_VADDR || address >= Memory::SHARED_MEMORY_VADDR_END) { | 33 | if (address < Memory::SHARED_MEMORY_VADDR || address + size >= Memory::SHARED_MEMORY_VADDR_END) { |
| 28 | LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X outside of shared mem bounds!", | 34 | LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X outside of shared mem bounds!", |
| 29 | GetObjectId(), address); | 35 | GetObjectId(), address); |
| 30 | // TODO: Verify error code with hardware | 36 | // TODO: Verify error code with hardware |
| @@ -32,21 +38,25 @@ ResultCode SharedMemory::Map(VAddr address, MemoryPermission permissions, | |||
| 32 | ErrorSummary::InvalidArgument, ErrorLevel::Permanent); | 38 | ErrorSummary::InvalidArgument, ErrorLevel::Permanent); |
| 33 | } | 39 | } |
| 34 | 40 | ||
| 41 | // TODO: Test permissions | ||
| 42 | |||
| 43 | // HACK: Since there's no way to write to the memory block without mapping it onto the game | ||
| 44 | // process yet, at least initialize memory the first time it's mapped. | ||
| 45 | if (address != this->base_address) { | ||
| 46 | std::memset(Memory::GetPointer(address), 0, size); | ||
| 47 | } | ||
| 48 | |||
| 35 | this->base_address = address; | 49 | this->base_address = address; |
| 36 | this->permissions = permissions; | ||
| 37 | this->other_permissions = other_permissions; | ||
| 38 | 50 | ||
| 39 | return RESULT_SUCCESS; | 51 | return RESULT_SUCCESS; |
| 40 | } | 52 | } |
| 41 | 53 | ||
| 42 | ResultVal<u8*> SharedMemory::GetPointer(u32 offset) { | 54 | u8* SharedMemory::GetPointer(u32 offset) { |
| 43 | if (base_address != 0) | 55 | if (base_address != 0) |
| 44 | return MakeResult<u8*>(Memory::GetPointer(base_address + offset)); | 56 | return Memory::GetPointer(base_address + offset); |
| 45 | 57 | ||
| 46 | LOG_ERROR(Kernel_SVC, "memory block id=%u not mapped!", GetObjectId()); | 58 | LOG_ERROR(Kernel_SVC, "memory block id=%u not mapped!", GetObjectId()); |
| 47 | // TODO(yuriks): Verify error code. | 59 | return nullptr; |
| 48 | return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, | ||
| 49 | ErrorSummary::InvalidState, ErrorLevel::Permanent); | ||
| 50 | } | 60 | } |
| 51 | 61 | ||
| 52 | } // namespace | 62 | } // namespace |
diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index 5833b411c..204266896 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h | |||
| @@ -27,11 +27,16 @@ class SharedMemory final : public Object { | |||
| 27 | public: | 27 | public: |
| 28 | /** | 28 | /** |
| 29 | * Creates a shared memory object | 29 | * Creates a shared memory object |
| 30 | * @param name Optional object name, used only for debugging purposes. | 30 | * @param size Size of the memory block. Must be page-aligned. |
| 31 | * @param permissions Permission restrictions applied to the process which created the block. | ||
| 32 | * @param other_permissions Permission restrictions applied to other processes mapping the block. | ||
| 33 | * @param name Optional object name, used for debugging purposes. | ||
| 31 | */ | 34 | */ |
| 32 | static SharedPtr<SharedMemory> Create(std::string name = "Unknown"); | 35 | static SharedPtr<SharedMemory> Create(u32 size, MemoryPermission permissions, |
| 36 | MemoryPermission other_permissions, std::string name = "Unknown"); | ||
| 33 | 37 | ||
| 34 | std::string GetTypeName() const override { return "SharedMemory"; } | 38 | std::string GetTypeName() const override { return "SharedMemory"; } |
| 39 | std::string GetName() const override { return name; } | ||
| 35 | 40 | ||
| 36 | static const HandleType HANDLE_TYPE = HandleType::SharedMemory; | 41 | static const HandleType HANDLE_TYPE = HandleType::SharedMemory; |
| 37 | HandleType GetHandleType() const override { return HANDLE_TYPE; } | 42 | HandleType GetHandleType() const override { return HANDLE_TYPE; } |
| @@ -49,12 +54,18 @@ public: | |||
| 49 | * @param offset Offset from the start of the shared memory block to get pointer | 54 | * @param offset Offset from the start of the shared memory block to get pointer |
| 50 | * @return Pointer to the shared memory block from the specified offset | 55 | * @return Pointer to the shared memory block from the specified offset |
| 51 | */ | 56 | */ |
| 52 | ResultVal<u8*> GetPointer(u32 offset = 0); | 57 | u8* GetPointer(u32 offset = 0); |
| 53 | 58 | ||
| 54 | VAddr base_address; ///< Address of shared memory block in RAM | 59 | /// Address of shared memory block in the process. |
| 55 | MemoryPermission permissions; ///< Permissions of shared memory block (SVC field) | 60 | VAddr base_address; |
| 56 | MemoryPermission other_permissions; ///< Other permissions of shared memory block (SVC field) | 61 | /// Size of the memory block. Page-aligned. |
| 57 | std::string name; ///< Name of shared memory object (optional) | 62 | u32 size; |
| 63 | /// Permission restrictions applied to the process which created the block. | ||
| 64 | MemoryPermission permissions; | ||
| 65 | /// Permission restrictions applied to other processes mapping the block. | ||
| 66 | MemoryPermission other_permissions; | ||
| 67 | /// Name of shared memory object. | ||
| 68 | std::string name; | ||
| 58 | 69 | ||
| 59 | private: | 70 | private: |
| 60 | SharedMemory(); | 71 | SharedMemory(); |
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index 560c9dcf6..09d463dd5 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp | |||
| @@ -304,7 +304,9 @@ void Init() { | |||
| 304 | file.ReadBytes(shared_font.data(), (size_t)file.GetSize()); | 304 | file.ReadBytes(shared_font.data(), (size_t)file.GetSize()); |
| 305 | 305 | ||
| 306 | // Create shared font memory object | 306 | // Create shared font memory object |
| 307 | shared_font_mem = Kernel::SharedMemory::Create("APT_U:shared_font_mem"); | 307 | using Kernel::MemoryPermission; |
| 308 | shared_font_mem = Kernel::SharedMemory::Create(3 * 1024 * 1024, // 3MB | ||
| 309 | MemoryPermission::ReadWrite, MemoryPermission::Read, "APT_U:shared_font_mem"); | ||
| 308 | } else { | 310 | } else { |
| 309 | LOG_WARNING(Service_APT, "Unable to load shared font: %s", filepath.c_str()); | 311 | LOG_WARNING(Service_APT, "Unable to load shared font: %s", filepath.c_str()); |
| 310 | shared_font_mem = nullptr; | 312 | shared_font_mem = nullptr; |
diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp index 8da063bd2..c6252a03b 100644 --- a/src/core/hle/service/gsp_gpu.cpp +++ b/src/core/hle/service/gsp_gpu.cpp | |||
| @@ -30,13 +30,12 @@ namespace GSP_GPU { | |||
| 30 | Kernel::SharedPtr<Kernel::Event> g_interrupt_event; | 30 | Kernel::SharedPtr<Kernel::Event> g_interrupt_event; |
| 31 | /// GSP shared memoryings | 31 | /// GSP shared memoryings |
| 32 | Kernel::SharedPtr<Kernel::SharedMemory> g_shared_memory; | 32 | Kernel::SharedPtr<Kernel::SharedMemory> g_shared_memory; |
| 33 | /// Thread index into interrupt relay queue, 1 is arbitrary | 33 | /// Thread index into interrupt relay queue |
| 34 | u32 g_thread_id = 1; | 34 | u32 g_thread_id = 0; |
| 35 | 35 | ||
| 36 | /// Gets a pointer to a thread command buffer in GSP shared memory | 36 | /// Gets a pointer to a thread command buffer in GSP shared memory |
| 37 | static inline u8* GetCommandBuffer(u32 thread_id) { | 37 | static inline u8* GetCommandBuffer(u32 thread_id) { |
| 38 | ResultVal<u8*> ptr = g_shared_memory->GetPointer(0x800 + (thread_id * sizeof(CommandBuffer))); | 38 | return g_shared_memory->GetPointer(0x800 + (thread_id * sizeof(CommandBuffer))); |
| 39 | return ptr.ValueOr(nullptr); | ||
| 40 | } | 39 | } |
| 41 | 40 | ||
| 42 | static inline FrameBufferUpdate* GetFrameBufferInfo(u32 thread_id, u32 screen_index) { | 41 | static inline FrameBufferUpdate* GetFrameBufferInfo(u32 thread_id, u32 screen_index) { |
| @@ -44,14 +43,14 @@ static inline FrameBufferUpdate* GetFrameBufferInfo(u32 thread_id, u32 screen_in | |||
| 44 | 43 | ||
| 45 | // For each thread there are two FrameBufferUpdate fields | 44 | // For each thread there are two FrameBufferUpdate fields |
| 46 | u32 offset = 0x200 + (2 * thread_id + screen_index) * sizeof(FrameBufferUpdate); | 45 | u32 offset = 0x200 + (2 * thread_id + screen_index) * sizeof(FrameBufferUpdate); |
| 47 | ResultVal<u8*> ptr = g_shared_memory->GetPointer(offset); | 46 | u8* ptr = g_shared_memory->GetPointer(offset); |
| 48 | return reinterpret_cast<FrameBufferUpdate*>(ptr.ValueOr(nullptr)); | 47 | return reinterpret_cast<FrameBufferUpdate*>(ptr); |
| 49 | } | 48 | } |
| 50 | 49 | ||
| 51 | /// Gets a pointer to the interrupt relay queue for a given thread index | 50 | /// Gets a pointer to the interrupt relay queue for a given thread index |
| 52 | static inline InterruptRelayQueue* GetInterruptRelayQueue(u32 thread_id) { | 51 | static inline InterruptRelayQueue* GetInterruptRelayQueue(u32 thread_id) { |
| 53 | ResultVal<u8*> ptr = g_shared_memory->GetPointer(sizeof(InterruptRelayQueue) * thread_id); | 52 | u8* ptr = g_shared_memory->GetPointer(sizeof(InterruptRelayQueue) * thread_id); |
| 54 | return reinterpret_cast<InterruptRelayQueue*>(ptr.ValueOr(nullptr)); | 53 | return reinterpret_cast<InterruptRelayQueue*>(ptr); |
| 55 | } | 54 | } |
| 56 | 55 | ||
| 57 | /** | 56 | /** |
| @@ -278,7 +277,7 @@ static void FlushDataCache(Service::Interface* self) { | |||
| 278 | * 1 : "Flags" field, purpose is unknown | 277 | * 1 : "Flags" field, purpose is unknown |
| 279 | * 3 : Handle to GSP synchronization event | 278 | * 3 : Handle to GSP synchronization event |
| 280 | * Outputs: | 279 | * Outputs: |
| 281 | * 0 : Result of function, 0 on success, otherwise error code | 280 | * 1 : Result of function, 0x2A07 on success, otherwise error code |
| 282 | * 2 : Thread index into GSP command buffer | 281 | * 2 : Thread index into GSP command buffer |
| 283 | * 4 : Handle to GSP shared memory | 282 | * 4 : Handle to GSP shared memory |
| 284 | */ | 283 | */ |
| @@ -288,11 +287,12 @@ static void RegisterInterruptRelayQueue(Service::Interface* self) { | |||
| 288 | 287 | ||
| 289 | g_interrupt_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[3]); | 288 | g_interrupt_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[3]); |
| 290 | ASSERT_MSG((g_interrupt_event != nullptr), "handle is not valid!"); | 289 | ASSERT_MSG((g_interrupt_event != nullptr), "handle is not valid!"); |
| 291 | g_shared_memory = Kernel::SharedMemory::Create("GSPSharedMem"); | ||
| 292 | 290 | ||
| 293 | Handle shmem_handle = Kernel::g_handle_table.Create(g_shared_memory).MoveFrom(); | 291 | Handle shmem_handle = Kernel::g_handle_table.Create(g_shared_memory).MoveFrom(); |
| 294 | 292 | ||
| 295 | cmd_buff[1] = 0x2A07; // Value verified by 3dmoo team, purpose unknown, but needed for GSP init | 293 | // This specific code is required for a successful initialization, rather than 0 |
| 294 | cmd_buff[1] = ResultCode((ErrorDescription)519, ErrorModule::GX, | ||
| 295 | ErrorSummary::Success, ErrorLevel::Success).raw; | ||
| 296 | cmd_buff[2] = g_thread_id++; // Thread ID | 296 | cmd_buff[2] = g_thread_id++; // Thread ID |
| 297 | cmd_buff[4] = shmem_handle; // GSP shared memory | 297 | cmd_buff[4] = shmem_handle; // GSP shared memory |
| 298 | 298 | ||
| @@ -527,8 +527,12 @@ Interface::Interface() { | |||
| 527 | Register(FunctionTable); | 527 | Register(FunctionTable); |
| 528 | 528 | ||
| 529 | g_interrupt_event = 0; | 529 | g_interrupt_event = 0; |
| 530 | g_shared_memory = 0; | 530 | |
| 531 | g_thread_id = 1; | 531 | using Kernel::MemoryPermission; |
| 532 | g_shared_memory = Kernel::SharedMemory::Create(0x1000, MemoryPermission::ReadWrite, | ||
| 533 | MemoryPermission::ReadWrite, "GSPSharedMem"); | ||
| 534 | |||
| 535 | g_thread_id = 0; | ||
| 532 | } | 536 | } |
| 533 | 537 | ||
| 534 | } // namespace | 538 | } // namespace |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index dd85848d0..9695f7e56 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -48,7 +48,7 @@ static u32 next_touch_index; | |||
| 48 | // * Set PadData.current_state.circle_right = 1 if current PadEntry.circle_pad_y <= -41 | 48 | // * Set PadData.current_state.circle_right = 1 if current PadEntry.circle_pad_y <= -41 |
| 49 | 49 | ||
| 50 | void Update() { | 50 | void Update() { |
| 51 | SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer().ValueOr(nullptr)); | 51 | SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer()); |
| 52 | const PadState state = VideoCore::g_emu_window->GetPadState(); | 52 | const PadState state = VideoCore::g_emu_window->GetPadState(); |
| 53 | 53 | ||
| 54 | if (mem == nullptr) { | 54 | if (mem == nullptr) { |
| @@ -163,7 +163,9 @@ void Init() { | |||
| 163 | AddService(new HID_U_Interface); | 163 | AddService(new HID_U_Interface); |
| 164 | AddService(new HID_SPVR_Interface); | 164 | AddService(new HID_SPVR_Interface); |
| 165 | 165 | ||
| 166 | shared_mem = SharedMemory::Create("HID:SharedMem"); | 166 | using Kernel::MemoryPermission; |
| 167 | shared_mem = SharedMemory::Create(0x1000, MemoryPermission::ReadWrite, | ||
| 168 | MemoryPermission::Read, "HID:SharedMem"); | ||
| 167 | 169 | ||
| 168 | next_pad_index = 0; | 170 | next_pad_index = 0; |
| 169 | next_touch_index = 0; | 171 | next_touch_index = 0; |
diff --git a/src/core/hle/service/ir/ir.cpp b/src/core/hle/service/ir/ir.cpp index 15ac477ef..adfbb258d 100644 --- a/src/core/hle/service/ir/ir.cpp +++ b/src/core/hle/service/ir/ir.cpp | |||
| @@ -34,7 +34,9 @@ void Init() { | |||
| 34 | AddService(new IR_U_Interface); | 34 | AddService(new IR_U_Interface); |
| 35 | AddService(new IR_User_Interface); | 35 | AddService(new IR_User_Interface); |
| 36 | 36 | ||
| 37 | shared_memory = SharedMemory::Create("IR:SharedMemory"); | 37 | using Kernel::MemoryPermission; |
| 38 | shared_memory = SharedMemory::Create(0x1000, Kernel::MemoryPermission::ReadWrite, | ||
| 39 | Kernel::MemoryPermission::ReadWrite, "IR:SharedMemory"); | ||
| 38 | 40 | ||
| 39 | // Create event handle(s) | 41 | // Create event handle(s) |
| 40 | handle_event = Event::Create(RESETTYPE_ONESHOT, "IR:HandleEvent"); | 42 | handle_event = Event::Create(RESETTYPE_ONESHOT, "IR:HandleEvent"); |
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 393cfbe79..1ec6599c7 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp | |||
| @@ -601,7 +601,9 @@ static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 | |||
| 601 | using Kernel::SharedMemory; | 601 | using Kernel::SharedMemory; |
| 602 | // TODO(Subv): Implement this function | 602 | // TODO(Subv): Implement this function |
| 603 | 603 | ||
| 604 | SharedPtr<SharedMemory> shared_memory = SharedMemory::Create(); | 604 | using Kernel::MemoryPermission; |
| 605 | SharedPtr<SharedMemory> shared_memory = SharedMemory::Create(size, | ||
| 606 | (MemoryPermission)my_permission, (MemoryPermission)other_permission); | ||
| 605 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(shared_memory))); | 607 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(shared_memory))); |
| 606 | 608 | ||
| 607 | LOG_WARNING(Kernel_SVC, "(STUBBED) called addr=0x%08X", addr); | 609 | LOG_WARNING(Kernel_SVC, "(STUBBED) called addr=0x%08X", addr); |