csnd_snd.cpp 4.2 KB

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