From 6f6ffceec4cc9e1652af8eca4a3cf908570d33d3 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Thu, 6 Dec 2018 09:50:55 -0500 Subject: [PATCH] audio_core/hle,lle: implement UnloadComponent --- src/audio_core/dsp_interface.h | 3 +++ src/audio_core/hle/hle.cpp | 4 +++ src/audio_core/hle/hle.h | 1 + src/audio_core/lle/lle.cpp | 37 +++++++++++++++++++++++++++- src/audio_core/lle/lle.h | 1 + src/core/hle/service/dsp/dsp_dsp.cpp | 11 +++++++++ src/core/hle/service/dsp/dsp_dsp.h | 9 +++++++ 7 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/audio_core/dsp_interface.h b/src/audio_core/dsp_interface.h index eab08d5f8..7a16dea0f 100644 --- a/src/audio_core/dsp_interface.h +++ b/src/audio_core/dsp_interface.h @@ -91,6 +91,9 @@ public: /// Loads the DSP program virtual void LoadComponent(const std::vector& buffer) = 0; + /// Unloads the DSP program + virtual void UnloadComponent() = 0; + /// Select the sink to use based on sink id. void SetSink(const std::string& sink_id, const std::string& audio_device); /// Get the current sink diff --git a/src/audio_core/hle/hle.cpp b/src/audio_core/hle/hle.cpp index 4b490d9bb..6e7b45278 100644 --- a/src/audio_core/hle/hle.cpp +++ b/src/audio_core/hle/hle.cpp @@ -411,4 +411,8 @@ void DspHle::LoadComponent(const std::vector& component_data) { } } +void DspHle::UnloadComponent() { + // Do nothing +} + } // namespace AudioCore diff --git a/src/audio_core/hle/hle.h b/src/audio_core/hle/hle.h index a472ca3c2..4ab468331 100644 --- a/src/audio_core/hle/hle.h +++ b/src/audio_core/hle/hle.h @@ -36,6 +36,7 @@ public: void SetServiceToInterrupt(std::weak_ptr dsp) override; void LoadComponent(const std::vector& buffer) override; + void UnloadComponent() override; private: struct Impl; diff --git a/src/audio_core/lle/lle.cpp b/src/audio_core/lle/lle.cpp index feb4b1e86..a7f46a913 100644 --- a/src/audio_core/lle/lle.cpp +++ b/src/audio_core/lle/lle.cpp @@ -109,6 +109,7 @@ struct DspLle::Impl final { bool data_signaled = false; Core::TimingEventType* teakra_slice_event; + bool loaded = false; static constexpr unsigned TeakraSlice = 20000; void RunTeakraSlice() { @@ -238,11 +239,17 @@ struct DspLle::Impl final { } void LoadComponent(const std::vector& buffer) { + if (loaded) { + LOG_ERROR(Audio_DSP, "Component already loaded!"); + return; + } + + teakra.Reset(); + Dsp1 dsp(buffer); auto& dsp_memory = teakra.GetDspMemory(); u8* program = dsp_memory.data(); u8* data = dsp_memory.data() + 0x40000; - dsp_memory.fill(0); for (const auto& segment : dsp.segments) { if (segment.memory_type == SegmentType::ProgramA || segment.memory_type == SegmentType::ProgramB) { @@ -269,6 +276,30 @@ struct DspLle::Impl final { while (!teakra.RecvDataIsReady(2)) RunTeakraSlice(); pipe_base_waddr = teakra.RecvData(2); + + loaded = true; + } + + void UnloadComponent() { + if (!loaded) { + LOG_ERROR(Audio_DSP, "Component not loaded!"); + return; + } + + // Send finalization signal + while (!teakra.SendDataIsEmpty(2)) + RunTeakraSlice(); + + teakra.SendData(2, 0x8000); + + // Wait for completion + while (!teakra.RecvDataIsReady(2)) + RunTeakraSlice(); + + teakra.RecvData(2); // discard the value + + Core::System::GetInstance().CoreTiming().UnscheduleEvent(teakra_slice_event, 0); + loaded = false; } }; @@ -354,6 +385,10 @@ void DspLle::LoadComponent(const std::vector& buffer) { impl->LoadComponent(buffer); } +void DspLle::UnloadComponent() { + impl->UnloadComponent(); +} + DspLle::DspLle() : impl(std::make_unique()) {} DspLle::~DspLle() = default; diff --git a/src/audio_core/lle/lle.h b/src/audio_core/lle/lle.h index 1e9302ed0..002de8aa7 100644 --- a/src/audio_core/lle/lle.h +++ b/src/audio_core/lle/lle.h @@ -25,6 +25,7 @@ public: void SetServiceToInterrupt(std::weak_ptr dsp) override; void LoadComponent(const std::vector& buffer) override; + void UnloadComponent() override; private: struct Impl; diff --git a/src/core/hle/service/dsp/dsp_dsp.cpp b/src/core/hle/service/dsp/dsp_dsp.cpp index fec7ad7bf..c885b73fa 100644 --- a/src/core/hle/service/dsp/dsp_dsp.cpp +++ b/src/core/hle/service/dsp/dsp_dsp.cpp @@ -184,6 +184,17 @@ void DSP_DSP::LoadComponent(Kernel::HLERequestContext& ctx) { size, prog_mask, data_mask); } +void DSP_DSP::UnloadComponent(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp(ctx, 0x12, 0, 0); + + system.DSP().UnloadComponent(); + + IPC::RequestBuilder rb = rp.MakeBuilder(1, 0); + rb.Push(RESULT_SUCCESS); + + LOG_INFO(Service_DSP, "(STUBBED)"); +} + void DSP_DSP::FlushDataCache(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp(ctx, 0x13, 2, 2); const VAddr address = rp.Pop(); diff --git a/src/core/hle/service/dsp/dsp_dsp.h b/src/core/hle/service/dsp/dsp_dsp.h index 78651bad8..2bc601511 100644 --- a/src/core/hle/service/dsp/dsp_dsp.h +++ b/src/core/hle/service/dsp/dsp_dsp.h @@ -153,6 +153,15 @@ private: */ void LoadComponent(Kernel::HLERequestContext& ctx); + /** + * DSP_DSP::UnloadComponent service function + * Inputs: + * 0 : Header Code[0x00120000] + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ + void UnloadComponent(Kernel::HLERequestContext& ctx); + /** * DSP_DSP::FlushDataCache service function *