mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	core: hle: Address various feedback & code cleanup.
- Should be no functional changes.
This commit is contained in:
		
							parent
							
								
									92caa003a8
								
							
						
					
					
						commit
						8bbe74a8dc
					
				| @ -13,13 +13,15 @@ namespace Core { | ||||
| class System; | ||||
| 
 | ||||
| namespace DramMemoryMap { | ||||
| constexpr u64 Base = 0x80000000ULL; | ||||
| constexpr u64 Size = 0x100000000ULL; | ||||
| constexpr u64 End = Base + Size; | ||||
| constexpr u64 KernelReserveBase = Base + 0x60000; | ||||
| constexpr u64 SlabHeapBase = KernelReserveBase + 0x85000; | ||||
| constexpr u64 SlapHeapSize = 0xa21000; | ||||
| constexpr u64 SlabHeapEnd = SlabHeapBase + SlapHeapSize; | ||||
| enum : u64 { | ||||
|     Base = 0x80000000ULL, | ||||
|     Size = 0x100000000ULL, | ||||
|     End = Base + Size, | ||||
|     KernelReserveBase = Base + 0x60000, | ||||
|     SlabHeapBase = KernelReserveBase + 0x85000, | ||||
|     SlapHeapSize = 0xa21000, | ||||
|     SlabHeapEnd = SlabHeapBase + SlapHeapSize, | ||||
| }; | ||||
| }; // namespace DramMemoryMap
 | ||||
| 
 | ||||
| class DeviceMemory : NonCopyable { | ||||
|  | ||||
| @ -14,16 +14,18 @@ namespace Kernel::Memory { | ||||
| 
 | ||||
| namespace { | ||||
| 
 | ||||
| constexpr std::size_t Size_1_MB{0x100000}; | ||||
| constexpr std::size_t Size_2_MB{2 * Size_1_MB}; | ||||
| constexpr std::size_t Size_128_MB{128 * Size_1_MB}; | ||||
| constexpr std::size_t Size_1_GB{0x40000000}; | ||||
| constexpr std::size_t Size_2_GB{2 * Size_1_GB}; | ||||
| constexpr std::size_t Size_4_GB{4 * Size_1_GB}; | ||||
| constexpr std::size_t Size_6_GB{6 * Size_1_GB}; | ||||
| constexpr std::size_t Size_64_GB{64 * Size_1_GB}; | ||||
| constexpr std::size_t Size_512_GB{512 * Size_1_GB}; | ||||
| constexpr u64 Invalid{std::numeric_limits<u64>::max()}; | ||||
| enum : u64 { | ||||
|     Size_1_MB = 0x100000, | ||||
|     Size_2_MB = 2 * Size_1_MB, | ||||
|     Size_128_MB = 128 * Size_1_MB, | ||||
|     Size_1_GB = 0x40000000, | ||||
|     Size_2_GB = 2 * Size_1_GB, | ||||
|     Size_4_GB = 4 * Size_1_GB, | ||||
|     Size_6_GB = 6 * Size_1_GB, | ||||
|     Size_64_GB = 64 * Size_1_GB, | ||||
|     Size_512_GB = 512 * Size_1_GB, | ||||
|     Invalid = std::numeric_limits<u64>::max(), | ||||
| }; | ||||
| 
 | ||||
| // clang-format off
 | ||||
| constexpr std::array<AddressSpaceInfo, 13> AddressSpaceInfos{{ | ||||
|  | ||||
| @ -15,7 +15,7 @@ MemoryBlockManager::MemoryBlockManager(VAddr start_addr, VAddr end_addr) | ||||
| } | ||||
| 
 | ||||
| MemoryBlockManager::iterator MemoryBlockManager::FindIterator(VAddr addr) { | ||||
|     iterator node{memory_block_tree.begin()}; | ||||
|     auto node{memory_block_tree.begin()}; | ||||
|     while (node != end()) { | ||||
|         const VAddr end_addr{node->GetNumPages() * PageSize + node->GetAddress()}; | ||||
|         if (node->GetAddress() <= addr && end_addr - 1 >= addr) { | ||||
| @ -35,8 +35,8 @@ VAddr MemoryBlockManager::FindFreeArea(VAddr region_start, std::size_t region_nu | ||||
| 
 | ||||
|     const VAddr region_end{region_start + region_num_pages * PageSize}; | ||||
|     const VAddr region_last{region_end - 1}; | ||||
|     for (const_iterator it{FindIterator(region_start)}; it != memory_block_tree.cend(); it++) { | ||||
|         const MemoryInfo info{it->GetMemoryInfo()}; | ||||
|     for (auto it{FindIterator(region_start)}; it != memory_block_tree.cend(); it++) { | ||||
|         const auto info{it->GetMemoryInfo()}; | ||||
|         if (region_last < info.GetAddress()) { | ||||
|             break; | ||||
|         } | ||||
|  | ||||
| @ -15,15 +15,14 @@ | ||||
| namespace Kernel::Memory { | ||||
| 
 | ||||
| std::size_t MemoryManager::Impl::Initialize(Pool new_pool, u64 start_address, u64 end_address) { | ||||
|     const std::size_t size{end_address - start_address}; | ||||
|     const auto size{end_address - start_address}; | ||||
| 
 | ||||
|     // Calculate metadata sizes
 | ||||
|     const std::size_t ref_count_size{(size / PageSize) * sizeof(u16)}; | ||||
|     const std::size_t optimize_map_size{(Common::AlignUp((size / PageSize), 64) / 64) * | ||||
|                                         sizeof(u64)}; | ||||
|     const std::size_t manager_size{Common::AlignUp(optimize_map_size + ref_count_size, PageSize)}; | ||||
|     const std::size_t page_heap_size{PageHeap::CalculateMetadataOverheadSize(size)}; | ||||
|     const std::size_t total_metadata_size{manager_size + page_heap_size}; | ||||
|     const auto ref_count_size{(size / PageSize) * sizeof(u16)}; | ||||
|     const auto optimize_map_size{(Common::AlignUp((size / PageSize), 64) / 64) * sizeof(u64)}; | ||||
|     const auto manager_size{Common::AlignUp(optimize_map_size + ref_count_size, PageSize)}; | ||||
|     const auto page_heap_size{PageHeap::CalculateMetadataOverheadSize(size)}; | ||||
|     const auto total_metadata_size{manager_size + page_heap_size}; | ||||
|     ASSERT(manager_size <= total_metadata_size); | ||||
|     ASSERT(Common::IsAligned(total_metadata_size, PageSize)); | ||||
| 
 | ||||
| @ -55,7 +54,7 @@ VAddr MemoryManager::AllocateContinuous(std::size_t num_pages, std::size_t align | ||||
|     } | ||||
| 
 | ||||
|     // Lock the pool that we're allocating from
 | ||||
|     const std::size_t pool_index{static_cast<std::size_t>(pool)}; | ||||
|     const auto pool_index{static_cast<std::size_t>(pool)}; | ||||
|     std::lock_guard lock{pool_locks[pool_index]}; | ||||
| 
 | ||||
|     // Choose a heap based on our page size request
 | ||||
| @ -72,7 +71,7 @@ VAddr MemoryManager::AllocateContinuous(std::size_t num_pages, std::size_t align | ||||
|     } | ||||
| 
 | ||||
|     // If we allocated more than we need, free some
 | ||||
|     const std::size_t allocated_pages{PageHeap::GetBlockNumPages(heap_index)}; | ||||
|     const auto allocated_pages{PageHeap::GetBlockNumPages(heap_index)}; | ||||
|     if (allocated_pages > num_pages) { | ||||
|         chosen_manager.Free(allocated_block + num_pages * PageSize, allocated_pages - num_pages); | ||||
|     } | ||||
| @ -90,7 +89,7 @@ ResultCode MemoryManager::Allocate(PageLinkedList& page_list, std::size_t num_pa | ||||
|     } | ||||
| 
 | ||||
|     // Lock the pool that we're allocating from
 | ||||
|     const std::size_t pool_index{static_cast<std::size_t>(pool)}; | ||||
|     const auto pool_index{static_cast<std::size_t>(pool)}; | ||||
|     std::lock_guard lock{pool_locks[pool_index]}; | ||||
| 
 | ||||
|     // Choose a heap based on our page size request
 | ||||
| @ -105,7 +104,7 @@ ResultCode MemoryManager::Allocate(PageLinkedList& page_list, std::size_t num_pa | ||||
|     // Ensure that we don't leave anything un-freed
 | ||||
|     auto group_guard = detail::ScopeExit([&] { | ||||
|         for (const auto& it : page_list.Nodes()) { | ||||
|             const std::size_t num_pages{std::min( | ||||
|             const auto num_pages{std::min( | ||||
|                 it.GetNumPages(), (chosen_manager.GetEndAddress() - it.GetAddress()) / PageSize)}; | ||||
|             chosen_manager.Free(it.GetAddress(), num_pages); | ||||
|         } | ||||
| @ -113,12 +112,12 @@ ResultCode MemoryManager::Allocate(PageLinkedList& page_list, std::size_t num_pa | ||||
| 
 | ||||
|     // Keep allocating until we've allocated all our pages
 | ||||
|     for (s32 index{heap_index}; index >= 0 && num_pages > 0; index--) { | ||||
|         const std::size_t pages_per_alloc{PageHeap::GetBlockNumPages(index)}; | ||||
|         const auto pages_per_alloc{PageHeap::GetBlockNumPages(index)}; | ||||
| 
 | ||||
|         while (num_pages >= pages_per_alloc) { | ||||
|             // Allocate a block
 | ||||
|             VAddr allocated_block{chosen_manager.AllocateBlock(index)}; | ||||
|             if (allocated_block == 0) { | ||||
|             if (!allocated_block) { | ||||
|                 break; | ||||
|             } | ||||
| 
 | ||||
| @ -158,7 +157,7 @@ ResultCode MemoryManager::Free(PageLinkedList& page_list, std::size_t num_pages, | ||||
|     } | ||||
| 
 | ||||
|     // Lock the pool that we're freeing from
 | ||||
|     const std::size_t pool_index{static_cast<std::size_t>(pool)}; | ||||
|     const auto pool_index{static_cast<std::size_t>(pool)}; | ||||
|     std::lock_guard lock{pool_locks[pool_index]}; | ||||
| 
 | ||||
|     // TODO (bunnei): Support multiple managers
 | ||||
| @ -166,7 +165,7 @@ ResultCode MemoryManager::Free(PageLinkedList& page_list, std::size_t num_pages, | ||||
| 
 | ||||
|     // Free all of the pages
 | ||||
|     for (const auto& it : page_list.Nodes()) { | ||||
|         const std::size_t num_pages{std::min( | ||||
|         const auto num_pages{std::min( | ||||
|             it.GetNumPages(), (chosen_manager.GetEndAddress() - it.GetAddress()) / PageSize)}; | ||||
|         chosen_manager.Free(it.GetAddress(), num_pages); | ||||
|     } | ||||
|  | ||||
| @ -22,9 +22,10 @@ namespace Kernel::Memory { | ||||
| class PageHeap final : NonCopyable { | ||||
| public: | ||||
|     static constexpr s32 GetAlignedBlockIndex(std::size_t num_pages, std::size_t align_pages) { | ||||
|         const std::size_t target_pages{std::max(num_pages, align_pages)}; | ||||
|         const auto target_pages{std::max(num_pages, align_pages)}; | ||||
|         for (std::size_t i = 0; i < NumMemoryBlockPageShifts; i++) { | ||||
|             if (target_pages <= (std::size_t(1) << MemoryBlockPageShifts[i]) / PageSize) { | ||||
|             if (target_pages <= | ||||
|                 (static_cast<std::size_t>(1) << MemoryBlockPageShifts[i]) / PageSize) { | ||||
|                 return static_cast<s32>(i); | ||||
|             } | ||||
|         } | ||||
| @ -33,7 +34,7 @@ public: | ||||
| 
 | ||||
|     static constexpr s32 GetBlockIndex(std::size_t num_pages) { | ||||
|         for (s32 i{static_cast<s32>(NumMemoryBlockPageShifts) - 1}; i >= 0; i--) { | ||||
|             if (num_pages >= (std::size_t(1) << MemoryBlockPageShifts[i]) / PageSize) { | ||||
|             if (num_pages >= (static_cast<std::size_t>(1) << MemoryBlockPageShifts[i]) / PageSize) { | ||||
|                 return i; | ||||
|             } | ||||
|         } | ||||
| @ -41,7 +42,7 @@ public: | ||||
|     } | ||||
| 
 | ||||
|     static constexpr std::size_t GetBlockSize(std::size_t index) { | ||||
|         return std::size_t(1) << MemoryBlockPageShifts[index]; | ||||
|         return static_cast<std::size_t>(1) << MemoryBlockPageShifts[index]; | ||||
|     } | ||||
| 
 | ||||
|     static constexpr std::size_t GetBlockNumPages(std::size_t index) { | ||||
| @ -51,7 +52,8 @@ public: | ||||
| private: | ||||
|     static constexpr std::size_t NumMemoryBlockPageShifts{7}; | ||||
|     static constexpr std::array<std::size_t, NumMemoryBlockPageShifts> MemoryBlockPageShifts{ | ||||
|         0xC, 0x10, 0x15, 0x16, 0x19, 0x1D, 0x1E}; | ||||
|         0xC, 0x10, 0x15, 0x16, 0x19, 0x1D, 0x1E, | ||||
|     }; | ||||
| 
 | ||||
|     class Block final : NonCopyable { | ||||
|     private: | ||||
| @ -122,13 +124,13 @@ private: | ||||
| 
 | ||||
|             constexpr bool ClearRange(std::size_t offset, std::size_t count) { | ||||
|                 const s32 depth{GetHighestDepthIndex()}; | ||||
|                 const std::size_t bit_ind{offset / 64}; | ||||
|                 const auto bit_ind{offset / 64}; | ||||
|                 u64* bits{bit_storages[depth]}; | ||||
|                 if (count < 64) { | ||||
|                     const std::size_t shift{offset % 64}; | ||||
|                     const auto shift{offset % 64}; | ||||
|                     ASSERT(shift + count <= 64); | ||||
|                     // Check that all the bits are set
 | ||||
|                     const u64 mask{((u64(1) << count) - 1) << shift}; | ||||
|                     const u64 mask{((1ULL << count) - 1) << shift}; | ||||
|                     u64 v{bits[bit_ind]}; | ||||
|                     if ((v & mask) != mask) { | ||||
|                         return false; | ||||
| @ -171,9 +173,9 @@ private: | ||||
|         private: | ||||
|             constexpr void SetBit(s32 depth, std::size_t offset) { | ||||
|                 while (depth >= 0) { | ||||
|                     const std::size_t ind{offset / 64}; | ||||
|                     const std::size_t which{offset % 64}; | ||||
|                     const u64 mask{u64(1) << which}; | ||||
|                     const auto ind{offset / 64}; | ||||
|                     const auto which{offset % 64}; | ||||
|                     const u64 mask{1ULL << which}; | ||||
| 
 | ||||
|                     u64* bit{std::addressof(bit_storages[depth][ind])}; | ||||
|                     const u64 v{*bit}; | ||||
| @ -189,9 +191,9 @@ private: | ||||
| 
 | ||||
|             constexpr void ClearBit(s32 depth, std::size_t offset) { | ||||
|                 while (depth >= 0) { | ||||
|                     const std::size_t ind{offset / 64}; | ||||
|                     const std::size_t which{offset % 64}; | ||||
|                     const u64 mask{u64(1) << which}; | ||||
|                     const auto ind{offset / 64}; | ||||
|                     const auto which{offset % 64}; | ||||
|                     const u64 mask{1ULL << which}; | ||||
| 
 | ||||
|                     u64* bit{std::addressof(bit_storages[depth][ind])}; | ||||
|                     u64 v{*bit}; | ||||
| @ -246,7 +248,7 @@ private: | ||||
|             return next_block_shift; | ||||
|         } | ||||
|         constexpr std::size_t GetSize() const { | ||||
|             return std::size_t(1) << GetShift(); | ||||
|             return static_cast<std::size_t>(1) << GetShift(); | ||||
|         } | ||||
|         constexpr std::size_t GetNumPages() const { | ||||
|             return GetSize() / PageSize; | ||||
| @ -266,13 +268,13 @@ private: | ||||
| 
 | ||||
|             // Align up the address
 | ||||
|             VAddr end{addr + size}; | ||||
|             const std::size_t align{(next_block_shift != 0) ? (u64(1) << next_block_shift) | ||||
|                                                             : (u64(1) << block_shift)}; | ||||
|             const auto align{(next_block_shift != 0) ? (1ULL << next_block_shift) | ||||
|                                                      : (1ULL << block_shift)}; | ||||
|             addr = Common::AlignDown((addr), align); | ||||
|             end = Common::AlignUp((end), align); | ||||
| 
 | ||||
|             heap_address = addr; | ||||
|             end_offset = (end - addr) / (u64(1) << block_shift); | ||||
|             end_offset = (end - addr) / (1ULL << block_shift); | ||||
|             return bitmap.Initialize(bit_storage, end_offset); | ||||
|         } | ||||
| 
 | ||||
| @ -283,7 +285,7 @@ private: | ||||
| 
 | ||||
|             // If we have a next shift, try to clear the blocks below and return the address
 | ||||
|             if (GetNextShift()) { | ||||
|                 const std::size_t diff{u64(1) << (GetNextShift() - GetShift())}; | ||||
|                 const auto diff{1ULL << (GetNextShift() - GetShift())}; | ||||
|                 offset = Common::AlignDown(offset, diff); | ||||
|                 if (bitmap.ClearRange(offset, diff)) { | ||||
|                     return heap_address + (offset << GetShift()); | ||||
| @ -300,7 +302,7 @@ private: | ||||
|             if (soffset < 0) { | ||||
|                 return 0; | ||||
|             } | ||||
|             const std::size_t offset{static_cast<std::size_t>(soffset)}; | ||||
|             const auto offset{static_cast<std::size_t>(soffset)}; | ||||
| 
 | ||||
|             // Update our tracking and return it
 | ||||
|             bitmap.ClearBit(offset); | ||||
| @ -311,9 +313,9 @@ private: | ||||
|         static constexpr std::size_t CalculateMetadataOverheadSize(std::size_t region_size, | ||||
|                                                                    std::size_t cur_block_shift, | ||||
|                                                                    std::size_t next_block_shift) { | ||||
|             const std::size_t cur_block_size{(u64(1) << cur_block_shift)}; | ||||
|             const std::size_t next_block_size{(u64(1) << next_block_shift)}; | ||||
|             const std::size_t align{(next_block_shift != 0) ? next_block_size : cur_block_size}; | ||||
|             const auto cur_block_size{(1ULL << cur_block_shift)}; | ||||
|             const auto next_block_size{(1ULL << next_block_shift)}; | ||||
|             const auto align{(next_block_shift != 0) ? next_block_size : cur_block_size}; | ||||
|             return Bitmap::CalculateMetadataOverheadSize( | ||||
|                 (align * 2 + Common::AlignUp(region_size, align)) / cur_block_size); | ||||
|         } | ||||
|  | ||||
| @ -64,10 +64,10 @@ ResultCode PageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_t | ||||
|                                            bool enable_aslr, VAddr code_addr, std::size_t code_size, | ||||
|                                            Memory::MemoryManager::Pool pool) { | ||||
| 
 | ||||
|     const auto GetSpaceStart = [&](AddressSpaceInfo::Type type) { | ||||
|     const auto GetSpaceStart = [this](AddressSpaceInfo::Type type) { | ||||
|         return AddressSpaceInfo::GetAddressSpaceStart(address_space_width, type); | ||||
|     }; | ||||
|     const auto GetSpaceSize = [&](AddressSpaceInfo::Type type) { | ||||
|     const auto GetSpaceSize = [this](AddressSpaceInfo::Type type) { | ||||
|         return AddressSpaceInfo::GetAddressSpaceSize(address_space_width, type); | ||||
|     }; | ||||
| 
 | ||||
| @ -286,17 +286,9 @@ ResultCode PageTable::MapProcessCode(VAddr addr, std::size_t num_pages, MemorySt | ||||
|     } | ||||
| 
 | ||||
|     PageLinkedList page_linked_list; | ||||
|     if (const ResultCode result{ | ||||
|             system.Kernel().MemoryManager().Allocate(page_linked_list, num_pages, memory_pool)}; | ||||
|         result.IsError()) { | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     if (const ResultCode result{ | ||||
|             Operate(addr, num_pages, page_linked_list, OperationType::MapGroup)}; | ||||
|         result.IsError()) { | ||||
|         return result; | ||||
|     } | ||||
|     CASCADE_CODE( | ||||
|         system.Kernel().MemoryManager().Allocate(page_linked_list, num_pages, memory_pool)); | ||||
|     CASCADE_CODE(Operate(addr, num_pages, page_linked_list, OperationType::MapGroup)); | ||||
| 
 | ||||
|     block_manager->Update(addr, num_pages, state, perm); | ||||
| 
 | ||||
| @ -310,13 +302,10 @@ ResultCode PageTable::MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std:: | ||||
| 
 | ||||
|     MemoryState state{}; | ||||
|     MemoryPermission perm{}; | ||||
|     if (const ResultCode result{CheckMemoryState( | ||||
|             &state, &perm, nullptr, src_addr, size, MemoryState::All, MemoryState::Normal, | ||||
|             MemoryPermission::Mask, MemoryPermission::ReadAndWrite, MemoryAttribute::Mask, | ||||
|             MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)}; | ||||
|         result.IsError()) { | ||||
|         return result; | ||||
|     } | ||||
|     CASCADE_CODE(CheckMemoryState(&state, &perm, nullptr, src_addr, size, MemoryState::All, | ||||
|                                   MemoryState::Normal, MemoryPermission::Mask, | ||||
|                                   MemoryPermission::ReadAndWrite, MemoryAttribute::Mask, | ||||
|                                   MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)); | ||||
| 
 | ||||
|     if (IsRegionMapped(dst_addr, size)) { | ||||
|         return ERR_INVALID_ADDRESS_STATE; | ||||
| @ -329,16 +318,9 @@ ResultCode PageTable::MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std:: | ||||
|         auto block_guard = detail::ScopeExit( | ||||
|             [&] { Operate(src_addr, num_pages, perm, OperationType::ChangePermissions); }); | ||||
| 
 | ||||
|         if (const ResultCode result{Operate(src_addr, num_pages, MemoryPermission::None, | ||||
|                                             OperationType::ChangePermissions)}; | ||||
|             result.IsError()) { | ||||
|             return result; | ||||
|         } | ||||
| 
 | ||||
|         if (const ResultCode result{MapPages(dst_addr, page_linked_list, MemoryPermission::None)}; | ||||
|             result.IsError()) { | ||||
|             return result; | ||||
|         } | ||||
|         CASCADE_CODE( | ||||
|             Operate(src_addr, num_pages, MemoryPermission::None, OperationType::ChangePermissions)); | ||||
|         CASCADE_CODE(MapPages(dst_addr, page_linked_list, MemoryPermission::None)); | ||||
| 
 | ||||
|         block_guard.Cancel(); | ||||
|     } | ||||
| @ -359,35 +341,20 @@ ResultCode PageTable::UnmapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std | ||||
| 
 | ||||
|     const std::size_t num_pages{size / PageSize}; | ||||
| 
 | ||||
|     if (const ResultCode result{CheckMemoryState( | ||||
|             nullptr, nullptr, nullptr, src_addr, size, MemoryState::All, MemoryState::Normal, | ||||
|             MemoryPermission::None, MemoryPermission::None, MemoryAttribute::Mask, | ||||
|             MemoryAttribute::Locked, MemoryAttribute::IpcAndDeviceMapped)}; | ||||
|         result.IsError()) { | ||||
|         return result; | ||||
|     } | ||||
|     CASCADE_CODE(CheckMemoryState(nullptr, nullptr, nullptr, src_addr, size, MemoryState::All, | ||||
|                                   MemoryState::Normal, MemoryPermission::None, | ||||
|                                   MemoryPermission::None, MemoryAttribute::Mask, | ||||
|                                   MemoryAttribute::Locked, MemoryAttribute::IpcAndDeviceMapped)); | ||||
| 
 | ||||
|     MemoryState state{}; | ||||
|     if (const ResultCode result{CheckMemoryState( | ||||
|     CASCADE_CODE(CheckMemoryState( | ||||
|         &state, nullptr, nullptr, dst_addr, PageSize, MemoryState::FlagCanCodeAlias, | ||||
|         MemoryState::FlagCanCodeAlias, MemoryPermission::None, MemoryPermission::None, | ||||
|             MemoryAttribute::Mask, MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)}; | ||||
|         result.IsError()) { | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     if (const ResultCode result{CheckMemoryState(dst_addr, size, MemoryState::All, state, | ||||
|                                                  MemoryPermission::None, MemoryPermission::None, | ||||
|                                                  MemoryAttribute::Mask, MemoryAttribute::None)}; | ||||
|         result.IsError()) { | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     if (const ResultCode result{ | ||||
|             Operate(dst_addr, num_pages, MemoryPermission::None, OperationType::Unmap)}; | ||||
|         result.IsError()) { | ||||
|         return result; | ||||
|     } | ||||
|         MemoryAttribute::Mask, MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)); | ||||
|     CASCADE_CODE(CheckMemoryState(dst_addr, size, MemoryState::All, state, MemoryPermission::None, | ||||
|                                   MemoryPermission::None, MemoryAttribute::Mask, | ||||
|                                   MemoryAttribute::None)); | ||||
|     CASCADE_CODE(Operate(dst_addr, num_pages, MemoryPermission::None, OperationType::Unmap)); | ||||
| 
 | ||||
|     block_manager->Update(dst_addr, num_pages, MemoryState::Free); | ||||
|     block_manager->Update(src_addr, num_pages, MemoryState::Normal, MemoryPermission::ReadAndWrite); | ||||
| @ -459,11 +426,8 @@ ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) { | ||||
|             process->GetResourceLimit()->Release(ResourceType::PhysicalMemory, remaining_size); | ||||
|         }); | ||||
| 
 | ||||
|         if (const ResultCode result{system.Kernel().MemoryManager().Allocate( | ||||
|                 page_linked_list, remaining_pages, memory_pool)}; | ||||
|             result.IsError()) { | ||||
|             return result; | ||||
|         } | ||||
|         CASCADE_CODE(system.Kernel().MemoryManager().Allocate(page_linked_list, remaining_pages, | ||||
|                                                               memory_pool)); | ||||
| 
 | ||||
|         block_guard.Cancel(); | ||||
|     } | ||||
| @ -508,9 +472,7 @@ ResultCode PageTable::UnmapPhysicalMemory(VAddr addr, std::size_t size) { | ||||
|         return RESULT_SUCCESS; | ||||
|     } | ||||
| 
 | ||||
|     if (const ResultCode result{UnmapMemory(addr, size)}; result.IsError()) { | ||||
|         return result; | ||||
|     } | ||||
|     CASCADE_CODE(UnmapMemory(addr, size)); | ||||
| 
 | ||||
|     auto process{system.Kernel().CurrentProcess()}; | ||||
|     process->GetResourceLimit()->Release(ResourceType::PhysicalMemory, mapped_size); | ||||
| @ -559,13 +521,10 @@ ResultCode PageTable::Map(VAddr dst_addr, VAddr src_addr, std::size_t size) { | ||||
|     std::lock_guard lock{page_table_lock}; | ||||
| 
 | ||||
|     MemoryState src_state{}; | ||||
|     if (const ResultCode result{CheckMemoryState( | ||||
|     CASCADE_CODE(CheckMemoryState( | ||||
|         &src_state, nullptr, nullptr, src_addr, size, MemoryState::FlagCanAlias, | ||||
|         MemoryState::FlagCanAlias, MemoryPermission::Mask, MemoryPermission::ReadAndWrite, | ||||
|             MemoryAttribute::Mask, MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)}; | ||||
|         result.IsError()) { | ||||
|         return result; | ||||
|     } | ||||
|         MemoryAttribute::Mask, MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)); | ||||
| 
 | ||||
|     if (IsRegionMapped(dst_addr, size)) { | ||||
|         return ERR_INVALID_ADDRESS_STATE; | ||||
| @ -582,17 +541,9 @@ ResultCode PageTable::Map(VAddr dst_addr, VAddr src_addr, std::size_t size) { | ||||
|                     OperationType::ChangePermissions); | ||||
|         }); | ||||
| 
 | ||||
|         if (const ResultCode result{Operate(src_addr, num_pages, MemoryPermission::None, | ||||
|                                             OperationType::ChangePermissions)}; | ||||
|             result.IsError()) { | ||||
|             return result; | ||||
|         } | ||||
| 
 | ||||
|         if (const ResultCode result{ | ||||
|                 MapPages(dst_addr, page_linked_list, MemoryPermission::ReadAndWrite)}; | ||||
|             result.IsError()) { | ||||
|             return result; | ||||
|         } | ||||
|         CASCADE_CODE( | ||||
|             Operate(src_addr, num_pages, MemoryPermission::None, OperationType::ChangePermissions)); | ||||
|         CASCADE_CODE(MapPages(dst_addr, page_linked_list, MemoryPermission::ReadAndWrite)); | ||||
| 
 | ||||
|         block_guard.Cancel(); | ||||
|     } | ||||
| @ -608,22 +559,16 @@ ResultCode PageTable::Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size) { | ||||
|     std::lock_guard lock{page_table_lock}; | ||||
| 
 | ||||
|     MemoryState src_state{}; | ||||
|     if (const ResultCode result{CheckMemoryState( | ||||
|     CASCADE_CODE(CheckMemoryState( | ||||
|         &src_state, nullptr, nullptr, src_addr, size, MemoryState::FlagCanAlias, | ||||
|         MemoryState::FlagCanAlias, MemoryPermission::Mask, MemoryPermission::None, | ||||
|             MemoryAttribute::Mask, MemoryAttribute::Locked, MemoryAttribute::IpcAndDeviceMapped)}; | ||||
|         result.IsError()) { | ||||
|         return result; | ||||
|     } | ||||
|         MemoryAttribute::Mask, MemoryAttribute::Locked, MemoryAttribute::IpcAndDeviceMapped)); | ||||
| 
 | ||||
|     MemoryPermission dst_perm{}; | ||||
|     if (const ResultCode result{CheckMemoryState( | ||||
|             nullptr, &dst_perm, nullptr, dst_addr, size, MemoryState::All, MemoryState::Stack, | ||||
|             MemoryPermission::None, MemoryPermission::None, MemoryAttribute::Mask, | ||||
|             MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)}; | ||||
|         result.IsError()) { | ||||
|         return result; | ||||
|     } | ||||
|     CASCADE_CODE(CheckMemoryState(nullptr, &dst_perm, nullptr, dst_addr, size, MemoryState::All, | ||||
|                                   MemoryState::Stack, MemoryPermission::None, | ||||
|                                   MemoryPermission::None, MemoryAttribute::Mask, | ||||
|                                   MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)); | ||||
| 
 | ||||
|     PageLinkedList src_pages; | ||||
|     PageLinkedList dst_pages; | ||||
| @ -639,17 +584,9 @@ ResultCode PageTable::Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size) { | ||||
|     { | ||||
|         auto block_guard = detail::ScopeExit([&] { MapPages(dst_addr, dst_pages, dst_perm); }); | ||||
| 
 | ||||
|         if (const ResultCode result{ | ||||
|                 Operate(dst_addr, num_pages, MemoryPermission::None, OperationType::Unmap)}; | ||||
|             result.IsError()) { | ||||
|             return result; | ||||
|         } | ||||
| 
 | ||||
|         if (const ResultCode result{Operate(src_addr, num_pages, MemoryPermission::ReadAndWrite, | ||||
|                                             OperationType::ChangePermissions)}; | ||||
|             result.IsError()) { | ||||
|             return result; | ||||
|         } | ||||
|         CASCADE_CODE(Operate(dst_addr, num_pages, MemoryPermission::None, OperationType::Unmap)); | ||||
|         CASCADE_CODE(Operate(src_addr, num_pages, MemoryPermission::ReadAndWrite, | ||||
|                              OperationType::ChangePermissions)); | ||||
| 
 | ||||
|         block_guard.Cancel(); | ||||
|     } | ||||
| @ -665,7 +602,7 @@ ResultCode PageTable::MapPages(VAddr addr, const PageLinkedList& page_linked_lis | ||||
|     VAddr cur_addr{addr}; | ||||
| 
 | ||||
|     for (const auto& node : page_linked_list.Nodes()) { | ||||
|         if (const ResultCode result{ | ||||
|         if (const auto result{ | ||||
|                 Operate(cur_addr, node.GetNumPages(), perm, OperationType::Map, node.GetAddress())}; | ||||
|             result.IsError()) { | ||||
|             const MemoryInfo info{block_manager->FindBlock(cur_addr).GetMemoryInfo()}; | ||||
| @ -698,9 +635,7 @@ ResultCode PageTable::MapPages(VAddr addr, PageLinkedList& page_linked_list, Mem | ||||
|         return ERR_INVALID_ADDRESS_STATE; | ||||
|     } | ||||
| 
 | ||||
|     if (const ResultCode result{MapPages(addr, page_linked_list, perm)}; result.IsError()) { | ||||
|         return result; | ||||
|     } | ||||
|     CASCADE_CODE(MapPages(addr, page_linked_list, perm)); | ||||
| 
 | ||||
|     block_manager->Update(addr, num_pages, state, perm); | ||||
| 
 | ||||
| @ -714,13 +649,10 @@ ResultCode PageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size, Memo | ||||
|     MemoryState prev_state{}; | ||||
|     MemoryPermission prev_perm{}; | ||||
| 
 | ||||
|     if (const ResultCode result{CheckMemoryState( | ||||
|             &prev_state, &prev_perm, nullptr, addr, size, MemoryState::FlagCode, | ||||
|             MemoryState::FlagCode, MemoryPermission::None, MemoryPermission::None, | ||||
|             MemoryAttribute::Mask, MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)}; | ||||
|         result.IsError()) { | ||||
|         return result; | ||||
|     } | ||||
|     CASCADE_CODE(CheckMemoryState( | ||||
|         &prev_state, &prev_perm, nullptr, addr, size, MemoryState::FlagCode, MemoryState::FlagCode, | ||||
|         MemoryPermission::None, MemoryPermission::None, MemoryAttribute::Mask, | ||||
|         MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)); | ||||
| 
 | ||||
|     MemoryState state{prev_state}; | ||||
| 
 | ||||
| @ -745,9 +677,7 @@ ResultCode PageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size, Memo | ||||
|                                       ? OperationType::ChangePermissionsAndRefresh | ||||
|                                       : OperationType::ChangePermissions}; | ||||
| 
 | ||||
|     if (const ResultCode result{Operate(addr, num_pages, perm, operation)}; result.IsError()) { | ||||
|         return result; | ||||
|     } | ||||
|     CASCADE_CODE(Operate(addr, num_pages, perm, operation)); | ||||
| 
 | ||||
|     block_manager->Update(addr, num_pages, state, perm); | ||||
| 
 | ||||
| @ -775,15 +705,12 @@ ResultCode PageTable::ReserveTransferMemory(VAddr addr, std::size_t size, Memory | ||||
|     MemoryState state{}; | ||||
|     MemoryAttribute attribute{}; | ||||
| 
 | ||||
|     if (const ResultCode result{CheckMemoryState( | ||||
|             &state, nullptr, &attribute, addr, size, | ||||
|     CASCADE_CODE(CheckMemoryState(&state, nullptr, &attribute, addr, size, | ||||
|                                   MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, | ||||
|                                   MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, | ||||
|             MemoryPermission::Mask, MemoryPermission::ReadAndWrite, MemoryAttribute::Mask, | ||||
|             MemoryAttribute::None, MemoryAttribute::IpcAndDeviceMapped)}; | ||||
|         result.IsError()) { | ||||
|         return result; | ||||
|     } | ||||
|                                   MemoryPermission::Mask, MemoryPermission::ReadAndWrite, | ||||
|                                   MemoryAttribute::Mask, MemoryAttribute::None, | ||||
|                                   MemoryAttribute::IpcAndDeviceMapped)); | ||||
| 
 | ||||
|     block_manager->Update(addr, size / PageSize, state, perm, attribute | MemoryAttribute::Locked); | ||||
| 
 | ||||
| @ -795,15 +722,12 @@ ResultCode PageTable::ResetTransferMemory(VAddr addr, std::size_t size) { | ||||
| 
 | ||||
|     MemoryState state{}; | ||||
| 
 | ||||
|     if (const ResultCode result{ | ||||
|             CheckMemoryState(&state, nullptr, nullptr, addr, size, | ||||
|     CASCADE_CODE(CheckMemoryState(&state, nullptr, nullptr, addr, size, | ||||
|                                   MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, | ||||
|                                   MemoryState::FlagCanTransfer | MemoryState::FlagReferenceCounted, | ||||
|                              MemoryPermission::None, MemoryPermission::None, MemoryAttribute::Mask, | ||||
|                              MemoryAttribute::Locked, MemoryAttribute::IpcAndDeviceMapped)}; | ||||
|         result.IsError()) { | ||||
|         return result; | ||||
|     } | ||||
|                                   MemoryPermission::None, MemoryPermission::None, | ||||
|                                   MemoryAttribute::Mask, MemoryAttribute::Locked, | ||||
|                                   MemoryAttribute::IpcAndDeviceMapped)); | ||||
| 
 | ||||
|     block_manager->Update(addr, size / PageSize, state, MemoryPermission::ReadAndWrite); | ||||
| 
 | ||||
| @ -818,14 +742,11 @@ ResultCode PageTable::SetMemoryAttribute(VAddr addr, std::size_t size, MemoryAtt | ||||
|     MemoryPermission perm{}; | ||||
|     MemoryAttribute attribute{}; | ||||
| 
 | ||||
|     if (const ResultCode result{CheckMemoryState( | ||||
|             &state, &perm, &attribute, addr, size, MemoryState::FlagCanChangeAttribute, | ||||
|             MemoryState::FlagCanChangeAttribute, MemoryPermission::None, MemoryPermission::None, | ||||
|             MemoryAttribute::LockedAndIpcLocked, MemoryAttribute::None, | ||||
|             MemoryAttribute::DeviceSharedAndUncached)}; | ||||
|         result.IsError()) { | ||||
|         return result; | ||||
|     } | ||||
|     CASCADE_CODE(CheckMemoryState(&state, &perm, &attribute, addr, size, | ||||
|                                   MemoryState::FlagCanChangeAttribute, | ||||
|                                   MemoryState::FlagCanChangeAttribute, MemoryPermission::None, | ||||
|                                   MemoryPermission::None, MemoryAttribute::LockedAndIpcLocked, | ||||
|                                   MemoryAttribute::None, MemoryAttribute::DeviceSharedAndUncached)); | ||||
| 
 | ||||
|     attribute = attribute & ~mask; | ||||
|     attribute = attribute | (mask & value); | ||||
| @ -866,21 +787,15 @@ ResultVal<VAddr> PageTable::SetHeapSize(std::size_t size) { | ||||
|         PageLinkedList page_linked_list; | ||||
|         const std::size_t num_pages{delta / PageSize}; | ||||
| 
 | ||||
|         if (const ResultCode result{ | ||||
|                 system.Kernel().MemoryManager().Allocate(page_linked_list, num_pages, memory_pool)}; | ||||
|             result.IsError()) { | ||||
|             return result; | ||||
|         } | ||||
|         CASCADE_CODE( | ||||
|             system.Kernel().MemoryManager().Allocate(page_linked_list, num_pages, memory_pool)); | ||||
| 
 | ||||
|         if (IsRegionMapped(current_heap_addr, delta)) { | ||||
|             return ERR_INVALID_ADDRESS_STATE; | ||||
|         } | ||||
| 
 | ||||
|         if (const ResultCode result{ | ||||
|                 Operate(current_heap_addr, num_pages, page_linked_list, OperationType::MapGroup)}; | ||||
|             result.IsError()) { | ||||
|             return result; | ||||
|         } | ||||
|         CASCADE_CODE( | ||||
|             Operate(current_heap_addr, num_pages, page_linked_list, OperationType::MapGroup)); | ||||
| 
 | ||||
|         block_manager->Update(current_heap_addr, num_pages, MemoryState::Normal, | ||||
|                               MemoryPermission::ReadAndWrite); | ||||
| @ -912,23 +827,12 @@ ResultVal<VAddr> PageTable::AllocateAndMapMemory(std::size_t needed_num_pages, s | ||||
|     } | ||||
| 
 | ||||
|     if (is_map_only) { | ||||
|         if (const ResultCode result{ | ||||
|                 Operate(addr, needed_num_pages, perm, OperationType::Map, map_addr)}; | ||||
|             result.IsError()) { | ||||
|             return result; | ||||
|         } | ||||
|         CASCADE_CODE(Operate(addr, needed_num_pages, perm, OperationType::Map, map_addr)); | ||||
|     } else { | ||||
|         PageLinkedList page_group; | ||||
|         if (const ResultCode result{system.Kernel().MemoryManager().Allocate( | ||||
|                 page_group, needed_num_pages, memory_pool)}; | ||||
|             result.IsError()) { | ||||
|             return result; | ||||
|         } | ||||
|         if (const ResultCode result{ | ||||
|                 Operate(addr, needed_num_pages, page_group, OperationType::MapGroup)}; | ||||
|             result.IsError()) { | ||||
|             return result; | ||||
|         } | ||||
|         CASCADE_CODE( | ||||
|             system.Kernel().MemoryManager().Allocate(page_group, needed_num_pages, memory_pool)); | ||||
|         CASCADE_CODE(Operate(addr, needed_num_pages, page_group, OperationType::MapGroup)); | ||||
|     } | ||||
| 
 | ||||
|     block_manager->Update(addr, needed_num_pages, state, perm); | ||||
| @ -1196,11 +1100,7 @@ ResultCode PageTable::CheckMemoryState(MemoryState* out_state, MemoryPermission* | ||||
|         } | ||||
| 
 | ||||
|         // Validate against the provided masks
 | ||||
|         if (const ResultCode result{ | ||||
|                 CheckMemoryState(info, state_mask, state, perm_mask, perm, attr_mask, attr)}; | ||||
|             result.IsError()) { | ||||
|             return result; | ||||
|         } | ||||
|         CASCADE_CODE(CheckMemoryState(info, state_mask, state, perm_mask, perm, attr_mask, attr)); | ||||
| 
 | ||||
|         // Break once we're done
 | ||||
|         if (last_addr <= info.GetLastAddress()) { | ||||
|  | ||||
| @ -11,9 +11,9 @@ | ||||
| namespace Kernel::Memory::SystemControl { | ||||
| 
 | ||||
| u64 GenerateRandomU64ForInit() { | ||||
|     std::random_device device; | ||||
|     std::mt19937 gen(device()); | ||||
|     std::uniform_int_distribution<u64> distribution(1, std::numeric_limits<u64>::max()); | ||||
|     static std::random_device device; | ||||
|     static std::mt19937 gen(device()); | ||||
|     static std::uniform_int_distribution<u64> distribution(1, std::numeric_limits<u64>::max()); | ||||
|     return distribution(gen); | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -40,14 +40,14 @@ ResultCode SharedMemory::Map(Process& target_process, VAddr address, std::size_t | ||||
|     const u64 page_count{(size + Memory::PageSize - 1) / Memory::PageSize}; | ||||
| 
 | ||||
|     if (page_list.GetNumPages() != page_count) { | ||||
|         UNIMPLEMENTED(); | ||||
|         UNIMPLEMENTED_MSG("Page count does not match"); | ||||
|     } | ||||
| 
 | ||||
|     Memory::MemoryPermission expected = | ||||
|         &target_process == owner_process ? owner_permission : user_permission; | ||||
| 
 | ||||
|     if (permission != expected) { | ||||
|         UNIMPLEMENTED(); | ||||
|         UNIMPLEMENTED_MSG("Permission does not match"); | ||||
|     } | ||||
| 
 | ||||
|     return target_process.PageTable().MapPages(address, page_list, Memory::MemoryState::Shared, | ||||
|  | ||||
| @ -28,7 +28,7 @@ public: | ||||
|         KernelCore& kernel, Core::DeviceMemory& device_memory, Process* owner_process, | ||||
|         Memory::PageLinkedList&& page_list, Memory::MemoryPermission owner_permission, | ||||
|         Memory::MemoryPermission user_permission, PAddr physical_address, std::size_t size, | ||||
|         std::string name = "Unknown"); | ||||
|         std::string name); | ||||
| 
 | ||||
|     std::string GetTypeName() const override { | ||||
|         return "SharedMemory"; | ||||
|  | ||||
| @ -1196,7 +1196,7 @@ static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_add | ||||
|     } | ||||
| 
 | ||||
|     auto& memory{system.Memory()}; | ||||
|     const Svc::MemoryInfo memory_info{process->PageTable().QueryInfo(address).GetSvcMemoryInfo()}; | ||||
|     const auto memory_info{process->PageTable().QueryInfo(address).GetSvcMemoryInfo()}; | ||||
| 
 | ||||
|     memory.Write64(memory_info_address + 0x00, memory_info.addr); | ||||
|     memory.Write64(memory_info_address + 0x08, memory_info.size); | ||||
|  | ||||
| @ -298,9 +298,7 @@ public: | ||||
|                 continue; | ||||
|             } | ||||
| 
 | ||||
|             if (result.IsError()) { | ||||
|                 return result; | ||||
|             } | ||||
|             CASCADE_CODE(result); | ||||
| 
 | ||||
|             if (ValidateRegionForMap(page_table, addr, size)) { | ||||
|                 return MakeResult<VAddr>(addr); | ||||
| @ -470,16 +468,15 @@ public: | ||||
|         } | ||||
| 
 | ||||
|         // Map memory for the NRO
 | ||||
|         const ResultVal<VAddr> map_result{MapNro(system.CurrentProcess(), nro_address, nro_size, | ||||
|                                                  bss_address, bss_size, nro_size + bss_size)}; | ||||
|         const auto map_result{MapNro(system.CurrentProcess(), nro_address, nro_size, bss_address, | ||||
|                                      bss_size, nro_size + bss_size)}; | ||||
|         if (map_result.Failed()) { | ||||
|             IPC::ResponseBuilder rb{ctx, 2}; | ||||
|             rb.Push(map_result.Code()); | ||||
|         } | ||||
| 
 | ||||
|         // Load the NRO into the mapped memory
 | ||||
|         if (const ResultCode result{ | ||||
|                 LoadNro(system.CurrentProcess(), header, nro_address, *map_result)}; | ||||
|         if (const auto result{LoadNro(system.CurrentProcess(), header, nro_address, *map_result)}; | ||||
|             result.IsError()) { | ||||
|             IPC::ResponseBuilder rb{ctx, 2}; | ||||
|             rb.Push(map_result.Code()); | ||||
| @ -551,7 +548,7 @@ public: | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         const ResultCode result{UnmapNro(iter->second)}; | ||||
|         const auto result{UnmapNro(iter->second)}; | ||||
| 
 | ||||
|         system.InvalidateCpuInstructionCaches(); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 bunnei
						bunnei