audio_core/hle,lle: implement UnloadComponent

This commit is contained in:
Weiyi Wang 2018-12-06 09:50:55 -05:00
parent 9b41e6f85f
commit 6f6ffceec4
7 changed files with 65 additions and 1 deletions

View file

@ -91,6 +91,9 @@ public:
/// Loads the DSP program /// Loads the DSP program
virtual void LoadComponent(const std::vector<u8>& buffer) = 0; virtual void LoadComponent(const std::vector<u8>& buffer) = 0;
/// Unloads the DSP program
virtual void UnloadComponent() = 0;
/// Select the sink to use based on sink id. /// Select the sink to use based on sink id.
void SetSink(const std::string& sink_id, const std::string& audio_device); void SetSink(const std::string& sink_id, const std::string& audio_device);
/// Get the current sink /// Get the current sink

View file

@ -411,4 +411,8 @@ void DspHle::LoadComponent(const std::vector<u8>& component_data) {
} }
} }
void DspHle::UnloadComponent() {
// Do nothing
}
} // namespace AudioCore } // namespace AudioCore

View file

@ -36,6 +36,7 @@ public:
void SetServiceToInterrupt(std::weak_ptr<Service::DSP::DSP_DSP> dsp) override; void SetServiceToInterrupt(std::weak_ptr<Service::DSP::DSP_DSP> dsp) override;
void LoadComponent(const std::vector<u8>& buffer) override; void LoadComponent(const std::vector<u8>& buffer) override;
void UnloadComponent() override;
private: private:
struct Impl; struct Impl;

View file

@ -109,6 +109,7 @@ struct DspLle::Impl final {
bool data_signaled = false; bool data_signaled = false;
Core::TimingEventType* teakra_slice_event; Core::TimingEventType* teakra_slice_event;
bool loaded = false;
static constexpr unsigned TeakraSlice = 20000; static constexpr unsigned TeakraSlice = 20000;
void RunTeakraSlice() { void RunTeakraSlice() {
@ -238,11 +239,17 @@ struct DspLle::Impl final {
} }
void LoadComponent(const std::vector<u8>& buffer) { void LoadComponent(const std::vector<u8>& buffer) {
if (loaded) {
LOG_ERROR(Audio_DSP, "Component already loaded!");
return;
}
teakra.Reset();
Dsp1 dsp(buffer); Dsp1 dsp(buffer);
auto& dsp_memory = teakra.GetDspMemory(); auto& dsp_memory = teakra.GetDspMemory();
u8* program = dsp_memory.data(); u8* program = dsp_memory.data();
u8* data = dsp_memory.data() + 0x40000; u8* data = dsp_memory.data() + 0x40000;
dsp_memory.fill(0);
for (const auto& segment : dsp.segments) { for (const auto& segment : dsp.segments) {
if (segment.memory_type == SegmentType::ProgramA || if (segment.memory_type == SegmentType::ProgramA ||
segment.memory_type == SegmentType::ProgramB) { segment.memory_type == SegmentType::ProgramB) {
@ -269,6 +276,30 @@ struct DspLle::Impl final {
while (!teakra.RecvDataIsReady(2)) while (!teakra.RecvDataIsReady(2))
RunTeakraSlice(); RunTeakraSlice();
pipe_base_waddr = teakra.RecvData(2); 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<u8>& buffer) {
impl->LoadComponent(buffer); impl->LoadComponent(buffer);
} }
void DspLle::UnloadComponent() {
impl->UnloadComponent();
}
DspLle::DspLle() : impl(std::make_unique<Impl>()) {} DspLle::DspLle() : impl(std::make_unique<Impl>()) {}
DspLle::~DspLle() = default; DspLle::~DspLle() = default;

View file

@ -25,6 +25,7 @@ public:
void SetServiceToInterrupt(std::weak_ptr<Service::DSP::DSP_DSP> dsp) override; void SetServiceToInterrupt(std::weak_ptr<Service::DSP::DSP_DSP> dsp) override;
void LoadComponent(const std::vector<u8>& buffer) override; void LoadComponent(const std::vector<u8>& buffer) override;
void UnloadComponent() override;
private: private:
struct Impl; struct Impl;

View file

@ -184,6 +184,17 @@ void DSP_DSP::LoadComponent(Kernel::HLERequestContext& ctx) {
size, prog_mask, data_mask); 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) { void DSP_DSP::FlushDataCache(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x13, 2, 2); IPC::RequestParser rp(ctx, 0x13, 2, 2);
const VAddr address = rp.Pop<u32>(); const VAddr address = rp.Pop<u32>();

View file

@ -153,6 +153,15 @@ private:
*/ */
void LoadComponent(Kernel::HLERequestContext& ctx); 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 * DSP_DSP::FlushDataCache service function
* *