aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/device_memory_manager.h2
-rw-r--r--src/core/file_sys/partition_filesystem.cpp8
-rw-r--r--src/core/file_sys/partition_filesystem.h1
-rw-r--r--src/core/file_sys/vfs/vfs_offset.cpp7
-rw-r--r--src/core/file_sys/vfs/vfs_offset.h3
-rw-r--r--src/core/file_sys/vfs/vfs_real.cpp14
-rw-r--r--src/core/file_sys/vfs/vfs_real.h3
-rw-r--r--src/core/guest_memory.h62
-rw-r--r--src/core/hle/service/glue/time/manager.cpp37
-rw-r--r--src/core/hle/service/glue/time/manager.h4
-rw-r--r--src/core/hle/service/glue/time/static.cpp7
-rw-r--r--src/core/hle/service/glue/time/static.h1
-rw-r--r--src/core/hle/service/glue/time/time_zone.cpp27
-rw-r--r--src/core/hle/service/glue/time/time_zone.h7
-rw-r--r--src/core/hle/service/glue/time/time_zone_binary.cpp132
-rw-r--r--src/core/hle/service/glue/time/time_zone_binary.h43
-rw-r--r--src/core/hle/service/glue/time/worker.cpp55
-rw-r--r--src/core/hle/service/glue/time/worker.h8
-rw-r--r--src/core/hle/service/nvdrv/core/container.h3
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp15
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp27
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h1
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.cpp15
-rw-r--r--src/core/loader/loader.cpp17
-rw-r--r--src/core/memory.h2
25 files changed, 249 insertions, 252 deletions
diff --git a/src/core/device_memory_manager.h b/src/core/device_memory_manager.h
index 0568a821b6..6dcf7bb228 100644
--- a/src/core/device_memory_manager.h
+++ b/src/core/device_memory_manager.h
@@ -43,6 +43,8 @@ public:
DeviceMemoryManager(const DeviceMemory& device_memory);
~DeviceMemoryManager();
+ static constexpr bool HAS_FLUSH_INVALIDATION = true;
+
void BindInterface(DeviceInterface* device_inter);
DAddr Allocate(size_t size);
diff --git a/src/core/file_sys/partition_filesystem.cpp b/src/core/file_sys/partition_filesystem.cpp
index dd8de9d8aa..8ad2307cb5 100644
--- a/src/core/file_sys/partition_filesystem.cpp
+++ b/src/core/file_sys/partition_filesystem.cpp
@@ -105,12 +105,4 @@ VirtualDir PartitionFilesystem::GetParentDirectory() const {
return nullptr;
}
-void PartitionFilesystem::PrintDebugInfo() const {
- LOG_DEBUG(Service_FS, "Magic: {:.4}", pfs_header.magic);
- LOG_DEBUG(Service_FS, "Files: {}", pfs_header.num_entries);
- for (u32 i = 0; i < pfs_header.num_entries; i++) {
- LOG_DEBUG(Service_FS, " > File {}: {} (0x{:X} bytes)", i,
- pfs_files[i]->GetName(), pfs_files[i]->GetSize());
- }
-}
} // namespace FileSys
diff --git a/src/core/file_sys/partition_filesystem.h b/src/core/file_sys/partition_filesystem.h
index 777b9ead94..c64b29b5da 100644
--- a/src/core/file_sys/partition_filesystem.h
+++ b/src/core/file_sys/partition_filesystem.h
@@ -35,7 +35,6 @@ public:
std::vector<VirtualDir> GetSubdirectories() const override;
std::string GetName() const override;
VirtualDir GetParentDirectory() const override;
- void PrintDebugInfo() const;
private:
struct Header {
diff --git a/src/core/file_sys/vfs/vfs_offset.cpp b/src/core/file_sys/vfs/vfs_offset.cpp
index 1a37d26708..6b51ed3eb9 100644
--- a/src/core/file_sys/vfs/vfs_offset.cpp
+++ b/src/core/file_sys/vfs/vfs_offset.cpp
@@ -9,9 +9,8 @@
namespace FileSys {
OffsetVfsFile::OffsetVfsFile(VirtualFile file_, std::size_t size_, std::size_t offset_,
- std::string name_, VirtualDir parent_)
- : file(file_), offset(offset_), size(size_), name(std::move(name_)),
- parent(parent_ == nullptr ? file->GetContainingDirectory() : std::move(parent_)) {}
+ std::string name_)
+ : file(file_), offset(offset_), size(size_), name(std::move(name_)) {}
OffsetVfsFile::~OffsetVfsFile() = default;
@@ -37,7 +36,7 @@ bool OffsetVfsFile::Resize(std::size_t new_size) {
}
VirtualDir OffsetVfsFile::GetContainingDirectory() const {
- return parent;
+ return nullptr;
}
bool OffsetVfsFile::IsWritable() const {
diff --git a/src/core/file_sys/vfs/vfs_offset.h b/src/core/file_sys/vfs/vfs_offset.h
index 4abe41d8e5..9800b4fd09 100644
--- a/src/core/file_sys/vfs/vfs_offset.h
+++ b/src/core/file_sys/vfs/vfs_offset.h
@@ -16,7 +16,7 @@ namespace FileSys {
class OffsetVfsFile : public VfsFile {
public:
OffsetVfsFile(VirtualFile file, std::size_t size, std::size_t offset = 0,
- std::string new_name = "", VirtualDir new_parent = nullptr);
+ std::string new_name = "");
~OffsetVfsFile() override;
std::string GetName() const override;
@@ -44,7 +44,6 @@ private:
std::size_t offset;
std::size_t size;
std::string name;
- VirtualDir parent;
};
} // namespace FileSys
diff --git a/src/core/file_sys/vfs/vfs_real.cpp b/src/core/file_sys/vfs/vfs_real.cpp
index 3ad073e4ab..052684e9db 100644
--- a/src/core/file_sys/vfs/vfs_real.cpp
+++ b/src/core/file_sys/vfs/vfs_real.cpp
@@ -76,6 +76,7 @@ VfsEntryType RealVfsFilesystem::GetEntryType(std::string_view path_) const {
}
VirtualFile RealVfsFilesystem::OpenFileFromEntry(std::string_view path_, std::optional<u64> size,
+ std::optional<std::string> parent_path,
OpenMode perms) {
const auto path = FS::SanitizePath(path_, FS::DirectorySeparator::PlatformDefault);
std::scoped_lock lk{list_lock};
@@ -94,14 +95,14 @@ VirtualFile RealVfsFilesystem::OpenFileFromEntry(std::string_view path_, std::op
this->InsertReferenceIntoListLocked(*reference);
auto file = std::shared_ptr<RealVfsFile>(
- new RealVfsFile(*this, std::move(reference), path, perms, size));
+ new RealVfsFile(*this, std::move(reference), path, perms, size, std::move(parent_path)));
cache[path] = file;
return file;
}
VirtualFile RealVfsFilesystem::OpenFile(std::string_view path_, OpenMode perms) {
- return OpenFileFromEntry(path_, {}, perms);
+ return OpenFileFromEntry(path_, {}, {}, perms);
}
VirtualFile RealVfsFilesystem::CreateFile(std::string_view path_, OpenMode perms) {
@@ -268,10 +269,11 @@ void RealVfsFilesystem::RemoveReferenceFromListLocked(FileReference& reference)
}
RealVfsFile::RealVfsFile(RealVfsFilesystem& base_, std::unique_ptr<FileReference> reference_,
- const std::string& path_, OpenMode perms_, std::optional<u64> size_)
+ const std::string& path_, OpenMode perms_, std::optional<u64> size_,
+ std::optional<std::string> parent_path_)
: base(base_), reference(std::move(reference_)), path(path_),
- parent_path(FS::GetParentPath(path_)), path_components(FS::SplitPathComponentsCopy(path_)),
- size(size_), perms(perms_) {}
+ parent_path(parent_path_ ? std::move(*parent_path_) : FS::GetParentPath(path_)),
+ path_components(FS::SplitPathComponentsCopy(path_)), size(size_), perms(perms_) {}
RealVfsFile::~RealVfsFile() {
base.DropReference(std::move(reference));
@@ -348,7 +350,7 @@ std::vector<VirtualFile> RealVfsDirectory::IterateEntries<RealVfsFile, VfsFile>(
&out](const std::filesystem::directory_entry& entry) {
const auto full_path_string = FS::PathToUTF8String(entry.path());
- out.emplace_back(base.OpenFileFromEntry(full_path_string, entry.file_size(), perms));
+ out.emplace_back(base.OpenFileFromEntry(full_path_string, entry.file_size(), path, perms));
return true;
};
diff --git a/src/core/file_sys/vfs/vfs_real.h b/src/core/file_sys/vfs/vfs_real.h
index 5c2172cce1..a773fc375a 100644
--- a/src/core/file_sys/vfs/vfs_real.h
+++ b/src/core/file_sys/vfs/vfs_real.h
@@ -62,6 +62,7 @@ private:
private:
friend class RealVfsDirectory;
VirtualFile OpenFileFromEntry(std::string_view path, std::optional<u64> size,
+ std::optional<std::string> parent_path,
OpenMode perms = OpenMode::Read);
private:
@@ -91,7 +92,7 @@ public:
private:
RealVfsFile(RealVfsFilesystem& base, std::unique_ptr<FileReference> reference,
const std::string& path, OpenMode perms = OpenMode::Read,
- std::optional<u64> size = {});
+ std::optional<u64> size = {}, std::optional<std::string> parent_path = {});
RealVfsFilesystem& base;
std::unique_ptr<FileReference> reference;
diff --git a/src/core/guest_memory.h b/src/core/guest_memory.h
index 7ee18c1269..83292f7023 100644
--- a/src/core/guest_memory.h
+++ b/src/core/guest_memory.h
@@ -44,15 +44,32 @@ public:
GuestMemory() = delete;
explicit GuestMemory(M& memory, u64 addr, std::size_t size,
Common::ScratchBuffer<T>* backup = nullptr)
- : m_memory{memory}, m_addr{addr}, m_size{size} {
+ : m_memory{&memory}, m_addr{addr}, m_size{size} {
static_assert(FLAGS & GuestMemoryFlags::Read || FLAGS & GuestMemoryFlags::Write);
- if constexpr (FLAGS & GuestMemoryFlags::Read) {
+ if constexpr (!(FLAGS & GuestMemoryFlags::Read)) {
+ if (!this->TrySetSpan()) {
+ if (backup) {
+ backup->resize_destructive(this->size());
+ m_data_span = *backup;
+ m_span_valid = true;
+ m_is_data_copy = true;
+ } else {
+ m_data_copy.resize(this->size());
+ m_data_span = std::span(m_data_copy);
+ m_span_valid = true;
+ m_is_data_copy = true;
+ }
+ }
+ } else if constexpr (FLAGS & GuestMemoryFlags::Read) {
Read(addr, size, backup);
}
}
~GuestMemory() = default;
+ GuestMemory(GuestMemory&& rhs) = default;
+ GuestMemory& operator=(GuestMemory&& rhs) = default;
+
T* data() noexcept {
return m_data_span.data();
}
@@ -109,8 +126,8 @@ public:
}
if (this->TrySetSpan()) {
- if constexpr (FLAGS & GuestMemoryFlags::Safe) {
- m_memory.FlushRegion(m_addr, this->size_bytes());
+ if constexpr (FLAGS & GuestMemoryFlags::Safe && M::HAS_FLUSH_INVALIDATION) {
+ m_memory->FlushRegion(m_addr, this->size_bytes());
}
} else {
if (backup) {
@@ -123,9 +140,9 @@ public:
m_is_data_copy = true;
m_span_valid = true;
if constexpr (FLAGS & GuestMemoryFlags::Safe) {
- m_memory.ReadBlock(m_addr, this->data(), this->size_bytes());
+ m_memory->ReadBlock(m_addr, this->data(), this->size_bytes());
} else {
- m_memory.ReadBlockUnsafe(m_addr, this->data(), this->size_bytes());
+ m_memory->ReadBlockUnsafe(m_addr, this->data(), this->size_bytes());
}
}
return m_data_span;
@@ -133,18 +150,19 @@ public:
void Write(std::span<T> write_data) noexcept {
if constexpr (FLAGS & GuestMemoryFlags::Cached) {
- m_memory.WriteBlockCached(m_addr, write_data.data(), this->size_bytes());
+ m_memory->WriteBlockCached(m_addr, write_data.data(), this->size_bytes());
} else if constexpr (FLAGS & GuestMemoryFlags::Safe) {
- m_memory.WriteBlock(m_addr, write_data.data(), this->size_bytes());
+ m_memory->WriteBlock(m_addr, write_data.data(), this->size_bytes());
} else {
- m_memory.WriteBlockUnsafe(m_addr, write_data.data(), this->size_bytes());
+ m_memory->WriteBlockUnsafe(m_addr, write_data.data(), this->size_bytes());
}
}
bool TrySetSpan() noexcept {
- if (u8* ptr = m_memory.GetSpan(m_addr, this->size_bytes()); ptr) {
+ if (u8* ptr = m_memory->GetSpan(m_addr, this->size_bytes()); ptr) {
m_data_span = {reinterpret_cast<T*>(ptr), this->size()};
m_span_valid = true;
+ m_is_data_copy = false;
return true;
}
return false;
@@ -159,7 +177,7 @@ protected:
return m_addr_changed;
}
- M& m_memory;
+ M* m_memory;
u64 m_addr{};
size_t m_size{};
std::span<T> m_data_span{};
@@ -175,17 +193,7 @@ public:
GuestMemoryScoped() = delete;
explicit GuestMemoryScoped(M& memory, u64 addr, std::size_t size,
Common::ScratchBuffer<T>* backup = nullptr)
- : GuestMemory<M, T, FLAGS>(memory, addr, size, backup) {
- if constexpr (!(FLAGS & GuestMemoryFlags::Read)) {
- if (!this->TrySetSpan()) {
- if (backup) {
- this->m_data_span = *backup;
- this->m_span_valid = true;
- this->m_is_data_copy = true;
- }
- }
- }
- }
+ : GuestMemory<M, T, FLAGS>(memory, addr, size, backup) {}
~GuestMemoryScoped() {
if constexpr (FLAGS & GuestMemoryFlags::Write) {
@@ -196,15 +204,17 @@ public:
if (this->AddressChanged() || this->IsDataCopy()) {
ASSERT(this->m_span_valid);
if constexpr (FLAGS & GuestMemoryFlags::Cached) {
- this->m_memory.WriteBlockCached(this->m_addr, this->data(), this->size_bytes());
+ this->m_memory->WriteBlockCached(this->m_addr, this->data(),
+ this->size_bytes());
} else if constexpr (FLAGS & GuestMemoryFlags::Safe) {
- this->m_memory.WriteBlock(this->m_addr, this->data(), this->size_bytes());
+ this->m_memory->WriteBlock(this->m_addr, this->data(), this->size_bytes());
} else {
- this->m_memory.WriteBlockUnsafe(this->m_addr, this->data(), this->size_bytes());
+ this->m_memory->WriteBlockUnsafe(this->m_addr, this->data(),
+ this->size_bytes());
}
} else if constexpr ((FLAGS & GuestMemoryFlags::Safe) ||
(FLAGS & GuestMemoryFlags::Cached)) {
- this->m_memory.InvalidateRegion(this->m_addr, this->size_bytes());
+ this->m_memory->InvalidateRegion(this->m_addr, this->size_bytes());
}
}
}
diff --git a/src/core/hle/service/glue/time/manager.cpp b/src/core/hle/service/glue/time/manager.cpp
index cb88486dd5..77bf8896cd 100644
--- a/src/core/hle/service/glue/time/manager.cpp
+++ b/src/core/hle/service/glue/time/manager.cpp
@@ -11,7 +11,6 @@
#include "core/file_sys/vfs/vfs.h"
#include "core/hle/kernel/svc.h"
#include "core/hle/service/glue/time/manager.h"
-#include "core/hle/service/glue/time/time_zone_binary.h"
#include "core/hle/service/psc/time/service_manager.h"
#include "core/hle/service/psc/time/static.h"
#include "core/hle/service/psc/time/system_clock.h"
@@ -20,8 +19,8 @@
#include "core/hle/service/sm/sm.h"
namespace Service::Glue::Time {
-namespace {
-s64 CalendarTimeToEpoch(Service::PSC::Time::CalendarTime calendar) {
+
+static s64 CalendarTimeToEpoch(Service::PSC::Time::CalendarTime calendar) {
constexpr auto is_leap = [](s32 year) -> bool {
return (((year) % 4) == 0 && (((year) % 100) != 0 || ((year) % 400) == 0));
};
@@ -50,7 +49,8 @@ s64 CalendarTimeToEpoch(Service::PSC::Time::CalendarTime calendar) {
return epoch_s - 62135683200ll;
}
-s64 GetEpochTimeFromInitialYear(std::shared_ptr<Service::Set::ISystemSettingsServer>& set_sys) {
+static s64 GetEpochTimeFromInitialYear(
+ std::shared_ptr<Service::Set::ISystemSettingsServer>& set_sys) {
s32 year{2000};
set_sys->GetSettingsItemValueImpl(year, "time", "standard_user_clock_initial_year");
@@ -65,31 +65,32 @@ s64 GetEpochTimeFromInitialYear(std::shared_ptr<Service::Set::ISystemSettingsSer
return CalendarTimeToEpoch(calendar);
}
-Service::PSC::Time::LocationName GetTimeZoneString(Service::PSC::Time::LocationName& in_name) {
+static Service::PSC::Time::LocationName GetTimeZoneString(
+ TimeZoneBinary& time_zone_binary, Service::PSC::Time::LocationName& in_name) {
auto configured_zone = Settings::GetTimeZoneString(Settings::values.time_zone_index.GetValue());
Service::PSC::Time::LocationName configured_name{};
std::memcpy(configured_name.data(), configured_zone.data(),
std::min(configured_name.size(), configured_zone.size()));
- if (!IsTimeZoneBinaryValid(configured_name)) {
+ if (!time_zone_binary.IsValid(configured_name)) {
configured_zone = Common::TimeZone::FindSystemTimeZone();
configured_name = {};
std::memcpy(configured_name.data(), configured_zone.data(),
std::min(configured_name.size(), configured_zone.size()));
}
- ASSERT_MSG(IsTimeZoneBinaryValid(configured_name), "Invalid time zone {}!",
+ ASSERT_MSG(time_zone_binary.IsValid(configured_name), "Invalid time zone {}!",
configured_name.data());
return configured_name;
}
-} // namespace
-
TimeManager::TimeManager(Core::System& system)
- : m_steady_clock_resource{system}, m_worker{system, m_steady_clock_resource,
- m_file_timestamp_worker} {
+ : m_steady_clock_resource{system}, m_time_zone_binary{system}, m_worker{
+ system,
+ m_steady_clock_resource,
+ m_file_timestamp_worker} {
m_time_m =
system.ServiceManager().GetService<Service::PSC::Time::ServiceManager>("time:m", true);
@@ -99,7 +100,7 @@ TimeManager::TimeManager(Core::System& system)
m_set_sys =
system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true);
- res = MountTimeZoneBinary(system);
+ res = m_time_zone_binary.Mount();
ASSERT(res == ResultSuccess);
m_worker.Initialize(m_time_sm, m_set_sys);
@@ -187,10 +188,6 @@ TimeManager::TimeManager(Core::System& system)
}
}
-TimeManager::~TimeManager() {
- ResetTimeZoneBinary();
-}
-
Result TimeManager::SetupStandardSteadyClockCore() {
Common::UUID external_clock_source_id{};
auto res = m_set_sys->GetExternalSteadyClockSourceId(&external_clock_source_id);
@@ -236,7 +233,7 @@ Result TimeManager::SetupTimeZoneServiceCore() {
auto res = m_set_sys->GetDeviceTimeZoneLocationName(&name);
ASSERT(res == ResultSuccess);
- auto configured_zone = GetTimeZoneString(name);
+ auto configured_zone = GetTimeZoneString(m_time_zone_binary, name);
if (configured_zone != name) {
m_set_sys->SetDeviceTimeZoneLocationName(configured_zone);
@@ -254,13 +251,13 @@ Result TimeManager::SetupTimeZoneServiceCore() {
res = m_set_sys->GetDeviceTimeZoneLocationUpdatedTime(&time_point);
ASSERT(res == ResultSuccess);
- auto location_count = GetTimeZoneCount();
+ auto location_count = m_time_zone_binary.GetTimeZoneCount();
Service::PSC::Time::RuleVersion rule_version{};
- GetTimeZoneVersion(rule_version);
+ m_time_zone_binary.GetTimeZoneVersion(rule_version);
std::span<const u8> rule_buffer{};
size_t rule_size{};
- res = GetTimeZoneRule(rule_buffer, rule_size, name);
+ res = m_time_zone_binary.GetTimeZoneRule(rule_buffer, rule_size, name);
ASSERT(res == ResultSuccess);
res = m_time_m->SetupTimeZoneServiceCore(name, rule_version, location_count, time_point,
diff --git a/src/core/hle/service/glue/time/manager.h b/src/core/hle/service/glue/time/manager.h
index bb4b650492..87e6a21fd5 100644
--- a/src/core/hle/service/glue/time/manager.h
+++ b/src/core/hle/service/glue/time/manager.h
@@ -10,6 +10,7 @@
#include "core/file_sys/vfs/vfs_types.h"
#include "core/hle/service/glue/time/file_timestamp_worker.h"
#include "core/hle/service/glue/time/standard_steady_clock_resource.h"
+#include "core/hle/service/glue/time/time_zone_binary.h"
#include "core/hle/service/glue/time/worker.h"
#include "core/hle/service/service.h"
@@ -26,7 +27,7 @@ namespace Service::Glue::Time {
class TimeManager {
public:
explicit TimeManager(Core::System& system);
- ~TimeManager();
+ ~TimeManager() = default;
std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys;
@@ -34,6 +35,7 @@ public:
std::shared_ptr<Service::PSC::Time::StaticService> m_time_sm{};
StandardSteadyClockResource m_steady_clock_resource;
FileTimestampWorker m_file_timestamp_worker;
+ TimeZoneBinary m_time_zone_binary;
TimeWorker m_worker;
private:
diff --git a/src/core/hle/service/glue/time/static.cpp b/src/core/hle/service/glue/time/static.cpp
index b801faef29..d8672b7248 100644
--- a/src/core/hle/service/glue/time/static.cpp
+++ b/src/core/hle/service/glue/time/static.cpp
@@ -26,8 +26,9 @@ StaticService::StaticService(Core::System& system_,
std::shared_ptr<TimeManager> time, const char* name)
: ServiceFramework{system_, name}, m_system{system_}, m_time_m{time->m_time_m},
m_setup_info{setup_info}, m_time_sm{time->m_time_sm},
- m_file_timestamp_worker{time->m_file_timestamp_worker}, m_standard_steady_clock_resource{
- time->m_steady_clock_resource} {
+ m_file_timestamp_worker{time->m_file_timestamp_worker},
+ m_standard_steady_clock_resource{time->m_steady_clock_resource},
+ m_time_zone_binary{time->m_time_zone_binary} {
// clang-format off
static const FunctionInfo functions[] = {
{0, D<&StaticService::GetStandardUserSystemClock>, "GetStandardUserSystemClock"},
@@ -106,7 +107,7 @@ Result StaticService::GetTimeZoneService(OutInterface<TimeZoneService> out_servi
*out_service = std::make_shared<TimeZoneService>(
m_system, m_file_timestamp_worker, m_setup_info.can_write_timezone_device_location,
- m_time_zone);
+ m_time_zone_binary, m_time_zone);
R_SUCCEED();
}
diff --git a/src/core/hle/service/glue/time/static.h b/src/core/hle/service/glue/time/static.h
index 5d3623182f..7bb0e0b36e 100644
--- a/src/core/hle/service/glue/time/static.h
+++ b/src/core/hle/service/glue/time/static.h
@@ -80,5 +80,6 @@ private:
std::shared_ptr<Service::PSC::Time::TimeZoneService> m_time_zone;
FileTimestampWorker& m_file_timestamp_worker;
StandardSteadyClockResource& m_standard_steady_clock_resource;
+ TimeZoneBinary& m_time_zone_binary;
};
} // namespace Service::Glue::Time
diff --git a/src/core/hle/service/glue/time/time_zone.cpp b/src/core/hle/service/glue/time/time_zone.cpp
index f4d0c87d5f..b2e8159653 100644
--- a/src/core/hle/service/glue/time/time_zone.cpp
+++ b/src/core/hle/service/glue/time/time_zone.cpp
@@ -15,19 +15,16 @@
#include "core/hle/service/sm/sm.h"
namespace Service::Glue::Time {
-namespace {
-static std::mutex g_list_mutex;
-static Common::IntrusiveListBaseTraits<Service::PSC::Time::OperationEvent>::ListType g_list_nodes{};
-} // namespace
TimeZoneService::TimeZoneService(
Core::System& system_, FileTimestampWorker& file_timestamp_worker,
- bool can_write_timezone_device_location,
+ bool can_write_timezone_device_location, TimeZoneBinary& time_zone_binary,
std::shared_ptr<Service::PSC::Time::TimeZoneService> time_zone_service)
: ServiceFramework{system_, "ITimeZoneService"}, m_system{system},
m_can_write_timezone_device_location{can_write_timezone_device_location},
- m_file_timestamp_worker{file_timestamp_worker},
- m_wrapped_service{std::move(time_zone_service)}, m_operation_event{m_system} {
+ m_file_timestamp_worker{file_timestamp_worker}, m_wrapped_service{std::move(
+ time_zone_service)},
+ m_operation_event{m_system}, m_time_zone_binary{time_zone_binary} {
// clang-format off
static const FunctionInfo functions[] = {
{0, D<&TimeZoneService::GetDeviceLocationName>, "GetDeviceLocationName"},
@@ -48,7 +45,6 @@ TimeZoneService::TimeZoneService(
// clang-format on
RegisterHandlers(functions);
- g_list_nodes.clear();
m_set_sys =
m_system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true);
}
@@ -69,13 +65,13 @@ Result TimeZoneService::SetDeviceLocationName(
LOG_DEBUG(Service_Time, "called. location_name={}", location_name);
R_UNLESS(m_can_write_timezone_device_location, Service::PSC::Time::ResultPermissionDenied);
- R_UNLESS(IsTimeZoneBinaryValid(location_name), Service::PSC::Time::ResultTimeZoneNotFound);
+ R_UNLESS(m_time_zone_binary.IsValid(location_name), Service::PSC::Time::ResultTimeZoneNotFound);
std::scoped_lock l{m_mutex};
std::span<const u8> binary{};
size_t binary_size{};
- R_TRY(GetTimeZoneRule(binary, binary_size, location_name))
+ R_TRY(m_time_zone_binary.GetTimeZoneRule(binary, binary_size, location_name))
R_TRY(m_wrapped_service->SetDeviceLocationNameWithTimeZoneRule(location_name, binary));
@@ -88,8 +84,8 @@ Result TimeZoneService::SetDeviceLocationName(
m_set_sys->SetDeviceTimeZoneLocationName(name);
m_set_sys->SetDeviceTimeZoneLocationUpdatedTime(time_point);
- std::scoped_lock m{g_list_mutex};
- for (auto& operation_event : g_list_nodes) {
+ std::scoped_lock m{m_list_mutex};
+ for (auto& operation_event : m_list_nodes) {
operation_event.m_event->Signal();
}
R_SUCCEED();
@@ -112,7 +108,8 @@ Result TimeZoneService::LoadLocationNameList(
};
std::scoped_lock l{m_mutex};
- R_RETURN(GetTimeZoneLocationList(*out_count, out_names, out_names.size(), index));
+ R_RETURN(
+ m_time_zone_binary.GetTimeZoneLocationList(*out_count, out_names, out_names.size(), index));
}
Result TimeZoneService::LoadTimeZoneRule(OutRule out_rule,
@@ -122,7 +119,7 @@ Result TimeZoneService::LoadTimeZoneRule(OutRule out_rule,
std::scoped_lock l{m_mutex};
std::span<const u8> binary{};
size_t binary_size{};
- R_TRY(GetTimeZoneRule(binary, binary_size, name))
+ R_TRY(m_time_zone_binary.GetTimeZoneRule(binary, binary_size, name))
R_RETURN(m_wrapped_service->ParseTimeZoneBinary(out_rule, binary));
}
@@ -174,7 +171,7 @@ Result TimeZoneService::GetDeviceLocationNameOperationEventReadableHandle(
m_operation_event.m_ctx.CreateEvent("Psc:TimeZoneService:OperationEvent");
operation_event_initialized = true;
std::scoped_lock l{m_mutex};
- g_list_nodes.push_back(m_operation_event);
+ m_list_nodes.push_back(m_operation_event);
}
*out_event = &m_operation_event.m_event->GetReadableEvent();
diff --git a/src/core/hle/service/glue/time/time_zone.h b/src/core/hle/service/glue/time/time_zone.h
index beb54ddde4..2b130b275d 100644
--- a/src/core/hle/service/glue/time/time_zone.h
+++ b/src/core/hle/service/glue/time/time_zone.h
@@ -32,6 +32,7 @@ class TimeZoneService;
namespace Service::Glue::Time {
class FileTimestampWorker;
+class TimeZoneBinary;
class TimeZoneService final : public ServiceFramework<TimeZoneService> {
using InRule = InLargeData<Tz::Rule, BufferAttr_HipcMapAlias>;
@@ -40,7 +41,7 @@ class TimeZoneService final : public ServiceFramework<TimeZoneService> {
public:
explicit TimeZoneService(
Core::System& system, FileTimestampWorker& file_timestamp_worker,
- bool can_write_timezone_device_location,
+ bool can_write_timezone_device_location, TimeZoneBinary& time_zone_binary,
std::shared_ptr<Service::PSC::Time::TimeZoneService> time_zone_service);
~TimeZoneService() override;
@@ -85,6 +86,10 @@ private:
std::mutex m_mutex;
bool operation_event_initialized{};
Service::PSC::Time::OperationEvent m_operation_event;
+ TimeZoneBinary& m_time_zone_binary;
+
+ std::mutex m_list_mutex;
+ Common::IntrusiveListBaseTraits<Service::PSC::Time::OperationEvent>::ListType m_list_nodes{};
};
} // namespace Service::Glue::Time
diff --git a/src/core/hle/service/glue/time/time_zone_binary.cpp b/src/core/hle/service/glue/time/time_zone_binary.cpp
index 18c6abd6bb..3cc1a62afd 100644
--- a/src/core/hle/service/glue/time/time_zone_binary.cpp
+++ b/src/core/hle/service/glue/time/time_zone_binary.cpp
@@ -12,41 +12,17 @@
#include "core/hle/service/glue/time/time_zone_binary.h"
namespace Service::Glue::Time {
-namespace {
constexpr u64 TimeZoneBinaryId = 0x10000000000080E;
-static FileSys::VirtualDir g_time_zone_binary_romfs{};
-static Result g_time_zone_binary_mount_result{ResultUnknown};
-static std::vector<u8> g_time_zone_scratch_space(0x2800, 0);
-
-Result TimeZoneReadBinary(size_t& out_read_size, std::span<u8> out_buffer, size_t out_buffer_size,
- std::string_view path) {
- R_UNLESS(g_time_zone_binary_mount_result == ResultSuccess, g_time_zone_binary_mount_result);
-
- auto vfs_file{g_time_zone_binary_romfs->GetFileRelative(path)};
- R_UNLESS(vfs_file, ResultUnknown);
-
- auto file_size{vfs_file->GetSize()};
- R_UNLESS(file_size > 0, ResultUnknown);
-
- R_UNLESS(file_size <= out_buffer_size, Service::PSC::Time::ResultFailed);
-
- out_read_size = vfs_file->Read(out_buffer.data(), file_size);
- R_UNLESS(out_read_size > 0, ResultUnknown);
-
- R_SUCCEED();
-}
-} // namespace
-
-void ResetTimeZoneBinary() {
- g_time_zone_binary_romfs = {};
- g_time_zone_binary_mount_result = ResultUnknown;
- g_time_zone_scratch_space.clear();
- g_time_zone_scratch_space.resize(0x2800, 0);
+void TimeZoneBinary::Reset() {
+ time_zone_binary_romfs = {};
+ time_zone_binary_mount_result = ResultUnknown;
+ time_zone_scratch_space.clear();
+ time_zone_scratch_space.resize(0x2800, 0);
}
-Result MountTimeZoneBinary(Core::System& system) {
- ResetTimeZoneBinary();
+Result TimeZoneBinary::Mount() {
+ Reset();
auto& fsc{system.GetFileSystemController()};
std::unique_ptr<FileSys::NCA> nca{};
@@ -58,60 +34,79 @@ Result MountTimeZoneBinary(Core::System& system) {
nca = bis_system->GetEntry(TimeZoneBinaryId, FileSys::ContentRecordType::Data);
if (nca) {
- g_time_zone_binary_romfs = FileSys::ExtractRomFS(nca->GetRomFS());
+ time_zone_binary_romfs = FileSys::ExtractRomFS(nca->GetRomFS());
}
- if (g_time_zone_binary_romfs) {
+ if (time_zone_binary_romfs) {
// Validate that the romfs is readable, using invalid firmware keys can cause this to get
// set but the files to be garbage. In that case, we want to hit the next path and
// synthesise them instead.
- g_time_zone_binary_mount_result = ResultSuccess;
+ time_zone_binary_mount_result = ResultSuccess;
Service::PSC::Time::LocationName name{"Etc/GMT"};
- if (!IsTimeZoneBinaryValid(name)) {
- ResetTimeZoneBinary();
+ if (!IsValid(name)) {
+ Reset();
}
}
- if (!g_time_zone_binary_romfs) {
- g_time_zone_binary_romfs = FileSys::ExtractRomFS(
+ if (!time_zone_binary_romfs) {
+ time_zone_binary_romfs = FileSys::ExtractRomFS(
FileSys::SystemArchive::SynthesizeSystemArchive(TimeZoneBinaryId));
}
- R_UNLESS(g_time_zone_binary_romfs, ResultUnknown);
+ R_UNLESS(time_zone_binary_romfs, ResultUnknown);
+
+ time_zone_binary_mount_result = ResultSuccess;
+ R_SUCCEED();
+}
+
+Result TimeZoneBinary::Read(size_t& out_read_size, std::span<u8> out_buffer, size_t out_buffer_size,
+ std::string_view path) {
+ R_UNLESS(time_zone_binary_mount_result == ResultSuccess, time_zone_binary_mount_result);
+
+ auto vfs_file{time_zone_binary_romfs->GetFileRelative(path)};
+ R_UNLESS(vfs_file, ResultUnknown);
+
+ auto file_size{vfs_file->GetSize()};
+ R_UNLESS(file_size > 0, ResultUnknown);
+
+ R_UNLESS(file_size <= out_buffer_size, Service::PSC::Time::ResultFailed);
+
+ out_read_size = vfs_file->Read(out_buffer.data(), file_size);
+ R_UNLESS(out_read_size > 0, ResultUnknown);
- g_time_zone_binary_mount_result = ResultSuccess;
R_SUCCEED();
}
-void GetTimeZoneBinaryListPath(std::string& out_path) {
- if (g_time_zone_binary_mount_result != ResultSuccess) {
+void TimeZoneBinary::GetListPath(std::string& out_path) {
+ if (time_zone_binary_mount_result != ResultSuccess) {
return;
}
// out_path = fmt::format("{}:/binaryList.txt", "TimeZoneBinary");
out_path = "/binaryList.txt";
}
-void GetTimeZoneBinaryVersionPath(std::string& out_path) {
- if (g_time_zone_binary_mount_result != ResultSuccess) {
+void TimeZoneBinary::GetVersionPath(std::string& out_path) {
+ if (time_zone_binary_mount_result != ResultSuccess) {
return;
}
// out_path = fmt::format("{}:/version.txt", "TimeZoneBinary");
out_path = "/version.txt";
}
-void GetTimeZoneZonePath(std::string& out_path, const Service::PSC::Time::LocationName& name) {
- if (g_time_zone_binary_mount_result != ResultSuccess) {
+void TimeZoneBinary::GetTimeZonePath(std::string& out_path,
+ const Service::PSC::Time::LocationName& name) {
+ if (time_zone_binary_mount_result != ResultSuccess) {
return;
}
// out_path = fmt::format("{}:/zoneinfo/{}", "TimeZoneBinary", name);
out_path = fmt::format("/zoneinfo/{}", name.data());
}
-bool IsTimeZoneBinaryValid(const Service::PSC::Time::LocationName& name) {
+bool TimeZoneBinary::IsValid(const Service::PSC::Time::LocationName& name) {
std::string path{};
- GetTimeZoneZonePath(path, name);
+ GetTimeZonePath(path, name);
- auto vfs_file{g_time_zone_binary_romfs->GetFileRelative(path)};
+ auto vfs_file{time_zone_binary_romfs->GetFileRelative(path)};
if (!vfs_file) {
LOG_INFO(Service_Time, "Could not find timezone file {}", path);
return false;
@@ -119,19 +114,19 @@ bool IsTimeZoneBinaryValid(const Service::PSC::Time::LocationName& name) {
return vfs_file->GetSize() != 0;
}
-u32 GetTimeZoneCount() {
+u32 TimeZoneBinary::GetTimeZoneCount() {
std::string path{};
- GetTimeZoneBinaryListPath(path);
+ GetListPath(path);
size_t bytes_read{};
- if (TimeZoneReadBinary(bytes_read, g_time_zone_scratch_space, 0x2800, path) != ResultSuccess) {
+ if (Read(bytes_read, time_zone_scratch_space, 0x2800, path) != ResultSuccess) {
return 0;
}
if (bytes_read == 0) {
return 0;
}
- auto chars = std::span(reinterpret_cast<char*>(g_time_zone_scratch_space.data()), bytes_read);
+ auto chars = std::span(reinterpret_cast<char*>(time_zone_scratch_space.data()), bytes_read);
u32 count{};
for (auto chr : chars) {
if (chr == '\n') {
@@ -141,50 +136,47 @@ u32 GetTimeZoneCount() {
return count;
}
-Result GetTimeZoneVersion(Service::PSC::Time::RuleVersion& out_rule_version) {
+Result TimeZoneBinary::GetTimeZoneVersion(Service::PSC::Time::RuleVersion& out_rule_version) {
std::string path{};
- GetTimeZoneBinaryVersionPath(path);
+ GetVersionPath(path);
auto rule_version_buffer{std::span(reinterpret_cast<u8*>(&out_rule_version),
sizeof(Service::PSC::Time::RuleVersion))};
size_t bytes_read{};
- R_TRY(TimeZoneReadBinary(bytes_read, rule_version_buffer, rule_version_buffer.size_bytes(),
- path));
+ R_TRY(Read(bytes_read, rule_version_buffer, rule_version_buffer.size_bytes(), path));
rule_version_buffer[bytes_read] = 0;
R_SUCCEED();
}
-Result GetTimeZoneRule(std::span<const u8>& out_rule, size_t& out_rule_size,
- const Service::PSC::Time::LocationName& name) {
+Result TimeZoneBinary::GetTimeZoneRule(std::span<const u8>& out_rule, size_t& out_rule_size,
+ const Service::PSC::Time::LocationName& name) {
std::string path{};
- GetTimeZoneZonePath(path, name);
+ GetTimeZonePath(path, name);
size_t bytes_read{};
- R_TRY(TimeZoneReadBinary(bytes_read, g_time_zone_scratch_space,
- g_time_zone_scratch_space.size(), path));
+ R_TRY(Read(bytes_read, time_zone_scratch_space, time_zone_scratch_space.size(), path));
- out_rule = std::span(g_time_zone_scratch_space.data(), bytes_read);
+ out_rule = std::span(time_zone_scratch_space.data(), bytes_read);
out_rule_size = bytes_read;
R_SUCCEED();
}
-Result GetTimeZoneLocationList(u32& out_count,
- std::span<Service::PSC::Time::LocationName> out_names,
- size_t max_names, u32 index) {
+Result TimeZoneBinary::GetTimeZoneLocationList(
+ u32& out_count, std::span<Service::PSC::Time::LocationName> out_names, size_t max_names,
+ u32 index) {
std::string path{};
- GetTimeZoneBinaryListPath(path);
+ GetListPath(path);
size_t bytes_read{};
- R_TRY(TimeZoneReadBinary(bytes_read, g_time_zone_scratch_space,
- g_time_zone_scratch_space.size(), path));
+ R_TRY(Read(bytes_read, time_zone_scratch_space, time_zone_scratch_space.size(), path));
out_count = 0;
R_SUCCEED_IF(bytes_read == 0);
Service::PSC::Time::LocationName current_name{};
size_t current_name_len{};
- std::span<const u8> chars{g_time_zone_scratch_space};
+ std::span<const u8> chars{time_zone_scratch_space};
u32 name_count{};
for (auto chr : chars) {
diff --git a/src/core/hle/service/glue/time/time_zone_binary.h b/src/core/hle/service/glue/time/time_zone_binary.h
index 9d0a8dfe95..135da631f2 100644
--- a/src/core/hle/service/glue/time/time_zone_binary.h
+++ b/src/core/hle/service/glue/time/time_zone_binary.h
@@ -6,6 +6,7 @@
#include <span>
#include <string>
#include <string_view>
+#include <vector>
#include "core/hle/service/psc/time/common.h"
@@ -15,18 +16,34 @@ class System;
namespace Service::Glue::Time {
-void ResetTimeZoneBinary();
-Result MountTimeZoneBinary(Core::System& system);
-void GetTimeZoneBinaryListPath(std::string& out_path);
-void GetTimeZoneBinaryVersionPath(std::string& out_path);
-void GetTimeZoneZonePath(std::string& out_path, const Service::PSC::Time::LocationName& name);
-bool IsTimeZoneBinaryValid(const Service::PSC::Time::LocationName& name);
-u32 GetTimeZoneCount();
-Result GetTimeZoneVersion(Service::PSC::Time::RuleVersion& out_rule_version);
-Result GetTimeZoneRule(std::span<const u8>& out_rule, size_t& out_rule_size,
- const Service::PSC::Time::LocationName& name);
-Result GetTimeZoneLocationList(u32& out_count,
- std::span<Service::PSC::Time::LocationName> out_names,
- size_t max_names, u32 index);
+class TimeZoneBinary {
+public:
+ explicit TimeZoneBinary(Core::System& system_)
+ : time_zone_scratch_space(0x2800, 0), system{system_} {}
+
+ Result Mount();
+ bool IsValid(const Service::PSC::Time::LocationName& name);
+ u32 GetTimeZoneCount();
+ Result GetTimeZoneVersion(Service::PSC::Time::RuleVersion& out_rule_version);
+ Result GetTimeZoneRule(std::span<const u8>& out_rule, size_t& out_rule_size,
+ const Service::PSC::Time::LocationName& name);
+ Result GetTimeZoneLocationList(u32& out_count,
+ std::span<Service::PSC::Time::LocationName> out_names,
+ size_t max_names, u32 index);
+
+private:
+ void Reset();
+ Result Read(size_t& out_read_size, std::span<u8> out_buffer, size_t out_buffer_size,
+ std::string_view path);
+ void GetListPath(std::string& out_path);
+ void GetVersionPath(std::string& out_path);
+ void GetTimeZonePath(std::string& out_path, const Service::PSC::Time::LocationName& name);
+
+ FileSys::VirtualDir time_zone_binary_romfs{};
+ Result time_zone_binary_mount_result{ResultUnknown};
+ std::vector<u8> time_zone_scratch_space;
+
+ Core::System& system;
+};
} // namespace Service::Glue::Time
diff --git a/src/core/hle/service/glue/time/worker.cpp b/src/core/hle/service/glue/time/worker.cpp
index b6bbd7965a..1dab3e9dcb 100644
--- a/src/core/hle/service/glue/time/worker.cpp
+++ b/src/core/hle/service/glue/time/worker.cpp
@@ -16,23 +16,6 @@
#include "core/hle/service/sm/sm.h"
namespace Service::Glue::Time {
-namespace {
-
-bool g_ig_report_network_clock_context_set{};
-Service::PSC::Time::SystemClockContext g_report_network_clock_context{};
-bool g_ig_report_ephemeral_clock_context_set{};
-Service::PSC::Time::SystemClockContext g_report_ephemeral_clock_context{};
-
-template <typename T>
-T GetSettingsItemValue(std::shared_ptr<Service::Set::ISystemSettingsServer>& set_sys,
- const char* category, const char* name) {
- T v{};
- auto res = set_sys->GetSettingsItemValueImpl(v, category, name);
- ASSERT(res == ResultSuccess);
- return v;
-}
-
-} // namespace
TimeWorker::TimeWorker(Core::System& system, StandardSteadyClockResource& steady_clock_resource,
FileTimestampWorker& file_timestamp_worker)
@@ -43,11 +26,6 @@ TimeWorker::TimeWorker(Core::System& system, StandardSteadyClockResource& steady
"Glue:TimeWorker:SteadyClockTimerEvent")},
m_timer_file_system{m_ctx.CreateEvent("Glue:TimeWorker:FileTimeTimerEvent")},
m_alarm_worker{m_system, m_steady_clock_resource}, m_pm_state_change_handler{m_alarm_worker} {
- g_ig_report_network_clock_context_set = false;
- g_report_network_clock_context = {};
- g_ig_report_ephemeral_clock_context_set = false;
- g_report_ephemeral_clock_context = {};
-
m_timer_steady_clock_timing_event = Core::Timing::CreateEvent(
"Time::SteadyClockEvent",
[this](s64 time,
@@ -82,6 +60,14 @@ TimeWorker::~TimeWorker() {
m_ctx.CloseEvent(m_timer_file_system);
}
+template <typename T>
+T TimeWorker::GetSettingsItemValue(const std::string& category, const std::string& name) {
+ T v{};
+ auto res = m_set_sys->GetSettingsItemValueImpl(v, category, name);
+ ASSERT(res == ResultSuccess);
+ return v;
+}
+
void TimeWorker::Initialize(std::shared_ptr<Service::PSC::Time::StaticService> time_sm,
std::shared_ptr<Service::Set::ISystemSettingsServer> set_sys) {
m_set_sys = std::move(set_sys);
@@ -91,8 +77,8 @@ void TimeWorker::Initialize(std::shared_ptr<Service::PSC::Time::StaticService> t
m_alarm_worker.Initialize(m_time_m);
- auto steady_clock_interval_m = GetSettingsItemValue<s32>(
- m_set_sys, "time", "standard_steady_clock_rtc_update_interval_minutes");
+ auto steady_clock_interval_m =
+ GetSettingsItemValue<s32>("time", "standard_steady_clock_rtc_update_interval_minutes");
auto one_minute_ns{
std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::minutes(1)).count()};
@@ -102,8 +88,7 @@ void TimeWorker::Initialize(std::shared_ptr<Service::PSC::Time::StaticService> t
std::chrono::nanoseconds(steady_clock_interval_ns),
m_timer_steady_clock_timing_event);
- auto fs_notify_time_s =
- GetSettingsItemValue<s32>(m_set_sys, "time", "notify_time_to_fs_interval_seconds");
+ auto fs_notify_time_s = GetSettingsItemValue<s32>("time", "notify_time_to_fs_interval_seconds");
auto one_second_ns{
std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::seconds(1)).count()};
s64 fs_notify_time_ns{fs_notify_time_s * one_second_ns};
@@ -218,14 +203,14 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) {
}
[[maybe_unused]] auto offset_before{
- g_ig_report_network_clock_context_set ? g_report_network_clock_context.offset : 0};
+ m_ig_report_network_clock_context_set ? m_report_network_clock_context.offset : 0};
// TODO system report "standard_netclock_operation"
// "clock_time" = time
// "context_offset_before" = offset_before
// "context_offset_after" = context.offset
- g_report_network_clock_context = context;
- if (!g_ig_report_network_clock_context_set) {
- g_ig_report_network_clock_context_set = true;
+ m_report_network_clock_context = context;
+ if (!m_ig_report_network_clock_context_set) {
+ m_ig_report_network_clock_context_set = true;
}
m_file_timestamp_worker.SetFilesystemPosixTime();
@@ -247,16 +232,16 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) {
break;
}
- [[maybe_unused]] auto offset_before{g_ig_report_ephemeral_clock_context_set
- ? g_report_ephemeral_clock_context.offset
+ [[maybe_unused]] auto offset_before{m_ig_report_ephemeral_clock_context_set
+ ? m_report_ephemeral_clock_context.offset
: 0};
// TODO system report "ephemeral_netclock_operation"
// "clock_time" = time
// "context_offset_before" = offset_before
// "context_offset_after" = context.offset
- g_report_ephemeral_clock_context = context;
- if (!g_ig_report_ephemeral_clock_context_set) {
- g_ig_report_ephemeral_clock_context_set = true;
+ m_report_ephemeral_clock_context = context;
+ if (!m_ig_report_ephemeral_clock_context_set) {
+ m_ig_report_ephemeral_clock_context_set = true;
}
break;
}
diff --git a/src/core/hle/service/glue/time/worker.h b/src/core/hle/service/glue/time/worker.h
index 75e5c4d0f1..69904e6748 100644
--- a/src/core/hle/service/glue/time/worker.h
+++ b/src/core/hle/service/glue/time/worker.h
@@ -34,6 +34,9 @@ public:
void StartThread();
private:
+ template <typename T>
+ T GetSettingsItemValue(const std::string& category, const std::string& name);
+
void ThreadFunc(std::stop_token stop_token);
Core::System& m_system;
@@ -59,6 +62,11 @@ private:
std::shared_ptr<Core::Timing::EventType> m_timer_file_system_timing_event;
AlarmWorker m_alarm_worker;
PmStateChangeHandler m_pm_state_change_handler;
+
+ bool m_ig_report_network_clock_context_set{};
+ Service::PSC::Time::SystemClockContext m_report_network_clock_context{};
+ bool m_ig_report_ephemeral_clock_context_set{};
+ Service::PSC::Time::SystemClockContext m_report_ephemeral_clock_context{};
};
} // namespace Service::Glue::Time
diff --git a/src/core/hle/service/nvdrv/core/container.h b/src/core/hle/service/nvdrv/core/container.h
index f159ced09b..cf549d7f32 100644
--- a/src/core/hle/service/nvdrv/core/container.h
+++ b/src/core/hle/service/nvdrv/core/container.h
@@ -68,10 +68,7 @@ public:
const SyncpointManager& GetSyncpointManager() const;
struct Host1xDeviceFileData {
- std::unordered_map<DeviceFD, u32> fd_to_id{};
std::deque<u32> syncpts_accumulated{};
- u32 nvdec_next_id{};
- u32 vic_next_id{};
};
Host1xDeviceFileData& Host1xDeviceFile();
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
index 2c0ac2a46e..60b89b6284 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
@@ -8,6 +8,7 @@
#include "core/hle/service/nvdrv/core/container.h"
#include "core/hle/service/nvdrv/devices/ioctl_serialization.h"
#include "core/hle/service/nvdrv/devices/nvhost_nvdec.h"
+#include "video_core/host1x/host1x.h"
#include "video_core/renderer_base.h"
namespace Service::Nvidia::Devices {
@@ -21,13 +22,8 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> in
switch (command.group) {
case 0x0:
switch (command.cmd) {
- case 0x1: {
- auto& host1x_file = core.Host1xDeviceFile();
- if (!host1x_file.fd_to_id.contains(fd)) {
- host1x_file.fd_to_id[fd] = host1x_file.nvdec_next_id++;
- }
+ case 0x1:
return WrapFixedVariable(this, &nvhost_nvdec::Submit, input, output, fd);
- }
case 0x2:
return WrapFixed(this, &nvhost_nvdec::GetSyncpoint, input, output);
case 0x3:
@@ -72,15 +68,12 @@ void nvhost_nvdec::OnOpen(NvCore::SessionId session_id, DeviceFD fd) {
LOG_INFO(Service_NVDRV, "NVDEC video stream started");
system.SetNVDECActive(true);
sessions[fd] = session_id;
+ host1x.StartDevice(fd, Tegra::Host1x::ChannelType::NvDec, channel_syncpoint);
}
void nvhost_nvdec::OnClose(DeviceFD fd) {
LOG_INFO(Service_NVDRV, "NVDEC video stream ended");
- auto& host1x_file = core.Host1xDeviceFile();
- const auto iter = host1x_file.fd_to_id.find(fd);
- if (iter != host1x_file.fd_to_id.end()) {
- system.GPU().ClearCdmaInstance(iter->second);
- }
+ host1x.StopDevice(fd, Tegra::Host1x::ChannelType::NvDec);
system.SetNVDECActive(false);
auto it = sessions.find(fd);
if (it != sessions.end()) {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
index a0a7bfa400..9ca6308e6f 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
@@ -55,8 +55,9 @@ std::size_t WriteVectors(std::span<u8> dst, const std::vector<T>& src, std::size
nvhost_nvdec_common::nvhost_nvdec_common(Core::System& system_, NvCore::Container& core_,
NvCore::ChannelType channel_type_)
- : nvdevice{system_}, core{core_}, syncpoint_manager{core.GetSyncpointManager()},
- nvmap{core.GetNvMapFile()}, channel_type{channel_type_} {
+ : nvdevice{system_}, host1x{system_.Host1x()}, core{core_},
+ syncpoint_manager{core.GetSyncpointManager()}, nvmap{core.GetNvMapFile()},
+ channel_type{channel_type_} {
auto& syncpts_accumulated = core.Host1xDeviceFile().syncpts_accumulated;
if (syncpts_accumulated.empty()) {
channel_syncpoint = syncpoint_manager.AllocateSyncpoint(false);
@@ -95,24 +96,24 @@ NvResult nvhost_nvdec_common::Submit(IoctlSubmit& params, std::span<u8> data, De
offset += SliceVectors(data, syncpt_increments, params.syncpoint_count, offset);
offset += SliceVectors(data, fence_thresholds, params.fence_count, offset);
- auto& gpu = system.GPU();
auto* session = core.GetSession(sessions[fd]);
- if (gpu.UseNvdec()) {
- for (std::size_t i = 0; i < syncpt_increments.size(); i++) {
- const SyncptIncr& syncpt_incr = syncpt_increments[i];
- fence_thresholds[i] =
- syncpoint_manager.IncrementSyncpointMaxExt(syncpt_incr.id, syncpt_incr.increments);
- }
+ for (std::size_t i = 0; i < syncpt_increments.size(); i++) {
+ const SyncptIncr& syncpt_incr = syncpt_increments[i];
+ fence_thresholds[i] =
+ syncpoint_manager.IncrementSyncpointMaxExt(syncpt_incr.id, syncpt_incr.increments);
}
+
for (const auto& cmd_buffer : command_buffers) {
const auto object = nvmap.GetHandle(cmd_buffer.memory_id);
ASSERT_OR_EXECUTE(object, return NvResult::InvalidState;);
- Tegra::ChCommandHeaderList cmdlist(cmd_buffer.word_count);
- session->process->GetMemory().ReadBlock(object->address + cmd_buffer.offset, cmdlist.data(),
- cmdlist.size() * sizeof(u32));
- gpu.PushCommandBuffer(core.Host1xDeviceFile().fd_to_id[fd], cmdlist);
+ Core::Memory::CpuGuestMemory<Tegra::ChCommandHeader,
+ Core::Memory::GuestMemoryFlags::SafeRead>
+ cmdlist(session->process->GetMemory(), object->address + cmd_buffer.offset,
+ cmd_buffer.word_count);
+ host1x.PushEntries(fd, std::move(cmdlist));
}
+
// Some games expect command_buffers to be written back
offset = 0;
offset += WriteVectors(data, command_buffers, offset);
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
index 900db81d27..63e6377603 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
@@ -119,6 +119,7 @@ protected:
Kernel::KEvent* QueryEvent(u32 event_id) override;
+ Tegra::Host1x::Host1x& host1x;
u32 channel_syncpoint;
s32_le nvmap_fd{};
u32_le submit_timeout{};
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
index bf090f5eb2..8219a2c7e8 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
@@ -7,6 +7,7 @@
#include "core/hle/service/nvdrv/core/container.h"
#include "core/hle/service/nvdrv/devices/ioctl_serialization.h"
#include "core/hle/service/nvdrv/devices/nvhost_vic.h"
+#include "video_core/host1x/host1x.h"
#include "video_core/renderer_base.h"
namespace Service::Nvidia::Devices {
@@ -21,13 +22,8 @@ NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inpu
switch (command.group) {
case 0x0:
switch (command.cmd) {
- case 0x1: {
- auto& host1x_file = core.Host1xDeviceFile();
- if (!host1x_file.fd_to_id.contains(fd)) {
- host1x_file.fd_to_id[fd] = host1x_file.vic_next_id++;
- }
+ case 0x1:
return WrapFixedVariable(this, &nvhost_vic::Submit, input, output, fd);
- }
case 0x2:
return WrapFixed(this, &nvhost_vic::GetSyncpoint, input, output);
case 0x3:
@@ -70,14 +66,11 @@ NvResult nvhost_vic::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> inpu
void nvhost_vic::OnOpen(NvCore::SessionId session_id, DeviceFD fd) {
sessions[fd] = session_id;
+ host1x.StartDevice(fd, Tegra::Host1x::ChannelType::VIC, channel_syncpoint);
}
void nvhost_vic::OnClose(DeviceFD fd) {
- auto& host1x_file = core.Host1xDeviceFile();
- const auto iter = host1x_file.fd_to_id.find(fd);
- if (iter != host1x_file.fd_to_id.end()) {
- system.GPU().ClearCdmaInstance(iter->second);
- }
+ host1x.StopDevice(fd, Tegra::Host1x::ChannelType::VIC);
sessions.erase(fd);
}
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
index b6e355622e..6aabdc75e1 100644
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -36,22 +36,23 @@ std::optional<FileType> IdentifyFileLoader(FileSys::VirtualFile file) {
} // namespace
FileType IdentifyFile(FileSys::VirtualFile file) {
- if (const auto romdir_type = IdentifyFileLoader<AppLoader_DeconstructedRomDirectory>(file)) {
- return *romdir_type;
- } else if (const auto nso_type = IdentifyFileLoader<AppLoader_NSO>(file)) {
- return *nso_type;
+ if (const auto nsp_type = IdentifyFileLoader<AppLoader_NSP>(file)) {
+ return *nsp_type;
+ } else if (const auto xci_type = IdentifyFileLoader<AppLoader_XCI>(file)) {
+ return *xci_type;
} else if (const auto nro_type = IdentifyFileLoader<AppLoader_NRO>(file)) {
return *nro_type;
} else if (const auto nca_type = IdentifyFileLoader<AppLoader_NCA>(file)) {
return *nca_type;
- } else if (const auto xci_type = IdentifyFileLoader<AppLoader_XCI>(file)) {
- return *xci_type;
} else if (const auto nax_type = IdentifyFileLoader<AppLoader_NAX>(file)) {
return *nax_type;
- } else if (const auto nsp_type = IdentifyFileLoader<AppLoader_NSP>(file)) {
- return *nsp_type;
} else if (const auto kip_type = IdentifyFileLoader<AppLoader_KIP>(file)) {
return *kip_type;
+ } else if (const auto nso_type = IdentifyFileLoader<AppLoader_NSO>(file)) {
+ return *nso_type;
+ } else if (const auto romdir_type =
+ IdentifyFileLoader<AppLoader_DeconstructedRomDirectory>(file)) {
+ return *romdir_type;
} else {
return FileType::Unknown;
}
diff --git a/src/core/memory.h b/src/core/memory.h
index f7e6b297f6..dcca26892b 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -64,6 +64,8 @@ public:
Memory(Memory&&) = default;
Memory& operator=(Memory&&) = delete;
+ static constexpr bool HAS_FLUSH_INVALIDATION = false;
+
/**
* Resets the state of the Memory system.
*/