diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/core.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/process.h | 21 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 31 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc_wrap.h | 8 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/filesystem.cpp | 16 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/filesystem.h | 4 | ||||
| -rw-r--r-- | src/core/hle/service/service.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/service/service.h | 3 | 
8 files changed, 70 insertions, 19 deletions
| diff --git a/src/core/core.cpp b/src/core/core.cpp index e2fb9e038..32baa40dc 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -148,7 +148,7 @@ struct System::Impl {          telemetry_session = std::make_unique<Core::TelemetrySession>();          service_manager = std::make_shared<Service::SM::ServiceManager>(); -        Service::Init(service_manager, virtual_filesystem); +        Service::Init(service_manager, *virtual_filesystem);          GDBStub::Init();          renderer = VideoCore::CreateRenderer(emu_window); diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 73ec01e11..f2816943a 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -24,6 +24,7 @@ class ProgramMetadata;  namespace Kernel {  class KernelCore; +class ResourceLimit;  struct AddressMapping {      // Address and size must be page-aligned @@ -57,9 +58,23 @@ union ProcessFlags {      BitField<12, 1, u16> loaded_high; ///< Application loaded high (not at 0x00100000).  }; -enum class ProcessStatus { Created, Running, Exited }; - -class ResourceLimit; +/** + * Indicates the status of a Process instance. + * + * @note These match the values as used by kernel, + *       so new entries should only be added if RE + *       shows that a new value has been introduced. + */ +enum class ProcessStatus { +    Created, +    CreatedWithDebuggerAttached, +    Running, +    WaitingForDebuggerToAttach, +    DebuggerAttached, +    Exiting, +    Exited, +    DebugBreak, +};  struct CodeSet final {      struct Segment { diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index e406df829..7a053da1e 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -389,6 +389,12 @@ static void Break(u32 reason, u64 info1, u64 info2) {              "Emulated program broke execution! reason=0x{:016X}, info1=0x{:016X}, info2=0x{:016X}",              reason, info1, info2);          ASSERT(false); + +        Core::CurrentProcess()->PrepareForTermination(); + +        // Kill the current thread +        GetCurrentThread()->Stop(); +        Core::System::GetInstance().PrepareReschedule();      }  } @@ -1092,6 +1098,29 @@ static ResultCode ClearEvent(Handle handle) {      return RESULT_SUCCESS;  } +static ResultCode GetProcessInfo(u64* out, Handle process_handle, u32 type) { +    LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, type=0x{:X}", process_handle, type); + +    // This function currently only allows retrieving a process' status. +    enum class InfoType { +        Status, +    }; + +    const auto& kernel = Core::System::GetInstance().Kernel(); +    const auto process = kernel.HandleTable().Get<Process>(process_handle); +    if (!process) { +        return ERR_INVALID_HANDLE; +    } + +    const auto info_type = static_cast<InfoType>(type); +    if (info_type != InfoType::Status) { +        return ERR_INVALID_ENUM_VALUE; +    } + +    *out = static_cast<u64>(process->GetStatus()); +    return RESULT_SUCCESS; +} +  namespace {  struct FunctionDef {      using Func = void(); @@ -1227,7 +1256,7 @@ static const FunctionDef SVC_Table[] = {      {0x79, nullptr, "CreateProcess"},      {0x7A, nullptr, "StartProcess"},      {0x7B, nullptr, "TerminateProcess"}, -    {0x7C, nullptr, "GetProcessInfo"}, +    {0x7C, SvcWrap<GetProcessInfo>, "GetProcessInfo"},      {0x7D, nullptr, "CreateResourceLimit"},      {0x7E, nullptr, "SetResourceLimitLimitValue"},      {0x7F, nullptr, "CallSecureMonitor"}, diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h index cbb80c3c4..b09753c80 100644 --- a/src/core/hle/kernel/svc_wrap.h +++ b/src/core/hle/kernel/svc_wrap.h @@ -77,6 +77,14 @@ void SvcWrap() {      FuncReturn(retval);  } +template <ResultCode func(u64*, u32, u32)> +void SvcWrap() { +    u64 param_1 = 0; +    u32 retval = func(¶m_1, static_cast<u32>(Param(1)), static_cast<u32>(Param(2))).raw; +    Core::CurrentArmInterface().SetReg(1, param_1); +    FuncReturn(retval); +} +  template <ResultCode func(u32, u64)>  void SvcWrap() {      FuncReturn(func(static_cast<u32>(Param(0)), Param(1)).raw); diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 439e62d27..e06712603 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -361,19 +361,19 @@ FileSys::VirtualDir GetModificationLoadRoot(u64 title_id) {      return bis_factory->GetModificationLoadRoot(title_id);  } -void CreateFactories(const FileSys::VirtualFilesystem& vfs, bool overwrite) { +void CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite) {      if (overwrite) {          bis_factory = nullptr;          save_data_factory = nullptr;          sdmc_factory = nullptr;      } -    auto nand_directory = vfs->OpenDirectory(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir), -                                             FileSys::Mode::ReadWrite); -    auto sd_directory = vfs->OpenDirectory(FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir), -                                           FileSys::Mode::ReadWrite); -    auto load_directory = vfs->OpenDirectory(FileUtil::GetUserPath(FileUtil::UserPath::LoadDir), -                                             FileSys::Mode::ReadWrite); +    auto nand_directory = vfs.OpenDirectory(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir), +                                            FileSys::Mode::ReadWrite); +    auto sd_directory = vfs.OpenDirectory(FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir), +                                          FileSys::Mode::ReadWrite); +    auto load_directory = vfs.OpenDirectory(FileUtil::GetUserPath(FileUtil::UserPath::LoadDir), +                                            FileSys::Mode::ReadWrite);      if (bis_factory == nullptr)          bis_factory = std::make_unique<FileSys::BISFactory>(nand_directory, load_directory); @@ -383,7 +383,7 @@ void CreateFactories(const FileSys::VirtualFilesystem& vfs, bool overwrite) {          sdmc_factory = std::make_unique<FileSys::SDMCFactory>(std::move(sd_directory));  } -void InstallInterfaces(SM::ServiceManager& service_manager, const FileSys::VirtualFilesystem& vfs) { +void InstallInterfaces(SM::ServiceManager& service_manager, FileSys::VfsFilesystem& vfs) {      romfs_factory = nullptr;      CreateFactories(vfs, false);      std::make_shared<FSP_LDR>()->InstallAsService(service_manager); diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h index 53b01bb01..2df1faeb0 100644 --- a/src/core/hle/service/filesystem/filesystem.h +++ b/src/core/hle/service/filesystem/filesystem.h @@ -57,9 +57,9 @@ FileSys::VirtualDir GetModificationLoadRoot(u64 title_id);  // Creates the SaveData, SDMC, and BIS Factories. Should be called once and before any function  // above is called. -void CreateFactories(const FileSys::VirtualFilesystem& vfs, bool overwrite = true); +void CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite = true); -void InstallInterfaces(SM::ServiceManager& service_manager, const FileSys::VirtualFilesystem& vfs); +void InstallInterfaces(SM::ServiceManager& service_manager, FileSys::VfsFilesystem& vfs);  // A class that wraps a VfsDirectory with methods that return ResultVal and ResultCode instead of  // pointers and booleans. This makes using a VfsDirectory with switch services much easier and diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 62f049660..a225cb4cb 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -197,7 +197,7 @@ ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::HLERequestContext& co  // Module interface  /// Initialize ServiceManager -void Init(std::shared_ptr<SM::ServiceManager>& sm, const FileSys::VirtualFilesystem& rfs) { +void Init(std::shared_ptr<SM::ServiceManager>& sm, FileSys::VfsFilesystem& vfs) {      // NVFlinger needs to be accessed by several services like Vi and AppletOE so we instantiate it      // here and pass it into the respective InstallInterfaces functions.      auto nv_flinger = std::make_shared<NVFlinger::NVFlinger>(); @@ -220,7 +220,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm, const FileSys::VirtualFilesys      EUPLD::InstallInterfaces(*sm);      Fatal::InstallInterfaces(*sm);      FGM::InstallInterfaces(*sm); -    FileSystem::InstallInterfaces(*sm, rfs); +    FileSystem::InstallInterfaces(*sm, vfs);      Friend::InstallInterfaces(*sm);      GRC::InstallInterfaces(*sm);      HID::InstallInterfaces(*sm); diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 2fc57a82e..98483ecf1 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -180,8 +180,7 @@ private:  };  /// Initialize ServiceManager -void Init(std::shared_ptr<SM::ServiceManager>& sm, -          const std::shared_ptr<FileSys::VfsFilesystem>& vfs); +void Init(std::shared_ptr<SM::ServiceManager>& sm, FileSys::VfsFilesystem& vfs);  /// Shutdown ServiceManager  void Shutdown(); | 
