Merge pull request #175 from bunnei/libnx-fixes-2

More fixes for Libnx
This commit is contained in:
bunnei 2018-02-10 01:14:40 -05:00 committed by GitHub
commit b26cdf1fe5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 166 additions and 99 deletions

View file

@ -92,6 +92,8 @@ add_library(core STATIC
hle/service/aoc/aoc_u.h hle/service/aoc/aoc_u.h
hle/service/apm/apm.cpp hle/service/apm/apm.cpp
hle/service/apm/apm.h hle/service/apm/apm.h
hle/service/apm/interface.cpp
hle/service/apm/interface.h
hle/service/audio/audio.cpp hle/service/audio/audio.cpp
hle/service/audio/audio.h hle/service/audio/audio.h
hle/service/audio/audin_u.cpp hle/service/audio/audin_u.cpp

View file

@ -5,63 +5,15 @@
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/hle/ipc_helpers.h" #include "core/hle/ipc_helpers.h"
#include "core/hle/service/apm/apm.h" #include "core/hle/service/apm/apm.h"
#include "core/hle/service/apm/interface.h"
namespace Service { namespace Service {
namespace APM { namespace APM {
void InstallInterfaces(SM::ServiceManager& service_manager) { void InstallInterfaces(SM::ServiceManager& service_manager) {
std::make_shared<APM>()->InstallAsService(service_manager); auto module_ = std::make_shared<Module>();
} std::make_shared<APM>(module_, "apm")->InstallAsService(service_manager);
std::make_shared<APM>(module_, "apm:p")->InstallAsService(service_manager);
class ISession final : public ServiceFramework<ISession> {
public:
ISession() : ServiceFramework("ISession") {
static const FunctionInfo functions[] = {
{0, &ISession::SetPerformanceConfiguration, "SetPerformanceConfiguration"},
{1, &ISession::GetPerformanceConfiguration, "GetPerformanceConfiguration"},
};
RegisterHandlers(functions);
}
private:
void SetPerformanceConfiguration(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
auto mode = static_cast<PerformanceMode>(rp.Pop<u32>());
u32 config = rp.Pop<u32>();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_APM, "(STUBBED) called mode=%u config=%u", static_cast<u32>(mode),
config);
}
void GetPerformanceConfiguration(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
auto mode = static_cast<PerformanceMode>(rp.Pop<u32>());
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<u32>(0); // Performance configuration
LOG_WARNING(Service_APM, "(STUBBED) called mode=%u", static_cast<u32>(mode));
}
};
APM::APM() : ServiceFramework("apm") {
static const FunctionInfo functions[] = {
{0x00000000, &APM::OpenSession, "OpenSession"},
{0x00000001, nullptr, "GetPerformanceMode"},
};
RegisterHandlers(functions);
}
void APM::OpenSession(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ISession>();
} }
} // namespace APM } // namespace APM

View file

@ -14,13 +14,10 @@ enum class PerformanceMode : u8 {
Docked = 1, Docked = 1,
}; };
class APM final : public ServiceFramework<APM> { class Module final {
public: public:
APM(); Module() = default;
~APM() = default; ~Module() = default;
private:
void OpenSession(Kernel::HLERequestContext& ctx);
}; };
/// Registers all AM services with the specified service manager. /// Registers all AM services with the specified service manager.

View file

@ -0,0 +1,66 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/service/apm/apm.h"
#include "core/hle/service/apm/interface.h"
namespace Service {
namespace APM {
class ISession final : public ServiceFramework<ISession> {
public:
ISession() : ServiceFramework("ISession") {
static const FunctionInfo functions[] = {
{0, &ISession::SetPerformanceConfiguration, "SetPerformanceConfiguration"},
{1, &ISession::GetPerformanceConfiguration, "GetPerformanceConfiguration"},
};
RegisterHandlers(functions);
}
private:
void SetPerformanceConfiguration(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
auto mode = static_cast<PerformanceMode>(rp.Pop<u32>());
u32 config = rp.Pop<u32>();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_APM, "(STUBBED) called mode=%u config=%u", static_cast<u32>(mode),
config);
}
void GetPerformanceConfiguration(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
auto mode = static_cast<PerformanceMode>(rp.Pop<u32>());
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<u32>(0); // Performance configuration
LOG_WARNING(Service_APM, "(STUBBED) called mode=%u", static_cast<u32>(mode));
}
};
APM::APM(std::shared_ptr<Module> apm, const char* name)
: ServiceFramework(name), apm(std::move(apm)) {
static const FunctionInfo functions[] = {
{0, &APM::OpenSession, "OpenSession"},
{1, nullptr, "GetPerformanceMode"},
};
RegisterHandlers(functions);
}
void APM::OpenSession(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ISession>();
}
} // namespace APM
} // namespace Service

View file

@ -0,0 +1,27 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/hle/service/service.h"
namespace Service {
namespace APM {
class APM final : public ServiceFramework<APM> {
public:
APM(std::shared_ptr<Module> apm, const char* name);
~APM() = default;
private:
void OpenSession(Kernel::HLERequestContext& ctx);
std::shared_ptr<Module> apm;
};
/// Registers all AM services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& service_manager);
} // namespace APM
} // namespace Service

View file

@ -70,6 +70,7 @@ private:
FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") { FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{1, &FSP_SRV::Initalize, "Initalize"}, {1, &FSP_SRV::Initalize, "Initalize"},
{18, &FSP_SRV::MountSdCard, "MountSdCard"},
{200, &FSP_SRV::OpenDataStorageByCurrentProcess, "OpenDataStorageByCurrentProcess"}, {200, &FSP_SRV::OpenDataStorageByCurrentProcess, "OpenDataStorageByCurrentProcess"},
{202, nullptr, "OpenDataStorageByDataId"}, {202, nullptr, "OpenDataStorageByDataId"},
{203, &FSP_SRV::OpenRomStorage, "OpenRomStorage"}, {203, &FSP_SRV::OpenRomStorage, "OpenRomStorage"},
@ -96,6 +97,13 @@ void FSP_SRV::Initalize(Kernel::HLERequestContext& ctx) {
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
void FSP_SRV::MountSdCard(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_FS, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) { void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_FS, "(STUBBED) called"); LOG_WARNING(Service_FS, "(STUBBED) called");

View file

@ -23,6 +23,7 @@ private:
void TryLoadRomFS(); void TryLoadRomFS();
void Initalize(Kernel::HLERequestContext& ctx); void Initalize(Kernel::HLERequestContext& ctx);
void MountSdCard(Kernel::HLERequestContext& ctx);
void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx); void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx); void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
void OpenRomStorage(Kernel::HLERequestContext& ctx); void OpenRomStorage(Kernel::HLERequestContext& ctx);

