HLE/Services: Convert err:f to the new ServiceFramework.

This commit is contained in:
Subv 2017-12-04 14:03:11 -05:00
parent e23c3cd7f7
commit 30bffb1964
3 changed files with 51 additions and 49 deletions

View File

@ -11,6 +11,7 @@
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/core.h" #include "core/core.h"
#include "core/hle/ipc.h" #include "core/hle/ipc.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/result.h" #include "core/hle/result.h"
#include "core/hle/service/err_f.h" #include "core/hle/service/err_f.h"
@ -57,23 +58,12 @@ struct ExceptionData {
}; };
static_assert(sizeof(ExceptionData) == 0x60, "ExceptionData struct has incorrect size"); static_assert(sizeof(ExceptionData) == 0x60, "ExceptionData struct has incorrect size");
// This is used instead of ResultCode from result.h
// because we can't have non-trivial data members in unions.
union RSL {
u32 raw;
BitField<0, 10, u32> description;
BitField<10, 8, u32> module;
BitField<21, 6, u32> summary;
BitField<27, 5, u32> level;
};
struct ErrInfo { struct ErrInfo {
struct ErrInfoCommon { struct ErrInfoCommon {
u8 specifier; // 0x0 u8 specifier; // 0x0
u8 rev_high; // 0x1 u8 rev_high; // 0x1
u16 rev_low; // 0x2 u16 rev_low; // 0x2
RSL result_code; // 0x4 u32 result_code; // 0x4
u32 pc_address; // 0x8 u32 pc_address; // 0x8
u32 pid; // 0xC u32 pid; // 0xC
u32 title_id_low; // 0x10 u32 title_id_low; // 0x10
@ -151,34 +141,27 @@ static void LogGenericInfo(const ErrInfo::ErrInfoCommon& errinfo_common) {
errinfo_common.app_title_id_low); errinfo_common.app_title_id_low);
LOG_CRITICAL(Service_ERR, "ADR: 0x%08X", errinfo_common.pc_address); LOG_CRITICAL(Service_ERR, "ADR: 0x%08X", errinfo_common.pc_address);
LOG_CRITICAL(Service_ERR, "RSL: 0x%08X", errinfo_common.result_code.raw); ResultCode result_code{errinfo_common.result_code};
LOG_CRITICAL(Service_ERR, " Level: %u", errinfo_common.result_code.level.Value()); LOG_CRITICAL(Service_ERR, "RSL: 0x%08X", result_code.raw);
LOG_CRITICAL(Service_ERR, " Summary: %u", errinfo_common.result_code.summary.Value()); LOG_CRITICAL(Service_ERR, " Level: %u", result_code.level.Value());
LOG_CRITICAL(Service_ERR, " Module: %u", errinfo_common.result_code.module.Value()); LOG_CRITICAL(Service_ERR, " Summary: %u", result_code.summary.Value());
LOG_CRITICAL(Service_ERR, " Desc: %u", errinfo_common.result_code.description.Value()); LOG_CRITICAL(Service_ERR, " Module: %u", result_code.module.Value());
LOG_CRITICAL(Service_ERR, " Desc: %u", result_code.description.Value());
} }
/* ThrowFatalError function void ERR_F::ThrowFatalError(Kernel::HLERequestContext& ctx) {
* Inputs: IPC::RequestParser rp(ctx, 1, 32, 0);
* 0 : Header code [0x00010800]
* 1-32 : FatalErrInfo
* Outputs:
* 0 : Header code
* 1 : Result code
*/
static void ThrowFatalError(Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
LOG_CRITICAL(Service_ERR, "Fatal error"); LOG_CRITICAL(Service_ERR, "Fatal error");
const ErrInfo* errinfo = reinterpret_cast<ErrInfo*>(&cmd_buff[1]); const ErrInfo errinfo = rp.PopRaw<ErrInfo>();
LOG_CRITICAL(Service_ERR, "Fatal error type: %s", LOG_CRITICAL(Service_ERR, "Fatal error type: %s",
GetErrType(errinfo->errinfo_common.specifier).c_str()); GetErrType(errinfo.errinfo_common.specifier).c_str());
Core::System::GetInstance().SetStatus(Core::System::ResultStatus::ErrorUnknown); Core::System::GetInstance().SetStatus(Core::System::ResultStatus::ErrorUnknown);
// Generic Info // Generic Info
LogGenericInfo(errinfo->errinfo_common); LogGenericInfo(errinfo.errinfo_common);
switch (static_cast<FatalErrType>(errinfo->errinfo_common.specifier)) { switch (static_cast<FatalErrType>(errinfo.errinfo_common.specifier)) {
case FatalErrType::Generic: case FatalErrType::Generic:
case FatalErrType::Corrupted: case FatalErrType::Corrupted:
case FatalErrType::CardRemoved: case FatalErrType::CardRemoved:
@ -187,7 +170,7 @@ static void ThrowFatalError(Interface* self) {
break; break;
} }
case FatalErrType::Exception: { case FatalErrType::Exception: {
const auto& errtype = errinfo->exception; const auto& errtype = errinfo.exception;
// Register Info // Register Info
LOG_CRITICAL(Service_ERR, "ARM Registers:"); LOG_CRITICAL(Service_ERR, "ARM Registers:");
@ -237,7 +220,7 @@ static void ThrowFatalError(Interface* self) {
} }
case FatalErrType::ResultFailure: { case FatalErrType::ResultFailure: {
const auto& errtype = errinfo->result_failure; const auto& errtype = errinfo.result_failure;
// Failure Message // Failure Message
LOG_CRITICAL(Service_ERR, "Failure Message: %s", errtype.message); LOG_CRITICAL(Service_ERR, "Failure Message: %s", errtype.message);
@ -247,19 +230,23 @@ static void ThrowFatalError(Interface* self) {
} // switch FatalErrType } // switch FatalErrType
cmd_buff[0] = IPC::MakeHeader(0x1, 1, 0); IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
cmd_buff[1] = RESULT_SUCCESS.raw; // No error rb.Push(RESULT_SUCCESS);
} }
const Interface::FunctionInfo FunctionTable[] = { ERR_F::ERR_F() : ServiceFramework("err:f", 1) {
// clang-format off static const FunctionInfo functions[] = {
{0x00010800, ThrowFatalError, "ThrowFatalError"}, {0x00010800, &ERR_F::ThrowFatalError, "ThrowFatalError"},
{0x00020042, nullptr, "SetUserString"}, {0x00020042, nullptr, "SetUserString"},
// clang-format on
}; };
RegisterHandlers(functions);
}
ERR_F::ERR_F() { ERR_F::~ERR_F() = default;
Register(FunctionTable);
void InstallInterfaces() {
auto errf = std::make_shared<ERR_F>();
errf->InstallAsNamedPort();
} }
} // namespace ERR } // namespace ERR

View File

@ -6,17 +6,32 @@
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
namespace Kernel {
class HLERequestContext;
}
namespace Service { namespace Service {
namespace ERR { namespace ERR {
class ERR_F final : public Interface { /// Interface to "err:f" service
class ERR_F final : public ServiceFramework<ERR_F> {
public: public:
ERR_F(); ERR_F();
~ERR_F();
std::string GetPortName() const override { private:
return "err:f"; /* ThrowFatalError function
} * Inputs:
* 0 : Header code [0x00010800]
* 1-32 : FatalErrInfo
* Outputs:
* 0 : Header code
* 1 : Result code
*/
void ThrowFatalError(Kernel::HLERequestContext& ctx);
}; };
void InstallInterfaces();
} // namespace ERR } // namespace ERR
} // namespace Service } // namespace Service

View File

@ -257,11 +257,11 @@ void Init() {
SM::g_service_manager = std::make_shared<SM::ServiceManager>(); SM::g_service_manager = std::make_shared<SM::ServiceManager>();
SM::ServiceManager::InstallInterfaces(SM::g_service_manager); SM::ServiceManager::InstallInterfaces(SM::g_service_manager);
ERR::InstallInterfaces();
NS::InstallInterfaces(*SM::g_service_manager); NS::InstallInterfaces(*SM::g_service_manager);
AC::InstallInterfaces(*SM::g_service_manager); AC::InstallInterfaces(*SM::g_service_manager);
AddNamedPort(new ERR::ERR_F);
FS::ArchiveInit(); FS::ArchiveInit();
ACT::Init(); ACT::Init();
AM::Init(); AM::Init();