| 
									
										
										
										
											2014-10-29 18:38:33 -07:00
										 |  |  | // Copyright 2014 Citra Emulator Project
 | 
					
						
							| 
									
										
										
										
											2014-12-16 21:38:14 -08:00
										 |  |  | // Licensed under GPLv2 or any later version
 | 
					
						
							| 
									
										
										
										
											2014-10-29 18:38:33 -07:00
										 |  |  | // Refer to the license.txt file included.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "core/hle/hle.h"
 | 
					
						
							| 
									
										
										
										
											2014-11-26 14:30:53 -05:00
										 |  |  | #include "core/hle/kernel/event.h"
 | 
					
						
							| 
									
										
										
										
											2014-10-29 18:38:33 -07:00
										 |  |  | #include "core/hle/service/dsp_dsp.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // Namespace DSP_DSP
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace DSP_DSP { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-27 22:01:48 -04:00
										 |  |  | static u32 read_pipe_count; | 
					
						
							| 
									
										
										
										
											2015-01-23 03:11:25 -02:00
										 |  |  | static Kernel::SharedPtr<Kernel::Event> semaphore_event; | 
					
						
							|  |  |  | static Kernel::SharedPtr<Kernel::Event> interrupt_event; | 
					
						
							| 
									
										
										
										
											2015-01-05 00:19:28 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | void SignalInterrupt() { | 
					
						
							|  |  |  |     // TODO(bunnei): This is just a stub, it does not do anything other than signal to the emulated
 | 
					
						
							|  |  |  |     // application that a DSP interrupt occurred, without specifying which one. Since we do not
 | 
					
						
							|  |  |  |     // emulate the DSP yet (and how it works is largely unknown), this is a work around to get games
 | 
					
						
							|  |  |  |     // that check the DSP interrupt signal event to run. We should figure out the different types of
 | 
					
						
							|  |  |  |     // DSP interrupts, and trigger them at the appropriate times.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-15 18:20:58 -05:00
										 |  |  |     if (interrupt_event != 0) | 
					
						
							| 
									
										
										
										
											2015-01-23 03:11:25 -02:00
										 |  |  |         interrupt_event->Signal(); | 
					
						
							| 
									
										
										
										
											2015-01-05 00:19:28 -05:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-11-26 14:30:53 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-01 00:31:37 -08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * DSP_DSP::ConvertProcessAddressFromDspDram service function | 
					
						
							|  |  |  |  *  Inputs: | 
					
						
							|  |  |  |  *      1 : Address | 
					
						
							|  |  |  |  *  Outputs: | 
					
						
							|  |  |  |  *      1 : Result of function, 0 on success, otherwise error code | 
					
						
							|  |  |  |  *      2 : (inaddr << 1) + 0x1FF40000 (where 0x1FF00000 is the DSP RAM address) | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-02-13 10:40:07 -05:00
										 |  |  | static void ConvertProcessAddressFromDspDram(Service::Interface* self) { | 
					
						
							| 
									
										
										
										
											2014-12-14 03:30:11 -02:00
										 |  |  |     u32* cmd_buff = Kernel::GetCommandBuffer(); | 
					
						
							| 
									
										
										
										
											2014-12-01 00:31:37 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     u32 addr = cmd_buff[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     cmd_buff[1] = 0; // No error
 | 
					
						
							|  |  |  |     cmd_buff[2] = (addr << 1) + (Memory::DSP_MEMORY_VADDR + 0x40000); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-09 00:11:03 -07:00
										 |  |  |     LOG_WARNING(Service_DSP, "(STUBBED) called with address 0x%08X", addr); | 
					
						
							| 
									
										
										
										
											2014-12-01 00:31:37 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-26 14:30:53 -05:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * DSP_DSP::LoadComponent service function | 
					
						
							|  |  |  |  *  Inputs: | 
					
						
							|  |  |  |  *      1 : Size | 
					
						
							|  |  |  |  *      2 : Unknown (observed only half word used) | 
					
						
							|  |  |  |  *      3 : Unknown (observed only half word used) | 
					
						
							|  |  |  |  *      4 : (size << 4) | 0xA | 
					
						
							|  |  |  |  *      5 : Buffer address | 
					
						
							|  |  |  |  *  Outputs: | 
					
						
							|  |  |  |  *      1 : Result of function, 0 on success, otherwise error code | 
					
						
							|  |  |  |  *      2 : Component loaded, 0 on not loaded, 1 on loaded | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-02-13 10:40:07 -05:00
										 |  |  | static void LoadComponent(Service::Interface* self) { | 
					
						
							| 
									
										
										
										
											2014-12-14 03:30:11 -02:00
										 |  |  |     u32* cmd_buff = Kernel::GetCommandBuffer(); | 
					
						
							| 
									
										
										
										
											2014-11-26 14:30:53 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-09 00:11:03 -07:00
										 |  |  |     u32 size       = cmd_buff[1]; | 
					
						
							|  |  |  |     u32 unk1       = cmd_buff[2]; | 
					
						
							|  |  |  |     u32 unk2       = cmd_buff[3]; | 
					
						
							|  |  |  |     u32 new_size   = cmd_buff[4]; | 
					
						
							|  |  |  |     u32 buffer     = cmd_buff[5]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-26 14:30:53 -05:00
										 |  |  |     cmd_buff[1] = 0; // No error
 | 
					
						
							|  |  |  |     cmd_buff[2] = 1; // Pretend that we actually loaded the DSP firmware
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // TODO(bunnei): Implement real DSP firmware loading
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-09 00:11:03 -07:00
										 |  |  |     LOG_WARNING(Service_DSP, "(STUBBED) called size=0x%X, unk1=0x%08X, unk2=0x%08X, new_size=0x%X, buffer=0x%08X", | 
					
						
							|  |  |  |                 size, unk1, unk2, new_size, buffer); | 
					
						
							| 
									
										
										
										
											2014-11-26 14:30:53 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * DSP_DSP::GetSemaphoreEventHandle service function | 
					
						
							|  |  |  |  *  Outputs: | 
					
						
							|  |  |  |  *      1 : Result of function, 0 on success, otherwise error code | 
					
						
							|  |  |  |  *      3 : Semaphore event handle | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-02-13 10:40:07 -05:00
										 |  |  | static void GetSemaphoreEventHandle(Service::Interface* self) { | 
					
						
							| 
									
										
										
										
											2014-12-14 03:30:11 -02:00
										 |  |  |     u32* cmd_buff = Kernel::GetCommandBuffer(); | 
					
						
							| 
									
										
										
										
											2014-11-26 14:30:53 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-23 03:11:25 -02:00
										 |  |  |     cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 | 
					
						
							|  |  |  |     cmd_buff[3] = Kernel::g_handle_table.Create(semaphore_event).MoveFrom(); // Event handle
 | 
					
						
							| 
									
										
										
										
											2014-11-26 14:30:53 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-05 23:53:49 -02:00
										 |  |  |     LOG_WARNING(Service_DSP, "(STUBBED) called"); | 
					
						
							| 
									
										
										
										
											2014-11-26 14:30:53 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-07 17:54:16 -08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * DSP_DSP::FlushDataCache service function | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This Function is a no-op, We aren't emulating the CPU cache any time soon. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Inputs: | 
					
						
							|  |  |  |  *      1 : Address | 
					
						
							|  |  |  |  *      2 : Size | 
					
						
							|  |  |  |  *      3 : Value 0, some descriptor for the KProcess Handle | 
					
						
							|  |  |  |  *      4 : KProcess handle | 
					
						
							|  |  |  |  *  Outputs: | 
					
						
							|  |  |  |  *      1 : Result of function, 0 on success, otherwise error code | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static void FlushDataCache(Service::Interface* self) { | 
					
						
							|  |  |  |     u32* cmd_buff = Kernel::GetCommandBuffer(); | 
					
						
							|  |  |  |     u32 address = cmd_buff[1]; | 
					
						
							|  |  |  |     u32 size    = cmd_buff[2]; | 
					
						
							|  |  |  |     u32 process = cmd_buff[4]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // TODO(purpasmart96): Verify return header on HW
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-09 00:11:03 -07:00
										 |  |  |     LOG_DEBUG(Service_DSP, "(STUBBED) called address=0x%08X, size=0x%X, process=0x%08X", | 
					
						
							| 
									
										
										
										
											2015-03-07 17:54:16 -08:00
										 |  |  |               address, size, process); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-26 14:30:53 -05:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * DSP_DSP::RegisterInterruptEvents service function | 
					
						
							|  |  |  |  *  Inputs: | 
					
						
							|  |  |  |  *      1 : Parameter 0 (purpose unknown) | 
					
						
							|  |  |  |  *      2 : Parameter 1 (purpose unknown) | 
					
						
							|  |  |  |  *      4 : Interrupt event handle | 
					
						
							|  |  |  |  *  Outputs: | 
					
						
							|  |  |  |  *      1 : Result of function, 0 on success, otherwise error code | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-02-13 10:40:07 -05:00
										 |  |  | static void RegisterInterruptEvents(Service::Interface* self) { | 
					
						
							| 
									
										
										
										
											2014-12-14 03:30:11 -02:00
										 |  |  |     u32* cmd_buff = Kernel::GetCommandBuffer(); | 
					
						
							| 
									
										
										
										
											2014-11-26 14:30:53 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-09 00:11:03 -07:00
										 |  |  |     u32 param0 = cmd_buff[1]; | 
					
						
							|  |  |  |     u32 param1 = cmd_buff[2]; | 
					
						
							|  |  |  |     u32 event_handle = cmd_buff[4]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-23 03:11:25 -02:00
										 |  |  |     auto evt = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]); | 
					
						
							|  |  |  |     if (evt != nullptr) { | 
					
						
							|  |  |  |         interrupt_event = evt; | 
					
						
							|  |  |  |         cmd_buff[1] = 0; // No error
 | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         LOG_ERROR(Service_DSP, "called with invalid handle=%08X", cmd_buff[4]); | 
					
						
							| 
									
										
										
										
											2014-11-26 14:30:53 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-23 03:11:25 -02:00
										 |  |  |         // TODO(yuriks): An error should be returned from SendSyncRequest, not in the cmdbuf
 | 
					
						
							|  |  |  |         cmd_buff[1] = -1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-26 14:30:53 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-09 00:11:03 -07:00
										 |  |  |     LOG_WARNING(Service_DSP, "(STUBBED) called param0=%u, param1=%u, event_handle=0x%08X", param0, param1, event_handle); | 
					
						
							| 
									
										
										
										
											2014-11-26 14:30:53 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * DSP_DSP::WriteReg0x10 service function | 
					
						
							|  |  |  |  *  Inputs: | 
					
						
							|  |  |  |  *      1 : Unknown (observed only half word used) | 
					
						
							|  |  |  |  *  Outputs: | 
					
						
							|  |  |  |  *      1 : Result of function, 0 on success, otherwise error code | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-02-13 10:40:07 -05:00
										 |  |  | static void WriteReg0x10(Service::Interface* self) { | 
					
						
							| 
									
										
										
										
											2014-12-14 03:30:11 -02:00
										 |  |  |     u32* cmd_buff = Kernel::GetCommandBuffer(); | 
					
						
							| 
									
										
										
										
											2014-11-26 14:30:53 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-05 00:19:28 -05:00
										 |  |  |     SignalInterrupt(); | 
					
						
							| 
									
										
										
										
											2014-11-26 14:30:53 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     cmd_buff[1] = 0; // No error
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-05 23:53:49 -02:00
										 |  |  |     LOG_WARNING(Service_DSP, "(STUBBED) called"); | 
					
						
							| 
									
										
										
										
											2014-11-26 14:30:53 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-31 15:11:51 -08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * DSP_DSP::WriteProcessPipe service function | 
					
						
							|  |  |  |  *  Inputs: | 
					
						
							|  |  |  |  *      1 : Number | 
					
						
							|  |  |  |  *      2 : Size | 
					
						
							|  |  |  |  *      3 : (size <<14) | 0x402 | 
					
						
							|  |  |  |  *      4 : Buffer | 
					
						
							|  |  |  |  *  Outputs: | 
					
						
							|  |  |  |  *      0 : Return header | 
					
						
							|  |  |  |  *      1 : Result of function, 0 on success, otherwise error code | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-02-13 10:40:07 -05:00
										 |  |  | static void WriteProcessPipe(Service::Interface* self) { | 
					
						
							| 
									
										
										
										
											2015-01-31 15:11:51 -08:00
										 |  |  |     u32* cmd_buff = Kernel::GetCommandBuffer(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     u32 number   = cmd_buff[1]; | 
					
						
							|  |  |  |     u32 size     = cmd_buff[2]; | 
					
						
							|  |  |  |     u32 new_size = cmd_buff[3]; | 
					
						
							|  |  |  |     u32 buffer   = cmd_buff[4]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-09 00:11:03 -07:00
										 |  |  |     LOG_WARNING(Service_DSP, "(STUBBED) called number=%u, size=0x%X, new_size=0x%X, buffer=0x%08X", | 
					
						
							| 
									
										
										
										
											2015-01-31 15:11:51 -08:00
										 |  |  |                 number, size, new_size, buffer); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-10 00:31:00 -05:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * DSP_DSP::ReadPipeIfPossible service function | 
					
						
							|  |  |  |  *  Inputs: | 
					
						
							|  |  |  |  *      1 : Unknown | 
					
						
							|  |  |  |  *      2 : Unknown | 
					
						
							|  |  |  |  *      3 : Size in bytes of read (observed only lower half word used) | 
					
						
							|  |  |  |  *      0x41 : Virtual address to read from DSP pipe to in memory | 
					
						
							|  |  |  |  *  Outputs: | 
					
						
							|  |  |  |  *      1 : Result of function, 0 on success, otherwise error code | 
					
						
							|  |  |  |  *      2 : Number of bytes read from pipe | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-02-13 10:40:07 -05:00
										 |  |  | static void ReadPipeIfPossible(Service::Interface* self) { | 
					
						
							| 
									
										
										
										
											2014-12-14 03:30:11 -02:00
										 |  |  |     u32* cmd_buff = Kernel::GetCommandBuffer(); | 
					
						
							| 
									
										
										
										
											2014-12-10 00:31:00 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-09 00:11:03 -07:00
										 |  |  |     u32 unk1 = cmd_buff[1]; | 
					
						
							|  |  |  |     u32 unk2 = cmd_buff[2]; | 
					
						
							| 
									
										
										
										
											2014-12-10 00:31:00 -05:00
										 |  |  |     u32 size = cmd_buff[3] & 0xFFFF;// Lower 16 bits are size
 | 
					
						
							|  |  |  |     VAddr addr = cmd_buff[0x41]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Canned DSP responses that games expect. These were taken from HW by 3dmoo team.
 | 
					
						
							|  |  |  |     // TODO: Remove this hack :)
 | 
					
						
							|  |  |  |     static const std::array<u16, 16> canned_read_pipe = { | 
					
						
							|  |  |  |         0x000F, 0xBFFF, 0x9E8E, 0x8680, 0xA78E, 0x9430, 0x8400, 0x8540, | 
					
						
							|  |  |  |         0x948E, 0x8710, 0x8410, 0xA90E, 0xAA0E, 0xAACE, 0xAC4E, 0xAC58 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     u32 initial_size = read_pipe_count; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (unsigned offset = 0; offset < size; offset += sizeof(u16)) { | 
					
						
							|  |  |  |         if (read_pipe_count < canned_read_pipe.size()) { | 
					
						
							|  |  |  |             Memory::Write16(addr + offset, canned_read_pipe[read_pipe_count]); | 
					
						
							|  |  |  |             read_pipe_count++; | 
					
						
							|  |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2014-12-05 23:53:49 -02:00
										 |  |  |             LOG_ERROR(Service_DSP, "canned read pipe log exceeded!"); | 
					
						
							| 
									
										
										
										
											2014-12-10 00:31:00 -05:00
										 |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     cmd_buff[1] = 0; // No error
 | 
					
						
							|  |  |  |     cmd_buff[2] = (read_pipe_count - initial_size) * sizeof(u16); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-09 00:11:03 -07:00
										 |  |  |     LOG_WARNING(Service_DSP, "(STUBBED) called unk1=0x%08X, unk2=0x%08X, size=0x%X, buffer=0x%08X", | 
					
						
							|  |  |  |                 unk1, unk2, size, addr); | 
					
						
							| 
									
										
										
										
											2014-12-10 00:31:00 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-31 15:11:51 -08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * DSP_DSP::SetSemaphoreMask service function | 
					
						
							|  |  |  |  *  Inputs: | 
					
						
							|  |  |  |  *      1 : Mask | 
					
						
							|  |  |  |  *  Outputs: | 
					
						
							|  |  |  |  *      1 : Result of function, 0 on success, otherwise error code | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-02-13 10:40:07 -05:00
										 |  |  | static void SetSemaphoreMask(Service::Interface* self) { | 
					
						
							| 
									
										
										
										
											2015-01-31 15:11:51 -08:00
										 |  |  |     u32* cmd_buff = Kernel::GetCommandBuffer(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     u32 mask = cmd_buff[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     LOG_WARNING(Service_DSP, "(STUBBED) called mask=0x%08X", mask); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * DSP_DSP::GetHeadphoneStatus service function | 
					
						
							|  |  |  |  *  Inputs: | 
					
						
							|  |  |  |  *      1 : None | 
					
						
							|  |  |  |  *  Outputs: | 
					
						
							|  |  |  |  *      1 : Result of function, 0 on success, otherwise error code | 
					
						
							|  |  |  |  *      2 : The headphone status response, 0 = Not using headphones?, | 
					
						
							|  |  |  |  *          1 = using headphones? | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-02-13 10:40:07 -05:00
										 |  |  | static void GetHeadphoneStatus(Service::Interface* self) { | 
					
						
							| 
									
										
										
										
											2015-01-31 15:11:51 -08:00
										 |  |  |     u32* cmd_buff = Kernel::GetCommandBuffer(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 | 
					
						
							|  |  |  |     cmd_buff[2] = 0; // Not using headphones?
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-07 17:54:16 -08:00
										 |  |  |     LOG_DEBUG(Service_DSP, "(STUBBED) called"); | 
					
						
							| 
									
										
										
										
											2015-01-31 15:11:51 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-29 18:38:33 -07:00
										 |  |  | const Interface::FunctionInfo FunctionTable[] = { | 
					
						
							| 
									
										
										
										
											2014-12-01 00:31:37 -08:00
										 |  |  |     {0x00010040, nullptr,                          "RecvData"}, | 
					
						
							|  |  |  |     {0x00020040, nullptr,                          "RecvDataIsReady"}, | 
					
						
							|  |  |  |     {0x00030080, nullptr,                          "SendData"}, | 
					
						
							|  |  |  |     {0x00040040, nullptr,                          "SendDataIsEmpty"}, | 
					
						
							|  |  |  |     {0x00070040, WriteReg0x10,                     "WriteReg0x10"}, | 
					
						
							|  |  |  |     {0x00080000, nullptr,                          "GetSemaphore"}, | 
					
						
							|  |  |  |     {0x00090040, nullptr,                          "ClearSemaphore"}, | 
					
						
							|  |  |  |     {0x000B0000, nullptr,                          "CheckSemaphoreRequest"}, | 
					
						
							|  |  |  |     {0x000C0040, ConvertProcessAddressFromDspDram, "ConvertProcessAddressFromDspDram"}, | 
					
						
							| 
									
										
										
										
											2015-01-31 15:11:51 -08:00
										 |  |  |     {0x000D0082, WriteProcessPipe,                 "WriteProcessPipe"}, | 
					
						
							| 
									
										
										
										
											2014-12-10 00:31:00 -05:00
										 |  |  |     {0x001000C0, ReadPipeIfPossible,               "ReadPipeIfPossible"}, | 
					
						
							| 
									
										
										
										
											2014-12-01 00:31:37 -08:00
										 |  |  |     {0x001100C2, LoadComponent,                    "LoadComponent"}, | 
					
						
							|  |  |  |     {0x00120000, nullptr,                          "UnloadComponent"}, | 
					
						
							| 
									
										
										
										
											2015-03-07 17:54:16 -08:00
										 |  |  |     {0x00130082, FlushDataCache,                   "FlushDataCache"}, | 
					
						
							| 
									
										
										
										
											2014-12-01 00:31:37 -08:00
										 |  |  |     {0x00140082, nullptr,                          "InvalidateDCache"}, | 
					
						
							|  |  |  |     {0x00150082, RegisterInterruptEvents,          "RegisterInterruptEvents"}, | 
					
						
							|  |  |  |     {0x00160000, GetSemaphoreEventHandle,          "GetSemaphoreEventHandle"}, | 
					
						
							| 
									
										
										
										
											2015-01-31 15:11:51 -08:00
										 |  |  |     {0x00170040, SetSemaphoreMask,                 "SetSemaphoreMask"}, | 
					
						
							| 
									
										
										
										
											2014-12-01 00:31:37 -08:00
										 |  |  |     {0x00180040, nullptr,                          "GetPhysicalAddress"}, | 
					
						
							|  |  |  |     {0x00190040, nullptr,                          "GetVirtualAddress"}, | 
					
						
							|  |  |  |     {0x001A0042, nullptr,                          "SetIirFilterI2S1_cmd1"}, | 
					
						
							|  |  |  |     {0x001B0042, nullptr,                          "SetIirFilterI2S1_cmd2"}, | 
					
						
							|  |  |  |     {0x001C0082, nullptr,                          "SetIirFilterEQ"}, | 
					
						
							| 
									
										
										
										
											2015-01-31 15:11:51 -08:00
										 |  |  |     {0x001F0000, GetHeadphoneStatus,               "GetHeadphoneStatus"}, | 
					
						
							| 
									
										
										
										
											2014-12-01 00:31:37 -08:00
										 |  |  |     {0x00210000, nullptr,                          "GetIsDspOccupied"}, | 
					
						
							| 
									
										
										
										
											2014-10-29 18:38:33 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // Interface class
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Interface::Interface() { | 
					
						
							| 
									
										
										
										
											2015-02-01 00:14:40 -02:00
										 |  |  |     semaphore_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "DSP_DSP::semaphore_event"); | 
					
						
							| 
									
										
										
										
											2015-01-23 03:11:25 -02:00
										 |  |  |     interrupt_event = nullptr; | 
					
						
							| 
									
										
										
										
											2014-12-10 00:31:00 -05:00
										 |  |  |     read_pipe_count = 0; | 
					
						
							| 
									
										
										
										
											2014-11-26 14:30:53 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-30 16:56:49 -02:00
										 |  |  |     Register(FunctionTable); | 
					
						
							| 
									
										
										
										
											2014-10-29 18:38:33 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // namespace
 |