csnd_snd.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // Copyright 2014 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <cstring>
  5. #include "common/alignment.h"
  6. #include "core/hle/ipc.h"
  7. #include "core/hle/kernel/handle_table.h"
  8. #include "core/hle/kernel/mutex.h"
  9. #include "core/hle/kernel/shared_memory.h"
  10. #include "core/hle/service/csnd_snd.h"
  11. #include "core/memory.h"
  12. namespace Service {
  13. namespace CSND {
  14. struct Type0Command {
  15. // command id and next command offset
  16. u32 command_id;
  17. u32 finished;
  18. u32 flags;
  19. u8 parameters[20];
  20. };
  21. static_assert(sizeof(Type0Command) == 0x20, "Type0Command structure size is wrong");
  22. static Kernel::SharedPtr<Kernel::SharedMemory> shared_memory = nullptr;
  23. static Kernel::SharedPtr<Kernel::Mutex> mutex = nullptr;
  24. /**
  25. * CSND_SND::Initialize service function
  26. * Inputs:
  27. * 0 : Header Code[0x00010140]
  28. * 1 : Shared memory block size, for mem-block creation
  29. * Outputs:
  30. * 1 : Result of function, 0 on success, otherwise error code
  31. * 2 : Handle-list header
  32. * 3 : Mutex handle
  33. * 4 : Shared memory block handle
  34. */
  35. static void Initialize(Interface* self) {
  36. u32* cmd_buff = Kernel::GetCommandBuffer();
  37. u32 size = Common::AlignUp(cmd_buff[1], Memory::PAGE_SIZE);
  38. using Kernel::MemoryPermission;
  39. shared_memory = Kernel::SharedMemory::Create(nullptr, size, MemoryPermission::ReadWrite,
  40. MemoryPermission::ReadWrite, 0,
  41. Kernel::MemoryRegion::BASE, "CSND:SharedMemory");
  42. mutex = Kernel::Mutex::Create(false, "CSND:mutex");
  43. cmd_buff[1] = RESULT_SUCCESS.raw;
  44. cmd_buff[2] = IPC::CopyHandleDesc(2);
  45. cmd_buff[3] = Kernel::g_handle_table.Create(mutex).MoveFrom();
  46. cmd_buff[4] = Kernel::g_handle_table.Create(shared_memory).MoveFrom();
  47. LOG_WARNING(Service_CSND, "(STUBBED) called");
  48. }
  49. /**
  50. * CSND_SND::Shutdown service function
  51. * Inputs:
  52. * 0 : Header Code[0x00020000]
  53. * Outputs:
  54. * 1 : Result of function, 0 on success, otherwise error code
  55. */
  56. static void Shutdown(Interface* self) {
  57. u32* cmd_buff = Kernel::GetCommandBuffer();
  58. shared_memory = nullptr;
  59. mutex = nullptr;
  60. cmd_buff[1] = RESULT_SUCCESS.raw;
  61. LOG_WARNING(Service_CSND, "(STUBBED) called");
  62. }
  63. /**
  64. * CSND_SND::ExecuteCommands service function
  65. * Inputs:
  66. * 0 : Header Code[0x00030040]
  67. * 1 : Command offset in shared memory.
  68. * Outputs:
  69. * 1 : Result of function, 0 on success, otherwise error code
  70. * 2 : Available channel bit mask
  71. */
  72. static void ExecuteCommands(Interface* self) {
  73. u32* cmd_buff = Kernel::GetCommandBuffer();
  74. if (shared_memory == nullptr) {
  75. cmd_buff[1] = 1;
  76. LOG_ERROR(Service_CSND, "called, shared memory not allocated");
  77. return;
  78. }
  79. VAddr addr = cmd_buff[1];
  80. u8* ptr = shared_memory->GetPointer(addr);
  81. Type0Command command;
  82. std::memcpy(&command, ptr, sizeof(Type0Command));
  83. command.finished |= 1;
  84. std::memcpy(ptr, &command, sizeof(Type0Command));
  85. cmd_buff[1] = RESULT_SUCCESS.raw;
  86. LOG_WARNING(Service_CSND, "(STUBBED) called, addr=0x%08X", addr);
  87. }
  88. /**
  89. * CSND_SND::AcquireSoundChannels service function
  90. * Inputs:
  91. * 0 : Header Code[0x00050000]
  92. * Outputs:
  93. * 1 : Result of function, 0 on success, otherwise error code
  94. * 2 : Available channel bit mask
  95. */
  96. static void AcquireSoundChannels(Interface* self) {
  97. u32* cmd_buff = Kernel::GetCommandBuffer();
  98. cmd_buff[1] = RESULT_SUCCESS.raw;
  99. cmd_buff[2] = 0xFFFFFF00;
  100. LOG_WARNING(Service_CSND, "(STUBBED) called");
  101. }
  102. const Interface::FunctionInfo FunctionTable[] = {
  103. {0x00010140, Initialize, "Initialize"},
  104. {0x00020000, Shutdown, "Shutdown"},
  105. {0x00030040, ExecuteCommands, "ExecuteCommands"},
  106. {0x00040080, nullptr, "ExecuteType1Commands"},
  107. {0x00050000, AcquireSoundChannels, "AcquireSoundChannels"},
  108. {0x00060000, nullptr, "ReleaseSoundChannels"},
  109. {0x00070000, nullptr, "AcquireCaptureDevice"},
  110. {0x00080040, nullptr, "ReleaseCaptureDevice"},
  111. {0x00090082, nullptr, "FlushDataCache"},
  112. {0x000A0082, nullptr, "StoreDataCache"},
  113. {0x000B0082, nullptr, "InvalidateDataCache"},
  114. {0x000C0000, nullptr, "Reset"},
  115. };
  116. CSND_SND::CSND_SND() {
  117. Register(FunctionTable);
  118. }
  119. } // namespace CSND
  120. } // namespace Service