diff options
| author | 2014-07-05 00:59:58 -0400 | |
|---|---|---|
| committer | 2014-07-05 10:24:52 -0400 | |
| commit | 7b7a435094654da2a707a2089ed5ca9584679c38 (patch) | |
| tree | ccaecd65308654a5499ba3b26494cadca39dc0ee /src/core | |
| parent | Kernel: Added support for shared memory objects. (diff) | |
| download | yuzu-7b7a435094654da2a707a2089ed5ca9584679c38.tar.gz yuzu-7b7a435094654da2a707a2089ed5ca9584679c38.tar.xz yuzu-7b7a435094654da2a707a2089ed5ca9584679c38.zip | |
GSP: Fixed to use real shared memory object, various cleanups.
- Previously, used a hard-coded shared memory handle of 0x10002000 (as used by libctru homebrew)
GSP: Added name for shared memory.
GSP: Cleaned up assertion message.
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/hle/service/gsp.cpp | 59 | ||||
| -rw-r--r-- | src/core/hle/svc.cpp | 11 |
2 files changed, 40 insertions, 30 deletions
diff --git a/src/core/hle/service/gsp.cpp b/src/core/hle/service/gsp.cpp index f75ba75c2..1fdbdf342 100644 --- a/src/core/hle/service/gsp.cpp +++ b/src/core/hle/service/gsp.cpp | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include "core/mem_map.h" | 9 | #include "core/mem_map.h" |
| 10 | #include "core/hle/hle.h" | 10 | #include "core/hle/hle.h" |
| 11 | #include "core/hle/kernel/event.h" | 11 | #include "core/hle/kernel/event.h" |
| 12 | #include "core/hle/kernel/shared_memory.h" | ||
| 12 | #include "core/hle/service/gsp.h" | 13 | #include "core/hle/service/gsp.h" |
| 13 | 14 | ||
| 14 | #include "core/hw/gpu.h" | 15 | #include "core/hw/gpu.h" |
| @@ -36,14 +37,24 @@ union GX_CmdBufferHeader { | |||
| 36 | BitField<8,8,u32> number_commands; | 37 | BitField<8,8,u32> number_commands; |
| 37 | }; | 38 | }; |
| 38 | 39 | ||
| 39 | /// Gets the address of the start (header) of a command buffer in GSP shared memory | 40 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 40 | static inline u32 GX_GetCmdBufferAddress(u32 thread_id) { | 41 | // Namespace GSP_GPU |
| 41 | return (0x10002000 + 0x800 + (thread_id * 0x200)); | 42 | |
| 42 | } | 43 | namespace GSP_GPU { |
| 44 | |||
| 45 | Handle g_event = 0; | ||
| 46 | Handle g_shared_memory = 0; | ||
| 47 | |||
| 48 | u32 g_thread_id = 0; | ||
| 49 | |||
| 50 | enum { | ||
| 51 | REG_FRAMEBUFFER_1 = 0x00400468, | ||
| 52 | REG_FRAMEBUFFER_2 = 0x00400494, | ||
| 53 | }; | ||
| 43 | 54 | ||
| 44 | /// Gets a pointer to the start (header) of a command buffer in GSP shared memory | 55 | /// Gets a pointer to the start (header) of a command buffer in GSP shared memory |
| 45 | static inline u8* GX_GetCmdBufferPointer(u32 thread_id, u32 offset=0) { | 56 | static inline u8* GX_GetCmdBufferPointer(u32 thread_id, u32 offset=0) { |
| 46 | return Memory::GetPointer(GX_GetCmdBufferAddress(thread_id) + offset); | 57 | return Kernel::GetSharedMemoryPointer(g_shared_memory, 0x800 + (thread_id * 0x200) + offset); |
| 47 | } | 58 | } |
| 48 | 59 | ||
| 49 | /// Finishes execution of a GSP command | 60 | /// Finishes execution of a GSP command |
| @@ -56,19 +67,6 @@ void GX_FinishCommand(u32 thread_id) { | |||
| 56 | // TODO: Increment header->index? | 67 | // TODO: Increment header->index? |
| 57 | } | 68 | } |
| 58 | 69 | ||
| 59 | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 60 | // Namespace GSP_GPU | ||
| 61 | |||
| 62 | namespace GSP_GPU { | ||
| 63 | |||
| 64 | Handle g_event_handle = 0; | ||
| 65 | u32 g_thread_id = 0; | ||
| 66 | |||
| 67 | enum { | ||
| 68 | REG_FRAMEBUFFER_1 = 0x00400468, | ||
| 69 | REG_FRAMEBUFFER_2 = 0x00400494, | ||
| 70 | }; | ||
| 71 | |||
| 72 | /// Read a GSP GPU hardware register | 70 | /// Read a GSP GPU hardware register |
| 73 | void ReadHWRegs(Service::Interface* self) { | 71 | void ReadHWRegs(Service::Interface* self) { |
| 74 | static const u32 framebuffer_1[] = {GPU::PADDR_VRAM_TOP_LEFT_FRAME1, GPU::PADDR_VRAM_TOP_RIGHT_FRAME1}; | 72 | static const u32 framebuffer_1[] = {GPU::PADDR_VRAM_TOP_LEFT_FRAME1, GPU::PADDR_VRAM_TOP_RIGHT_FRAME1}; |
| @@ -103,24 +101,34 @@ void ReadHWRegs(Service::Interface* self) { | |||
| 103 | 101 | ||
| 104 | } | 102 | } |
| 105 | 103 | ||
| 104 | /** | ||
| 105 | * GSP_GPU::RegisterInterruptRelayQueue service function | ||
| 106 | * Inputs: | ||
| 107 | * 1 : "Flags" field, purpose is unknown | ||
| 108 | * 3 : Handle to GSP synchronization event | ||
| 109 | * Outputs: | ||
| 110 | * 0 : Result of function, 0 on success, otherwise error code | ||
| 111 | * 2 : Thread index into GSP command buffer | ||
| 112 | * 4 : Handle to GSP shared memory | ||
| 113 | */ | ||
| 106 | void RegisterInterruptRelayQueue(Service::Interface* self) { | 114 | void RegisterInterruptRelayQueue(Service::Interface* self) { |
| 107 | u32* cmd_buff = Service::GetCommandBuffer(); | 115 | u32* cmd_buff = Service::GetCommandBuffer(); |
| 108 | u32 flags = cmd_buff[1]; | 116 | u32 flags = cmd_buff[1]; |
| 109 | u32 event_handle = cmd_buff[3]; | 117 | g_event = cmd_buff[3]; |
| 110 | |||
| 111 | _assert_msg_(GSP, (event_handle != 0), "called, but event is nullptr!"); | ||
| 112 | 118 | ||
| 113 | g_event_handle = event_handle; | 119 | _assert_msg_(GSP, (g_event != 0), "handle is not valid!"); |
| 114 | 120 | ||
| 115 | Kernel::SetEventLocked(event_handle, false); | 121 | Kernel::SetEventLocked(g_event, false); |
| 116 | 122 | ||
| 117 | // Hack - This function will permanently set the state of the GSP event such that GPU command | 123 | // Hack - This function will permanently set the state of the GSP event such that GPU command |
| 118 | // synchronization barriers always passthrough. Correct solution would be to set this after the | 124 | // synchronization barriers always passthrough. Correct solution would be to set this after the |
| 119 | // GPU as processed all queued up commands, but due to the emulator being single-threaded they | 125 | // GPU as processed all queued up commands, but due to the emulator being single-threaded they |
| 120 | // will always be ready. | 126 | // will always be ready. |
| 121 | Kernel::SetPermanentLock(event_handle, true); | 127 | Kernel::SetPermanentLock(g_event, true); |
| 122 | 128 | ||
| 123 | cmd_buff[2] = g_thread_id; // ThreadID | 129 | cmd_buff[0] = 0; // Result - no error |
| 130 | cmd_buff[2] = g_thread_id; // ThreadID | ||
| 131 | cmd_buff[4] = g_shared_memory; // GSP shared memory | ||
| 124 | } | 132 | } |
| 125 | 133 | ||
| 126 | 134 | ||
| @@ -208,6 +216,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 208 | 216 | ||
| 209 | Interface::Interface() { | 217 | Interface::Interface() { |
| 210 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 218 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); |
| 219 | g_shared_memory = Kernel::CreateSharedMemory("GSPSharedMem"); | ||
| 211 | } | 220 | } |
| 212 | 221 | ||
| 213 | Interface::~Interface() { | 222 | Interface::~Interface() { |
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 441d8ce8d..746d24a70 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include "core/hle/kernel/event.h" | 12 | #include "core/hle/kernel/event.h" |
| 13 | #include "core/hle/kernel/kernel.h" | 13 | #include "core/hle/kernel/kernel.h" |
| 14 | #include "core/hle/kernel/mutex.h" | 14 | #include "core/hle/kernel/mutex.h" |
| 15 | #include "core/hle/kernel/shared_memory.h" | ||
| 15 | #include "core/hle/kernel/thread.h" | 16 | #include "core/hle/kernel/thread.h" |
| 16 | 17 | ||
| 17 | #include "core/hle/function_wrappers.h" | 18 | #include "core/hle/function_wrappers.h" |
| @@ -58,17 +59,17 @@ Result ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 addr1, u32 siz | |||
| 58 | } | 59 | } |
| 59 | 60 | ||
| 60 | /// Maps a memory block to specified address | 61 | /// Maps a memory block to specified address |
| 61 | Result MapMemoryBlock(Handle memblock, u32 addr, u32 mypermissions, u32 otherpermission) { | 62 | Result MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 other_permissions) { |
| 62 | DEBUG_LOG(SVC, "called memblock=0x08X, addr=0x%08X, mypermissions=0x%08X, otherpermission=%d", | 63 | DEBUG_LOG(SVC, "called memblock=0x08X, addr=0x%08X, mypermissions=0x%08X, otherpermission=%d", |
| 63 | memblock, addr, mypermissions, otherpermission); | 64 | handle, addr, permissions, other_permissions); |
| 64 | switch (mypermissions) { | 65 | switch (permissions) { |
| 65 | case MEMORY_PERMISSION_NORMAL: | 66 | case MEMORY_PERMISSION_NORMAL: |
| 66 | case MEMORY_PERMISSION_NORMAL + 1: | 67 | case MEMORY_PERMISSION_NORMAL + 1: |
| 67 | case MEMORY_PERMISSION_NORMAL + 2: | 68 | case MEMORY_PERMISSION_NORMAL + 2: |
| 68 | Memory::MapBlock_Shared(memblock, addr, mypermissions); | 69 | Kernel::MapSharedMemory(handle, addr, permissions, other_permissions); |
| 69 | break; | 70 | break; |
| 70 | default: | 71 | default: |
| 71 | ERROR_LOG(OSHLE, "unknown permissions=0x%08X", mypermissions); | 72 | ERROR_LOG(OSHLE, "unknown permissions=0x%08X", permissions); |
| 72 | } | 73 | } |
| 73 | return 0; | 74 | return 0; |
| 74 | } | 75 | } |