View file

@ -40,7 +40,11 @@ u32 BufferQueue::DequeueBuffer(u32 pixel_format, u32 width, u32 height) {
return igbp_buffer.format == pixel_format && igbp_buffer.width == width && return igbp_buffer.format == pixel_format && igbp_buffer.width == width &&
igbp_buffer.height == height; igbp_buffer.height == height;
}); });
ASSERT(itr != queue.end()); if (itr == queue.end()) {
LOG_CRITICAL(Service_NVDRV, "no free buffers for pixel_format=%d, width=%d, height=%d",
pixel_format, width, height);
itr = queue.begin();
}
itr->status = Buffer::Status::Dequeued; itr->status = Buffer::Status::Dequeued;
return itr->slot; return itr->slot;

View file

@ -211,7 +211,6 @@ public:
void DeserializeData() override { void DeserializeData() override {
std::u16string token = ReadInterfaceToken(); std::u16string token = ReadInterfaceToken();
data = Read<Data>(); data = Read<Data>();
ASSERT(data.graphic_buffer_length == sizeof(NVFlinger::IGBPBuffer));
buffer = Read<NVFlinger::IGBPBuffer>(); buffer = Read<NVFlinger::IGBPBuffer>();
} }
@ -301,14 +300,11 @@ public:
protected: protected:
void SerializeData() override { void SerializeData() override {
// TODO(Subv): Find out what this all means // TODO(bunnei): Find out what this all means. Writing anything non-zero here breaks libnx.
Write<u32_le>(1); Write<u32_le>(0);
Write<u32_le>(0);
Write<u32_le>(sizeof(NVFlinger::IGBPBuffer)); Write<u32_le>(0);
Write<u32_le>(0); // Unknown
Write(buffer); Write(buffer);
Write<u32_le>(0); Write<u32_le>(0);
} }
@ -401,7 +397,7 @@ public:
{0, &IHOSBinderDriver::TransactParcel, "TransactParcel"}, {0, &IHOSBinderDriver::TransactParcel, "TransactParcel"},
{1, &IHOSBinderDriver::AdjustRefcount, "AdjustRefcount"}, {1, &IHOSBinderDriver::AdjustRefcount, "AdjustRefcount"},
{2, &IHOSBinderDriver::GetNativeHandle, "GetNativeHandle"}, {2, &IHOSBinderDriver::GetNativeHandle, "GetNativeHandle"},
{3, nullptr, "TransactParcelAuto"}, {3, &IHOSBinderDriver::TransactParcelAuto, "TransactParcelAuto"},
}; };
RegisterHandlers(functions); RegisterHandlers(functions);
} }
@ -425,35 +421,21 @@ private:
SetPreallocatedBuffer = 14 SetPreallocatedBuffer = 14
}; };
void TransactParcel(Kernel::HLERequestContext& ctx) { void TransactParcel(u32 id, TransactionId transaction, const std::vector<u8>& input_data,
IPC::RequestParser rp{ctx}; VAddr output_addr, u64 output_size) {
u32 id = rp.Pop<u32>();
auto transaction = static_cast<TransactionId>(rp.Pop<u32>());
u32 flags = rp.Pop<u32>();
auto& input_buffer = ctx.BufferDescriptorA()[0];
std::vector<u8> input_data(input_buffer.Size());
Memory::ReadBlock(input_buffer.Address(), input_data.data(), input_buffer.Size());
auto& output_buffer = ctx.BufferDescriptorB()[0];
auto buffer_queue = nv_flinger->GetBufferQueue(id); auto buffer_queue = nv_flinger->GetBufferQueue(id);
LOG_WARNING(Service_VI, "(STUBBED) called, transaction=%x", transaction); std::vector<u8> response_buffer;
if (transaction == TransactionId::Connect) { if (transaction == TransactionId::Connect) {
IGBPConnectRequestParcel request{input_data}; IGBPConnectRequestParcel request{input_data};
IGBPConnectResponseParcel response{1280, 720}; IGBPConnectResponseParcel response{1280, 720};
auto response_buffer = response.Serialize(); response_buffer = response.Serialize();
Memory::WriteBlock(output_buffer.Address(), response_buffer.data(),
output_buffer.Size());
} else if (transaction == TransactionId::SetPreallocatedBuffer) { } else if (transaction == TransactionId::SetPreallocatedBuffer) {
IGBPSetPreallocatedBufferRequestParcel request{input_data}; IGBPSetPreallocatedBufferRequestParcel request{input_data};
buffer_queue->SetPreallocatedBuffer(request.data.slot, request.buffer); buffer_queue->SetPreallocatedBuffer(request.data.slot, request.buffer);
IGBPSetPreallocatedBufferResponseParcel response{}; IGBPSetPreallocatedBufferResponseParcel response{};
auto response_buffer = response.Serialize(); response_buffer = response.Serialize();
Memory::WriteBlock(output_buffer.Address(), response_buffer.data(),
output_buffer.Size());
} else if (transaction == TransactionId::DequeueBuffer) { } else if (transaction == TransactionId::DequeueBuffer) {
IGBPDequeueBufferRequestParcel request{input_data}; IGBPDequeueBufferRequestParcel request{input_data};
@ -461,27 +443,21 @@ private:
request.data.height); request.data.height);
IGBPDequeueBufferResponseParcel response{slot}; IGBPDequeueBufferResponseParcel response{slot};
auto response_buffer = response.Serialize(); response_buffer = response.Serialize();
Memory::WriteBlock(output_buffer.Address(), response_buffer.data(),
output_buffer.Size());
} else if (transaction == TransactionId::RequestBuffer) { } else if (transaction == TransactionId::RequestBuffer) {
IGBPRequestBufferRequestParcel request{input_data}; IGBPRequestBufferRequestParcel request{input_data};
auto& buffer = buffer_queue->RequestBuffer(request.slot); auto& buffer = buffer_queue->RequestBuffer(request.slot);
IGBPRequestBufferResponseParcel response{buffer}; IGBPRequestBufferResponseParcel response{buffer};
auto response_buffer = response.Serialize(); response_buffer = response.Serialize();
Memory::WriteBlock(output_buffer.Address(), response_buffer.data(),
output_buffer.Size());
} else if (transaction == TransactionId::QueueBuffer) { } else if (transaction == TransactionId::QueueBuffer) {
IGBPQueueBufferRequestParcel request{input_data}; IGBPQueueBufferRequestParcel request{input_data};
buffer_queue->QueueBuffer(request.data.slot); buffer_queue->QueueBuffer(request.data.slot);
IGBPQueueBufferResponseParcel response{1280, 720}; IGBPQueueBufferResponseParcel response{1280, 720};
auto response_buffer = response.Serialize(); response_buffer = response.Serialize();
Memory::WriteBlock(output_buffer.Address(), response_buffer.data(),
output_buffer.Size());
} else if (transaction == TransactionId::Query) { } else if (transaction == TransactionId::Query) {
IGBPQueryRequestParcel request{input_data}; IGBPQueryRequestParcel request{input_data};
@ -489,13 +465,47 @@ private:
buffer_queue->Query(static_cast<NVFlinger::BufferQueue::QueryType>(request.type)); buffer_queue->Query(static_cast<NVFlinger::BufferQueue::QueryType>(request.type));
IGBPQueryResponseParcel response{value}; IGBPQueryResponseParcel response{value};
auto response_buffer = response.Serialize(); response_buffer = response.Serialize();
Memory::WriteBlock(output_buffer.Address(), response_buffer.data(),
output_buffer.Size());
} else { } else {
ASSERT_MSG(false, "Unimplemented"); ASSERT_MSG(false, "Unimplemented");
} }
Memory::WriteBlock(output_addr, response_buffer.data(), output_size);
}
void TransactParcel(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
u32 id = rp.Pop<u32>();
auto transaction = static_cast<TransactionId>(rp.Pop<u32>());
u32 flags = rp.Pop<u32>();
LOG_DEBUG(Service_VI, "called, transaction=%x", transaction);
auto& input_buffer = ctx.BufferDescriptorA()[0];
auto& output_buffer = ctx.BufferDescriptorB()[0];
std::vector<u8> input_data(input_buffer.Size());
Memory::ReadBlock(input_buffer.Address(), input_data.data(), input_buffer.Size());
TransactParcel(id, transaction, input_data, output_buffer.Address(), output_buffer.Size());
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void TransactParcelAuto(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
u32 id = rp.Pop<u32>();
auto transaction = static_cast<TransactionId>(rp.Pop<u32>());
u32 flags = rp.Pop<u32>();
LOG_DEBUG(Service_VI, "called, transaction=%x", transaction);
auto& input_buffer = ctx.BufferDescriptorX()[0];
auto& output_buffer = ctx.BufferDescriptorC()[0];
std::vector<u8> input_data(input_buffer.size);
Memory::ReadBlock(input_buffer.Address(), input_data.data(), input_buffer.size);
TransactParcel(id, transaction, input_data, output_buffer.Address(), output_buffer.Size());
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }