early-access version 4064
This commit is contained in:
parent
b82964292d
commit
b820406e60
13 changed files with 110 additions and 105 deletions
|
@ -1,7 +1,7 @@
|
||||||
yuzu emulator early access
|
yuzu emulator early access
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This is the source code for early-access 4063.
|
This is the source code for early-access 4064.
|
||||||
|
|
||||||
## Legal Notice
|
## Legal Notice
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
#include "core/guest_memory.h"
|
#include "core/guest_memory.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
|
#include "core/hle/kernel/k_process.h"
|
||||||
|
|
||||||
namespace AudioCore {
|
namespace AudioCore {
|
||||||
|
|
||||||
using namespace std::literals;
|
using namespace std::literals;
|
||||||
|
@ -26,7 +28,7 @@ DeviceSession::~DeviceSession() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DeviceSession::Initialize(std::string_view name_, SampleFormat sample_format_,
|
Result DeviceSession::Initialize(std::string_view name_, SampleFormat sample_format_,
|
||||||
u16 channel_count_, size_t session_id_, u32 handle_,
|
u16 channel_count_, size_t session_id_, Kernel::KProcess* handle_,
|
||||||
u64 applet_resource_user_id_, Sink::StreamType type_) {
|
u64 applet_resource_user_id_, Sink::StreamType type_) {
|
||||||
if (stream) {
|
if (stream) {
|
||||||
Finalize();
|
Finalize();
|
||||||
|
@ -37,6 +39,7 @@ Result DeviceSession::Initialize(std::string_view name_, SampleFormat sample_for
|
||||||
channel_count = channel_count_;
|
channel_count = channel_count_;
|
||||||
session_id = session_id_;
|
session_id = session_id_;
|
||||||
handle = handle_;
|
handle = handle_;
|
||||||
|
handle->Open();
|
||||||
applet_resource_user_id = applet_resource_user_id_;
|
applet_resource_user_id = applet_resource_user_id_;
|
||||||
|
|
||||||
if (type == Sink::StreamType::In) {
|
if (type == Sink::StreamType::In) {
|
||||||
|
@ -55,6 +58,11 @@ void DeviceSession::Finalize() {
|
||||||
sink->CloseStream(stream);
|
sink->CloseStream(stream);
|
||||||
stream = nullptr;
|
stream = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (handle) {
|
||||||
|
handle->Close();
|
||||||
|
handle = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceSession::Start() {
|
void DeviceSession::Start() {
|
||||||
|
@ -92,7 +100,7 @@ void DeviceSession::AppendBuffers(std::span<const AudioBuffer> buffers) {
|
||||||
stream->AppendBuffer(new_buffer, tmp_samples);
|
stream->AppendBuffer(new_buffer, tmp_samples);
|
||||||
} else {
|
} else {
|
||||||
Core::Memory::CpuGuestMemory<s16, Core::Memory::GuestMemoryFlags::UnsafeRead> samples(
|
Core::Memory::CpuGuestMemory<s16, Core::Memory::GuestMemoryFlags::UnsafeRead> samples(
|
||||||
system.ApplicationMemory(), buffer.samples, buffer.size / sizeof(s16));
|
handle->GetMemory(), buffer.samples, buffer.size / sizeof(s16));
|
||||||
stream->AppendBuffer(new_buffer, samples);
|
stream->AppendBuffer(new_buffer, samples);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,7 +109,7 @@ void DeviceSession::AppendBuffers(std::span<const AudioBuffer> buffers) {
|
||||||
void DeviceSession::ReleaseBuffer(const AudioBuffer& buffer) const {
|
void DeviceSession::ReleaseBuffer(const AudioBuffer& buffer) const {
|
||||||
if (type == Sink::StreamType::In) {
|
if (type == Sink::StreamType::In) {
|
||||||
auto samples{stream->ReleaseBuffer(buffer.size / sizeof(s16))};
|
auto samples{stream->ReleaseBuffer(buffer.size / sizeof(s16))};
|
||||||
system.ApplicationMemory().WriteBlockUnsafe(buffer.samples, samples.data(), buffer.size);
|
handle->GetMemory().WriteBlockUnsafe(buffer.samples, samples.data(), buffer.size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,10 @@ struct EventType;
|
||||||
} // namespace Timing
|
} // namespace Timing
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
class KProcess;
|
||||||
|
} // namespace Kernel
|
||||||
|
|
||||||
namespace AudioCore {
|
namespace AudioCore {
|
||||||
|
|
||||||
namespace Sink {
|
namespace Sink {
|
||||||
|
@ -44,13 +48,13 @@ public:
|
||||||
* @param sample_format - Sample format for this device's output.
|
* @param sample_format - Sample format for this device's output.
|
||||||
* @param channel_count - Number of channels for this device (2 or 6).
|
* @param channel_count - Number of channels for this device (2 or 6).
|
||||||
* @param session_id - This session's id.
|
* @param session_id - This session's id.
|
||||||
* @param handle - Handle for this device session (unused).
|
* @param handle - Process handle for this device session.
|
||||||
* @param applet_resource_user_id - Applet resource user id for this device session (unused).
|
* @param applet_resource_user_id - Applet resource user id for this device session (unused).
|
||||||
* @param type - Type of this stream (Render, In, Out).
|
* @param type - Type of this stream (Render, In, Out).
|
||||||
* @return Result code for this call.
|
* @return Result code for this call.
|
||||||
*/
|
*/
|
||||||
Result Initialize(std::string_view name, SampleFormat sample_format, u16 channel_count,
|
Result Initialize(std::string_view name, SampleFormat sample_format, u16 channel_count,
|
||||||
size_t session_id, u32 handle, u64 applet_resource_user_id,
|
size_t session_id, Kernel::KProcess* handle, u64 applet_resource_user_id,
|
||||||
Sink::StreamType type);
|
Sink::StreamType type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -137,8 +141,8 @@ private:
|
||||||
u16 channel_count{};
|
u16 channel_count{};
|
||||||
/// Session id of this device session
|
/// Session id of this device session
|
||||||
size_t session_id{};
|
size_t session_id{};
|
||||||
/// Handle of this device session
|
/// Process handle of device memory owner
|
||||||
u32 handle{};
|
Kernel::KProcess* handle{};
|
||||||
/// Applet resource user id of this device session
|
/// Applet resource user id of this device session
|
||||||
u64 applet_resource_user_id{};
|
u64 applet_resource_user_id{};
|
||||||
/// Total number of samples played by this device session
|
/// Total number of samples played by this device session
|
||||||
|
|
|
@ -57,7 +57,7 @@ Result System::IsConfigValid(const std::string_view device_name,
|
||||||
}
|
}
|
||||||
|
|
||||||
Result System::Initialize(std::string device_name, const AudioInParameter& in_params,
|
Result System::Initialize(std::string device_name, const AudioInParameter& in_params,
|
||||||
const u32 handle_, const u64 applet_resource_user_id_) {
|
Kernel::KProcess* handle_, const u64 applet_resource_user_id_) {
|
||||||
auto result{IsConfigValid(device_name, in_params)};
|
auto result{IsConfigValid(device_name, in_params)};
|
||||||
if (result.IsError()) {
|
if (result.IsError()) {
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -19,7 +19,8 @@ class System;
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
class KEvent;
|
class KEvent;
|
||||||
}
|
class KProcess;
|
||||||
|
} // namespace Kernel
|
||||||
|
|
||||||
namespace AudioCore::AudioIn {
|
namespace AudioCore::AudioIn {
|
||||||
|
|
||||||
|
@ -93,12 +94,12 @@ public:
|
||||||
*
|
*
|
||||||
* @param device_name - The name of the requested input device.
|
* @param device_name - The name of the requested input device.
|
||||||
* @param in_params - Input parameters, see AudioInParameter.
|
* @param in_params - Input parameters, see AudioInParameter.
|
||||||
* @param handle - Unused.
|
* @param handle - Process handle.
|
||||||
* @param applet_resource_user_id - Unused.
|
* @param applet_resource_user_id - Unused.
|
||||||
* @return Result code.
|
* @return Result code.
|
||||||
*/
|
*/
|
||||||
Result Initialize(std::string device_name, const AudioInParameter& in_params, u32 handle,
|
Result Initialize(std::string device_name, const AudioInParameter& in_params,
|
||||||
u64 applet_resource_user_id);
|
Kernel::KProcess* handle, u64 applet_resource_user_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start this system.
|
* Start this system.
|
||||||
|
@ -244,8 +245,8 @@ public:
|
||||||
private:
|
private:
|
||||||
/// Core system
|
/// Core system
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
/// (Unused)
|
/// Process handle
|
||||||
u32 handle{};
|
Kernel::KProcess* handle{};
|
||||||
/// (Unused)
|
/// (Unused)
|
||||||
u64 applet_resource_user_id{};
|
u64 applet_resource_user_id{};
|
||||||
/// Buffer event, signalled when a buffer is ready
|
/// Buffer event, signalled when a buffer is ready
|
||||||
|
|
|
@ -48,8 +48,8 @@ Result System::IsConfigValid(std::string_view device_name,
|
||||||
return Service::Audio::ResultInvalidChannelCount;
|
return Service::Audio::ResultInvalidChannelCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result System::Initialize(std::string device_name, const AudioOutParameter& in_params, u32 handle_,
|
Result System::Initialize(std::string device_name, const AudioOutParameter& in_params,
|
||||||
u64 applet_resource_user_id_) {
|
Kernel::KProcess* handle_, u64 applet_resource_user_id_) {
|
||||||
auto result = IsConfigValid(device_name, in_params);
|
auto result = IsConfigValid(device_name, in_params);
|
||||||
if (result.IsError()) {
|
if (result.IsError()) {
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -19,7 +19,8 @@ class System;
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
class KEvent;
|
class KEvent;
|
||||||
}
|
class KProcess;
|
||||||
|
} // namespace Kernel
|
||||||
|
|
||||||
namespace AudioCore::AudioOut {
|
namespace AudioCore::AudioOut {
|
||||||
|
|
||||||
|
@ -84,12 +85,12 @@ public:
|
||||||
*
|
*
|
||||||
* @param device_name - The name of the requested output device.
|
* @param device_name - The name of the requested output device.
|
||||||
* @param in_params - Input parameters, see AudioOutParameter.
|
* @param in_params - Input parameters, see AudioOutParameter.
|
||||||
* @param handle - Unused.
|
* @param handle - Process handle.
|
||||||
* @param applet_resource_user_id - Unused.
|
* @param applet_resource_user_id - Unused.
|
||||||
* @return Result code.
|
* @return Result code.
|
||||||
*/
|
*/
|
||||||
Result Initialize(std::string device_name, const AudioOutParameter& in_params, u32 handle,
|
Result Initialize(std::string device_name, const AudioOutParameter& in_params,
|
||||||
u64 applet_resource_user_id);
|
Kernel::KProcess* handle, u64 applet_resource_user_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start this system.
|
* Start this system.
|
||||||
|
@ -228,8 +229,8 @@ public:
|
||||||
private:
|
private:
|
||||||
/// Core system
|
/// Core system
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
/// (Unused)
|
/// Process handle
|
||||||
u32 handle{};
|
Kernel::KProcess* handle{};
|
||||||
/// (Unused)
|
/// (Unused)
|
||||||
u64 applet_resource_user_id{};
|
u64 applet_resource_user_id{};
|
||||||
/// Buffer event, signalled when a buffer is ready
|
/// Buffer event, signalled when a buffer is ready
|
||||||
|
|
|
@ -28,14 +28,14 @@ Result KMemoryBlockManager::Initialize(KProcessAddress st, KProcessAddress nd,
|
||||||
}
|
}
|
||||||
|
|
||||||
void KMemoryBlockManager::Finalize(KMemoryBlockSlabManager* slab_manager,
|
void KMemoryBlockManager::Finalize(KMemoryBlockSlabManager* slab_manager,
|
||||||
HostUnmapCallback&& host_unmap_callback) {
|
BlockCallback&& block_callback) {
|
||||||
// Erase every block until we have none left.
|
// Erase every block until we have none left.
|
||||||
auto it = m_memory_block_tree.begin();
|
auto it = m_memory_block_tree.begin();
|
||||||
while (it != m_memory_block_tree.end()) {
|
while (it != m_memory_block_tree.end()) {
|
||||||
KMemoryBlock* block = std::addressof(*it);
|
KMemoryBlock* block = std::addressof(*it);
|
||||||
it = m_memory_block_tree.erase(it);
|
it = m_memory_block_tree.erase(it);
|
||||||
|
block_callback(block->GetAddress(), block->GetSize());
|
||||||
slab_manager->Free(block);
|
slab_manager->Free(block);
|
||||||
host_unmap_callback(block->GetAddress(), block->GetSize());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(m_memory_block_tree.empty());
|
ASSERT(m_memory_block_tree.empty());
|
||||||
|
|
|
@ -85,11 +85,11 @@ public:
|
||||||
public:
|
public:
|
||||||
KMemoryBlockManager();
|
KMemoryBlockManager();
|
||||||
|
|
||||||
using HostUnmapCallback = std::function<void(Common::ProcessAddress, u64)>;
|
using BlockCallback = std::function<void(Common::ProcessAddress, u64)>;
|
||||||
|
|
||||||
Result Initialize(KProcessAddress st, KProcessAddress nd,
|
Result Initialize(KProcessAddress st, KProcessAddress nd,
|
||||||
KMemoryBlockSlabManager* slab_manager);
|
KMemoryBlockSlabManager* slab_manager);
|
||||||
void Finalize(KMemoryBlockSlabManager* slab_manager, HostUnmapCallback&& host_unmap_callback);
|
void Finalize(KMemoryBlockSlabManager* slab_manager, BlockCallback&& block_callback);
|
||||||
|
|
||||||
iterator end() {
|
iterator end() {
|
||||||
return m_memory_block_tree.end();
|
return m_memory_block_tree.end();
|
||||||
|
|
|
@ -435,69 +435,14 @@ Result KPageTableBase::FinalizeProcess() {
|
||||||
// Only process tables should be finalized.
|
// Only process tables should be finalized.
|
||||||
ASSERT(!this->IsKernel());
|
ASSERT(!this->IsKernel());
|
||||||
|
|
||||||
// HLE processes don't have memory mapped.
|
|
||||||
R_SUCCEED_IF(m_impl == nullptr);
|
|
||||||
|
|
||||||
// NOTE: Here Nintendo calls an unknown OnFinalize function.
|
// NOTE: Here Nintendo calls an unknown OnFinalize function.
|
||||||
// this->OnFinalize();
|
// this->OnFinalize();
|
||||||
|
|
||||||
// NOTE: Here Nintendo calls a second unknown OnFinalize function.
|
// NOTE: Here Nintendo calls a second unknown OnFinalize function.
|
||||||
// this->OnFinalize2();
|
// this->OnFinalize2();
|
||||||
|
|
||||||
// Get implementation objects.
|
// NOTE: Here Nintendo does a page table walk to discover heap pages to free.
|
||||||
auto& impl = this->GetImpl();
|
// We will use the block manager finalization below to free them.
|
||||||
auto& mm = m_kernel.MemoryManager();
|
|
||||||
|
|
||||||
// Traverse, freeing all pages.
|
|
||||||
{
|
|
||||||
// Get the address space size.
|
|
||||||
const size_t as_size = this->GetAddressSpaceSize();
|
|
||||||
|
|
||||||
// Begin the traversal.
|
|
||||||
TraversalContext context;
|
|
||||||
TraversalEntry cur_entry = {
|
|
||||||
.phys_addr = 0,
|
|
||||||
.block_size = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
bool cur_valid = false;
|
|
||||||
TraversalEntry next_entry;
|
|
||||||
bool next_valid;
|
|
||||||
size_t tot_size = 0;
|
|
||||||
|
|
||||||
next_valid = impl.BeginTraversal(std::addressof(next_entry), std::addressof(context),
|
|
||||||
this->GetAddressSpaceStart());
|
|
||||||
|
|
||||||
// Iterate over entries.
|
|
||||||
while (true) {
|
|
||||||
if ((!next_valid && !cur_valid) ||
|
|
||||||
(next_valid && cur_valid &&
|
|
||||||
next_entry.phys_addr == cur_entry.phys_addr + cur_entry.block_size)) {
|
|
||||||
cur_entry.block_size += next_entry.block_size;
|
|
||||||
} else {
|
|
||||||
if (cur_valid && IsHeapPhysicalAddressForFinalize(cur_entry.phys_addr)) {
|
|
||||||
mm.Close(cur_entry.phys_addr, cur_entry.block_size / PageSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update tracking variables.
|
|
||||||
tot_size += cur_entry.block_size;
|
|
||||||
cur_entry = next_entry;
|
|
||||||
cur_valid = next_valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cur_entry.block_size + tot_size >= as_size) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
next_valid =
|
|
||||||
impl.ContinueTraversal(std::addressof(next_entry), std::addressof(context));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle the last block.
|
|
||||||
if (cur_valid && IsHeapPhysicalAddressForFinalize(cur_entry.phys_addr)) {
|
|
||||||
mm.Close(cur_entry.phys_addr, cur_entry.block_size / PageSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
@ -505,14 +450,24 @@ Result KPageTableBase::FinalizeProcess() {
|
||||||
void KPageTableBase::Finalize() {
|
void KPageTableBase::Finalize() {
|
||||||
this->FinalizeProcess();
|
this->FinalizeProcess();
|
||||||
|
|
||||||
auto HostUnmapCallback = [&](KProcessAddress addr, u64 size) {
|
auto BlockCallback = [&](KProcessAddress addr, u64 size) {
|
||||||
if (m_impl->fastmem_arena) {
|
if (m_impl->fastmem_arena) {
|
||||||
m_system.DeviceMemory().buffer.Unmap(GetInteger(addr), size, false);
|
m_system.DeviceMemory().buffer.Unmap(GetInteger(addr), size, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get physical pages.
|
||||||
|
KPageGroup pg(m_kernel, m_block_info_manager);
|
||||||
|
this->MakePageGroup(pg, addr, size / PageSize);
|
||||||
|
|
||||||
|
// Free the pages.
|
||||||
|
pg.CloseAndReset();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Finalize memory blocks.
|
// Finalize memory blocks.
|
||||||
m_memory_block_manager.Finalize(m_memory_block_slab_manager, std::move(HostUnmapCallback));
|
{
|
||||||
|
KScopedLightLock lk(m_general_lock);
|
||||||
|
m_memory_block_manager.Finalize(m_memory_block_slab_manager, std::move(BlockCallback));
|
||||||
|
}
|
||||||
|
|
||||||
// Free any unsafe mapped memory.
|
// Free any unsafe mapped memory.
|
||||||
if (m_mapped_unsafe_physical_memory) {
|
if (m_mapped_unsafe_physical_memory) {
|
||||||
|
|
|
@ -18,11 +18,11 @@ using namespace AudioCore::AudioIn;
|
||||||
class IAudioIn final : public ServiceFramework<IAudioIn> {
|
class IAudioIn final : public ServiceFramework<IAudioIn> {
|
||||||
public:
|
public:
|
||||||
explicit IAudioIn(Core::System& system_, Manager& manager, size_t session_id,
|
explicit IAudioIn(Core::System& system_, Manager& manager, size_t session_id,
|
||||||
const std::string& device_name, const AudioInParameter& in_params, u32 handle,
|
const std::string& device_name, const AudioInParameter& in_params,
|
||||||
u64 applet_resource_user_id)
|
Kernel::KProcess* handle, u64 applet_resource_user_id)
|
||||||
: ServiceFramework{system_, "IAudioIn"},
|
: ServiceFramework{system_, "IAudioIn"},
|
||||||
service_context{system_, "IAudioIn"}, event{service_context.CreateEvent("AudioInEvent")},
|
service_context{system_, "IAudioIn"}, event{service_context.CreateEvent("AudioInEvent")},
|
||||||
impl{std::make_shared<In>(system_, manager, event, session_id)} {
|
process{handle}, impl{std::make_shared<In>(system_, manager, event, session_id)} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, &IAudioIn::GetAudioInState, "GetAudioInState"},
|
{0, &IAudioIn::GetAudioInState, "GetAudioInState"},
|
||||||
|
@ -45,6 +45,8 @@ public:
|
||||||
|
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
|
|
||||||
|
process->Open();
|
||||||
|
|
||||||
if (impl->GetSystem()
|
if (impl->GetSystem()
|
||||||
.Initialize(device_name, in_params, handle, applet_resource_user_id)
|
.Initialize(device_name, in_params, handle, applet_resource_user_id)
|
||||||
.IsError()) {
|
.IsError()) {
|
||||||
|
@ -55,6 +57,7 @@ public:
|
||||||
~IAudioIn() override {
|
~IAudioIn() override {
|
||||||
impl->Free();
|
impl->Free();
|
||||||
service_context.CloseEvent(event);
|
service_context.CloseEvent(event);
|
||||||
|
process->Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] std::shared_ptr<In> GetImpl() {
|
[[nodiscard]] std::shared_ptr<In> GetImpl() {
|
||||||
|
@ -196,6 +199,7 @@ private:
|
||||||
|
|
||||||
KernelHelpers::ServiceContext service_context;
|
KernelHelpers::ServiceContext service_context;
|
||||||
Kernel::KEvent* event;
|
Kernel::KEvent* event;
|
||||||
|
Kernel::KProcess* process;
|
||||||
std::shared_ptr<AudioCore::AudioIn::In> impl;
|
std::shared_ptr<AudioCore::AudioIn::In> impl;
|
||||||
Common::ScratchBuffer<u64> released_buffer;
|
Common::ScratchBuffer<u64> released_buffer;
|
||||||
};
|
};
|
||||||
|
@ -267,6 +271,14 @@ void AudInU::OpenAudioIn(HLERequestContext& ctx) {
|
||||||
auto device_name = Common::StringFromBuffer(device_name_data);
|
auto device_name = Common::StringFromBuffer(device_name_data);
|
||||||
auto handle{ctx.GetCopyHandle(0)};
|
auto handle{ctx.GetCopyHandle(0)};
|
||||||
|
|
||||||
|
auto process{ctx.GetObjectFromHandle<Kernel::KProcess>(handle)};
|
||||||
|
if (process.IsNull()) {
|
||||||
|
LOG_ERROR(Service_Audio, "Failed to get process handle");
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(ResultUnknown);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::scoped_lock l{impl->mutex};
|
std::scoped_lock l{impl->mutex};
|
||||||
auto link{impl->LinkToManager()};
|
auto link{impl->LinkToManager()};
|
||||||
if (link.IsError()) {
|
if (link.IsError()) {
|
||||||
|
@ -287,8 +299,9 @@ void AudInU::OpenAudioIn(HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_Audio, "Opening new AudioIn, sessionid={}, free sessions={}", new_session_id,
|
LOG_DEBUG(Service_Audio, "Opening new AudioIn, sessionid={}, free sessions={}", new_session_id,
|
||||||
impl->num_free_sessions);
|
impl->num_free_sessions);
|
||||||
|
|
||||||
auto audio_in = std::make_shared<IAudioIn>(system, *impl, new_session_id, device_name,
|
auto audio_in =
|
||||||
in_params, handle, applet_resource_user_id);
|
std::make_shared<IAudioIn>(system, *impl, new_session_id, device_name, in_params,
|
||||||
|
process.GetPointerUnsafe(), applet_resource_user_id);
|
||||||
impl->sessions[new_session_id] = audio_in->GetImpl();
|
impl->sessions[new_session_id] = audio_in->GetImpl();
|
||||||
impl->applet_resource_user_ids[new_session_id] = applet_resource_user_id;
|
impl->applet_resource_user_ids[new_session_id] = applet_resource_user_id;
|
||||||
|
|
||||||
|
@ -318,6 +331,14 @@ void AudInU::OpenAudioInProtocolSpecified(HLERequestContext& ctx) {
|
||||||
auto device_name = Common::StringFromBuffer(device_name_data);
|
auto device_name = Common::StringFromBuffer(device_name_data);
|
||||||
auto handle{ctx.GetCopyHandle(0)};
|
auto handle{ctx.GetCopyHandle(0)};
|
||||||
|
|
||||||
|
auto process{ctx.GetObjectFromHandle<Kernel::KProcess>(handle)};
|
||||||
|
if (process.IsNull()) {
|
||||||
|
LOG_ERROR(Service_Audio, "Failed to get process handle");
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(ResultUnknown);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::scoped_lock l{impl->mutex};
|
std::scoped_lock l{impl->mutex};
|
||||||
auto link{impl->LinkToManager()};
|
auto link{impl->LinkToManager()};
|
||||||
if (link.IsError()) {
|
if (link.IsError()) {
|
||||||
|
@ -338,8 +359,9 @@ void AudInU::OpenAudioInProtocolSpecified(HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_Audio, "Opening new AudioIn, sessionid={}, free sessions={}", new_session_id,
|
LOG_DEBUG(Service_Audio, "Opening new AudioIn, sessionid={}, free sessions={}", new_session_id,
|
||||||
impl->num_free_sessions);
|
impl->num_free_sessions);
|
||||||
|
|
||||||
auto audio_in = std::make_shared<IAudioIn>(system, *impl, new_session_id, device_name,
|
auto audio_in =
|
||||||
in_params, handle, applet_resource_user_id);
|
std::make_shared<IAudioIn>(system, *impl, new_session_id, device_name, in_params,
|
||||||
|
process.GetPointerUnsafe(), applet_resource_user_id);
|
||||||
impl->sessions[new_session_id] = audio_in->GetImpl();
|
impl->sessions[new_session_id] = audio_in->GetImpl();
|
||||||
impl->applet_resource_user_ids[new_session_id] = applet_resource_user_id;
|
impl->applet_resource_user_ids[new_session_id] = applet_resource_user_id;
|
||||||
|
|
||||||
|
|
|
@ -26,9 +26,10 @@ class IAudioOut final : public ServiceFramework<IAudioOut> {
|
||||||
public:
|
public:
|
||||||
explicit IAudioOut(Core::System& system_, AudioCore::AudioOut::Manager& manager,
|
explicit IAudioOut(Core::System& system_, AudioCore::AudioOut::Manager& manager,
|
||||||
size_t session_id, const std::string& device_name,
|
size_t session_id, const std::string& device_name,
|
||||||
const AudioOutParameter& in_params, u32 handle, u64 applet_resource_user_id)
|
const AudioOutParameter& in_params, Kernel::KProcess* handle,
|
||||||
|
u64 applet_resource_user_id)
|
||||||
: ServiceFramework{system_, "IAudioOut"}, service_context{system_, "IAudioOut"},
|
: ServiceFramework{system_, "IAudioOut"}, service_context{system_, "IAudioOut"},
|
||||||
event{service_context.CreateEvent("AudioOutEvent")},
|
event{service_context.CreateEvent("AudioOutEvent")}, process{handle},
|
||||||
impl{std::make_shared<AudioCore::AudioOut::Out>(system_, manager, event, session_id)} {
|
impl{std::make_shared<AudioCore::AudioOut::Out>(system_, manager, event, session_id)} {
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
@ -50,11 +51,14 @@ public:
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
|
|
||||||
|
process->Open();
|
||||||
}
|
}
|
||||||
|
|
||||||
~IAudioOut() override {
|
~IAudioOut() override {
|
||||||
impl->Free();
|
impl->Free();
|
||||||
service_context.CloseEvent(event);
|
service_context.CloseEvent(event);
|
||||||
|
process->Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] std::shared_ptr<AudioCore::AudioOut::Out> GetImpl() {
|
[[nodiscard]] std::shared_ptr<AudioCore::AudioOut::Out> GetImpl() {
|
||||||
|
@ -206,6 +210,7 @@ private:
|
||||||
|
|
||||||
KernelHelpers::ServiceContext service_context;
|
KernelHelpers::ServiceContext service_context;
|
||||||
Kernel::KEvent* event;
|
Kernel::KEvent* event;
|
||||||
|
Kernel::KProcess* process;
|
||||||
std::shared_ptr<AudioCore::AudioOut::Out> impl;
|
std::shared_ptr<AudioCore::AudioOut::Out> impl;
|
||||||
Common::ScratchBuffer<u64> released_buffer;
|
Common::ScratchBuffer<u64> released_buffer;
|
||||||
};
|
};
|
||||||
|
@ -257,6 +262,14 @@ void AudOutU::OpenAudioOut(HLERequestContext& ctx) {
|
||||||
auto device_name = Common::StringFromBuffer(device_name_data);
|
auto device_name = Common::StringFromBuffer(device_name_data);
|
||||||
auto handle{ctx.GetCopyHandle(0)};
|
auto handle{ctx.GetCopyHandle(0)};
|
||||||
|
|
||||||
|
auto process{ctx.GetObjectFromHandle<Kernel::KProcess>(handle)};
|
||||||
|
if (process.IsNull()) {
|
||||||
|
LOG_ERROR(Service_Audio, "Failed to get process handle");
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(ResultUnknown);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto link{impl->LinkToManager()};
|
auto link{impl->LinkToManager()};
|
||||||
if (link.IsError()) {
|
if (link.IsError()) {
|
||||||
LOG_ERROR(Service_Audio, "Failed to link Audio Out to Audio Manager");
|
LOG_ERROR(Service_Audio, "Failed to link Audio Out to Audio Manager");
|
||||||
|
@ -276,10 +289,11 @@ void AudOutU::OpenAudioOut(HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_Audio, "Opening new AudioOut, sessionid={}, free sessions={}", new_session_id,
|
LOG_DEBUG(Service_Audio, "Opening new AudioOut, sessionid={}, free sessions={}", new_session_id,
|
||||||
impl->num_free_sessions);
|
impl->num_free_sessions);
|
||||||
|
|
||||||
auto audio_out = std::make_shared<IAudioOut>(system, *impl, new_session_id, device_name,
|
auto audio_out =
|
||||||
in_params, handle, applet_resource_user_id);
|
std::make_shared<IAudioOut>(system, *impl, new_session_id, device_name, in_params,
|
||||||
result = audio_out->GetImpl()->GetSystem().Initialize(device_name, in_params, handle,
|
process.GetPointerUnsafe(), applet_resource_user_id);
|
||||||
applet_resource_user_id);
|
result = audio_out->GetImpl()->GetSystem().Initialize(
|
||||||
|
device_name, in_params, process.GetPointerUnsafe(), applet_resource_user_id);
|
||||||
if (result.IsError()) {
|
if (result.IsError()) {
|
||||||
LOG_ERROR(Service_Audio, "Failed to initialize the AudioOut System!");
|
LOG_ERROR(Service_Audio, "Failed to initialize the AudioOut System!");
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
|
|
@ -275,12 +275,12 @@ AppLoader_NRO::LoadResult AppLoader_NRO::Load(Kernel::KProcess& process, Core::S
|
||||||
return {ResultStatus::ErrorLoadingNRO, {}};
|
return {ResultStatus::ErrorLoadingNRO, {}};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (romfs != nullptr) {
|
u64 program_id{};
|
||||||
|
ReadProgramId(program_id);
|
||||||
system.GetFileSystemController().RegisterProcess(
|
system.GetFileSystemController().RegisterProcess(
|
||||||
process.GetProcessId(), {},
|
process.GetProcessId(), program_id,
|
||||||
std::make_unique<FileSys::RomFSFactory>(*this, system.GetContentProvider(),
|
std::make_unique<FileSys::RomFSFactory>(*this, system.GetContentProvider(),
|
||||||
system.GetFileSystemController()));
|
system.GetFileSystemController()));
|
||||||
}
|
|
||||||
|
|
||||||
is_loaded = true;
|
is_loaded = true;
|
||||||
return {ResultStatus::Success, LoadParameters{Kernel::KThread::DefaultThreadPriority,
|
return {ResultStatus::Success, LoadParameters{Kernel::KThread::DefaultThreadPriority,
|
||||||
|
|
Loading…
Reference in a new issue