diff options
Diffstat (limited to 'src/core')
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. */ |
