diff options
| author | 2016-04-24 11:39:59 +0100 | |
|---|---|---|
| committer | 2016-04-27 06:35:08 +0100 | |
| commit | 2929b67c5f76a6bb7bc99e612fc582c5de28353f (patch) | |
| tree | ab75e454181aa8280d7628f31ed6427646b10814 /src/core | |
| parent | DSP_DSP: Updated interrupt implementation (diff) | |
| download | yuzu-2929b67c5f76a6bb7bc99e612fc582c5de28353f.tar.gz yuzu-2929b67c5f76a6bb7bc99e612fc582c5de28353f.tar.xz yuzu-2929b67c5f76a6bb7bc99e612fc582c5de28353f.zip | |
DSP_DSP: Add return IPC headers
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/hle/result.h | 1 | ||||
| -rw-r--r-- | src/core/hle/service/dsp_dsp.cpp | 30 |
2 files changed, 27 insertions, 4 deletions
diff --git a/src/core/hle/result.h b/src/core/hle/result.h index 2d22652d9..53931a106 100644 --- a/src/core/hle/result.h +++ b/src/core/hle/result.h | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | /// Detailed description of the error. This listing is likely incomplete. | 18 | /// Detailed description of the error. This listing is likely incomplete. |
| 19 | enum class ErrorDescription : u32 { | 19 | enum class ErrorDescription : u32 { |
| 20 | Success = 0, | 20 | Success = 0, |
| 21 | OS_InvalidBufferDescriptor = 48, | ||
| 21 | WrongAddress = 53, | 22 | WrongAddress = 53, |
| 22 | FS_NotFound = 120, | 23 | FS_NotFound = 120, |
| 23 | FS_AlreadyExists = 190, | 24 | FS_AlreadyExists = 190, |
diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp index e9ef50f86..58ded7eb5 100644 --- a/src/core/hle/service/dsp_dsp.cpp +++ b/src/core/hle/service/dsp_dsp.cpp | |||
| @@ -102,7 +102,10 @@ static void ConvertProcessAddressFromDspDram(Service::Interface* self) { | |||
| 102 | 102 | ||
| 103 | u32 addr = cmd_buff[1]; | 103 | u32 addr = cmd_buff[1]; |
| 104 | 104 | ||
| 105 | cmd_buff[0] = IPC::MakeHeader(0xC, 2, 0); | ||
| 105 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | 106 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error |
| 107 | |||
| 108 | // TODO(merry): There is a per-region offset missing in this calculation (that seems to be always zero). | ||
| 106 | cmd_buff[2] = (addr << 1) + (Memory::DSP_RAM_VADDR + 0x40000); | 109 | cmd_buff[2] = (addr << 1) + (Memory::DSP_RAM_VADDR + 0x40000); |
| 107 | 110 | ||
| 108 | LOG_DEBUG(Service_DSP, "addr=0x%08X", addr); | 111 | LOG_DEBUG(Service_DSP, "addr=0x%08X", addr); |
| @@ -157,7 +160,9 @@ static void LoadComponent(Service::Interface* self) { | |||
| 157 | static void GetSemaphoreEventHandle(Service::Interface* self) { | 160 | static void GetSemaphoreEventHandle(Service::Interface* self) { |
| 158 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 161 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 159 | 162 | ||
| 163 | cmd_buff[0] = IPC::MakeHeader(0x16, 1, 2); | ||
| 160 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | 164 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error |
| 165 | // cmd_buff[2] not set | ||
| 161 | cmd_buff[3] = Kernel::g_handle_table.Create(semaphore_event).MoveFrom(); // Event handle | 166 | cmd_buff[3] = Kernel::g_handle_table.Create(semaphore_event).MoveFrom(); // Event handle |
| 162 | 167 | ||
| 163 | LOG_WARNING(Service_DSP, "(STUBBED) called"); | 168 | LOG_WARNING(Service_DSP, "(STUBBED) called"); |
| @@ -182,8 +187,7 @@ static void FlushDataCache(Service::Interface* self) { | |||
| 182 | u32 size = cmd_buff[2]; | 187 | u32 size = cmd_buff[2]; |
| 183 | u32 process = cmd_buff[4]; | 188 | u32 process = cmd_buff[4]; |
| 184 | 189 | ||
| 185 | // TODO(purpasmart96): Verify return header on HW | 190 | cmd_buff[0] = IPC::MakeHeader(0x13, 1, 0); |
| 186 | |||
| 187 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | 191 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error |
| 188 | 192 | ||
| 189 | LOG_TRACE(Service_DSP, "called address=0x%08X, size=0x%X, process=0x%08X", address, size, process); | 193 | LOG_TRACE(Service_DSP, "called address=0x%08X, size=0x%X, process=0x%08X", address, size, process); |
| @@ -248,6 +252,7 @@ static void RegisterInterruptEvents(Service::Interface* self) { | |||
| 248 | static void SetSemaphore(Service::Interface* self) { | 252 | static void SetSemaphore(Service::Interface* self) { |
| 249 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 253 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 250 | 254 | ||
| 255 | cmd_buff[0] = IPC::MakeHeader(0x7, 1, 0); | ||
| 251 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | 256 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error |
| 252 | 257 | ||
| 253 | LOG_WARNING(Service_DSP, "(STUBBED) called"); | 258 | LOG_WARNING(Service_DSP, "(STUBBED) called"); |
| @@ -271,17 +276,23 @@ static void WriteProcessPipe(Service::Interface* self) { | |||
| 271 | u32 size = cmd_buff[2]; | 276 | u32 size = cmd_buff[2]; |
| 272 | u32 buffer = cmd_buff[4]; | 277 | u32 buffer = cmd_buff[4]; |
| 273 | 278 | ||
| 274 | ASSERT_MSG(IPC::StaticBufferDesc(size, 1) == cmd_buff[3], "IPC static buffer descriptor failed validation (0x%X). pipe=%u, size=0x%X, buffer=0x%08X", cmd_buff[3], pipe, size, buffer); | 279 | if (IPC::StaticBufferDesc(size, 1) != cmd_buff[3]) { |
| 280 | LOG_ERROR(Service_DSP, "IPC static buffer descriptor failed validation (0x%X). pipe=%u, size=0x%X, buffer=0x%08X", cmd_buff[3], pipe, size, buffer); | ||
| 281 | cmd_buff[0] = IPC::MakeHeader(0, 1, 0); | ||
| 282 | cmd_buff[1] = ResultCode(ErrorDescription::OS_InvalidBufferDescriptor, ErrorModule::OS, ErrorSummary::WrongArgument, ErrorLevel::Permanent).raw; | ||
| 283 | return; | ||
| 284 | } | ||
| 285 | |||
| 275 | ASSERT_MSG(Memory::GetPointer(buffer) != nullptr, "Invalid Buffer: pipe=%u, size=0x%X, buffer=0x%08X", pipe, size, buffer); | 286 | ASSERT_MSG(Memory::GetPointer(buffer) != nullptr, "Invalid Buffer: pipe=%u, size=0x%X, buffer=0x%08X", pipe, size, buffer); |
| 276 | 287 | ||
| 277 | std::vector<u8> message(size); | 288 | std::vector<u8> message(size); |
| 278 | |||
| 279 | for (size_t i = 0; i < size; i++) { | 289 | for (size_t i = 0; i < size; i++) { |
| 280 | message[i] = Memory::Read8(buffer + i); | 290 | message[i] = Memory::Read8(buffer + i); |
| 281 | } | 291 | } |
| 282 | 292 | ||
| 283 | DSP::HLE::PipeWrite(pipe, message); | 293 | DSP::HLE::PipeWrite(pipe, message); |
| 284 | 294 | ||
| 295 | cmd_buff[0] = IPC::MakeHeader(0xD, 1, 0); | ||
| 285 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | 296 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error |
| 286 | 297 | ||
| 287 | LOG_DEBUG(Service_DSP, "pipe=%u, size=0x%X, buffer=0x%08X", pipe, size, buffer); | 298 | LOG_DEBUG(Service_DSP, "pipe=%u, size=0x%X, buffer=0x%08X", pipe, size, buffer); |
| @@ -311,6 +322,7 @@ static void ReadPipeIfPossible(Service::Interface* self) { | |||
| 311 | 322 | ||
| 312 | ASSERT_MSG(Memory::GetPointer(addr) != nullptr, "Invalid addr: pipe=0x%08X, unknown=0x%08X, size=0x%X, buffer=0x%08X", pipe, unknown, size, addr); | 323 | ASSERT_MSG(Memory::GetPointer(addr) != nullptr, "Invalid addr: pipe=0x%08X, unknown=0x%08X, size=0x%X, buffer=0x%08X", pipe, unknown, size, addr); |
| 313 | 324 | ||
| 325 | cmd_buff[0] = IPC::MakeHeader(0x10, 1, 2); | ||
| 314 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | 326 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error |
| 315 | if (DSP::HLE::GetPipeReadableSize(pipe) >= size) { | 327 | if (DSP::HLE::GetPipeReadableSize(pipe) >= size) { |
| 316 | std::vector<u8> response = DSP::HLE::PipeRead(pipe, size); | 328 | std::vector<u8> response = DSP::HLE::PipeRead(pipe, size); |
| @@ -321,6 +333,8 @@ static void ReadPipeIfPossible(Service::Interface* self) { | |||
| 321 | } else { | 333 | } else { |
| 322 | cmd_buff[2] = 0; // Return no data | 334 | cmd_buff[2] = 0; // Return no data |
| 323 | } | 335 | } |
| 336 | cmd_buff[3] = IPC::StaticBufferDesc(size, 0); | ||
| 337 | cmd_buff[4] = addr; | ||
| 324 | 338 | ||
| 325 | LOG_DEBUG(Service_DSP, "pipe=0x%08X, unknown=0x%08X, size=0x%X, buffer=0x%08X, return cmd_buff[2]=0x%08X", pipe, unknown, size, addr, cmd_buff[2]); | 339 | LOG_DEBUG(Service_DSP, "pipe=0x%08X, unknown=0x%08X, size=0x%X, buffer=0x%08X, return cmd_buff[2]=0x%08X", pipe, unknown, size, addr, cmd_buff[2]); |
| 326 | } | 340 | } |
| @@ -351,8 +365,11 @@ static void ReadPipe(Service::Interface* self) { | |||
| 351 | 365 | ||
| 352 | Memory::WriteBlock(addr, response.data(), response.size()); | 366 | Memory::WriteBlock(addr, response.data(), response.size()); |
| 353 | 367 | ||
| 368 | cmd_buff[0] = IPC::MakeHeader(0xE, 2, 2); | ||
| 354 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | 369 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error |
| 355 | cmd_buff[2] = static_cast<u32>(response.size()); | 370 | cmd_buff[2] = static_cast<u32>(response.size()); |
| 371 | cmd_buff[3] = IPC::StaticBufferDesc(size, 0); | ||
| 372 | cmd_buff[4] = addr; | ||
| 356 | } else { | 373 | } else { |
| 357 | // No more data is in pipe. Hardware hangs in this case; this should never happen. | 374 | // No more data is in pipe. Hardware hangs in this case; this should never happen. |
| 358 | UNREACHABLE(); | 375 | UNREACHABLE(); |
| @@ -376,6 +393,7 @@ static void GetPipeReadableSize(Service::Interface* self) { | |||
| 376 | DSP::HLE::DspPipe pipe = static_cast<DSP::HLE::DspPipe>(cmd_buff[1]); | 393 | DSP::HLE::DspPipe pipe = static_cast<DSP::HLE::DspPipe>(cmd_buff[1]); |
| 377 | u32 unknown = cmd_buff[2]; | 394 | u32 unknown = cmd_buff[2]; |
| 378 | 395 | ||
| 396 | cmd_buff[0] = IPC::MakeHeader(0xF, 2, 0); | ||
| 379 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | 397 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error |
| 380 | cmd_buff[2] = DSP::HLE::GetPipeReadableSize(pipe); | 398 | cmd_buff[2] = DSP::HLE::GetPipeReadableSize(pipe); |
| 381 | 399 | ||
| @@ -394,6 +412,7 @@ static void SetSemaphoreMask(Service::Interface* self) { | |||
| 394 | 412 | ||
| 395 | u32 mask = cmd_buff[1]; | 413 | u32 mask = cmd_buff[1]; |
| 396 | 414 | ||
| 415 | cmd_buff[0] = IPC::MakeHeader(0x17, 1, 0); | ||
| 397 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | 416 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error |
| 398 | 417 | ||
| 399 | LOG_WARNING(Service_DSP, "(STUBBED) called mask=0x%08X", mask); | 418 | LOG_WARNING(Service_DSP, "(STUBBED) called mask=0x%08X", mask); |
| @@ -411,6 +430,7 @@ static void SetSemaphoreMask(Service::Interface* self) { | |||
| 411 | static void GetHeadphoneStatus(Service::Interface* self) { | 430 | static void GetHeadphoneStatus(Service::Interface* self) { |
| 412 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 431 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 413 | 432 | ||
| 433 | cmd_buff[0] = IPC::MakeHeader(0x1F, 2, 0); | ||
| 414 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | 434 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error |
| 415 | cmd_buff[2] = 0; // Not using headphones? | 435 | cmd_buff[2] = 0; // Not using headphones? |
| 416 | 436 | ||
| @@ -437,6 +457,7 @@ static void RecvData(Service::Interface* self) { | |||
| 437 | 457 | ||
| 438 | // Application reads this after requesting DSP shutdown, to verify the DSP has indeed shutdown or slept. | 458 | // Application reads this after requesting DSP shutdown, to verify the DSP has indeed shutdown or slept. |
| 439 | 459 | ||
| 460 | cmd_buff[0] = IPC::MakeHeader(0x1, 2, 0); | ||
| 440 | cmd_buff[1] = RESULT_SUCCESS.raw; | 461 | cmd_buff[1] = RESULT_SUCCESS.raw; |
| 441 | switch (DSP::HLE::GetDspState()) { | 462 | switch (DSP::HLE::GetDspState()) { |
| 442 | case DSP::HLE::DspState::On: | 463 | case DSP::HLE::DspState::On: |
| @@ -472,6 +493,7 @@ static void RecvDataIsReady(Service::Interface* self) { | |||
| 472 | 493 | ||
| 473 | ASSERT_MSG(register_number == 0, "Unknown register_number %u", register_number); | 494 | ASSERT_MSG(register_number == 0, "Unknown register_number %u", register_number); |
| 474 | 495 | ||
| 496 | cmd_buff[0] = IPC::MakeHeader(0x2, 2, 0); | ||
| 475 | cmd_buff[1] = RESULT_SUCCESS.raw; | 497 | cmd_buff[1] = RESULT_SUCCESS.raw; |
| 476 | cmd_buff[2] = 1; // Ready to read | 498 | cmd_buff[2] = 1; // Ready to read |
| 477 | 499 | ||