mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	kernel: transfer_memory: Refactor for new VMM.
This commit is contained in:
		
							parent
							
								
									c53454ff46
								
							
						
					
					
						commit
						3fcc4cab4f
					
				@ -2,10 +2,9 @@
 | 
				
			|||||||
// Licensed under GPLv2 or any later version
 | 
					// Licensed under GPLv2 or any later version
 | 
				
			||||||
// Refer to the license.txt file included.
 | 
					// Refer to the license.txt file included.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "core/hle/kernel/errors.h"
 | 
					 | 
				
			||||||
#include "core/hle/kernel/kernel.h"
 | 
					#include "core/hle/kernel/kernel.h"
 | 
				
			||||||
 | 
					#include "core/hle/kernel/memory/page_table.h"
 | 
				
			||||||
#include "core/hle/kernel/process.h"
 | 
					#include "core/hle/kernel/process.h"
 | 
				
			||||||
#include "core/hle/kernel/shared_memory.h"
 | 
					 | 
				
			||||||
#include "core/hle/kernel/transfer_memory.h"
 | 
					#include "core/hle/kernel/transfer_memory.h"
 | 
				
			||||||
#include "core/hle/result.h"
 | 
					#include "core/hle/result.h"
 | 
				
			||||||
#include "core/memory.h"
 | 
					#include "core/memory.h"
 | 
				
			||||||
@ -22,13 +21,13 @@ TransferMemory::~TransferMemory() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
std::shared_ptr<TransferMemory> TransferMemory::Create(KernelCore& kernel,
 | 
					std::shared_ptr<TransferMemory> TransferMemory::Create(KernelCore& kernel,
 | 
				
			||||||
                                                       Core::Memory::Memory& memory,
 | 
					                                                       Core::Memory::Memory& memory,
 | 
				
			||||||
                                                       VAddr base_address, u64 size,
 | 
					                                                       VAddr base_address, std::size_t size,
 | 
				
			||||||
                                                       MemoryPermission permissions) {
 | 
					                                                       Memory::MemoryPermission permissions) {
 | 
				
			||||||
    std::shared_ptr<TransferMemory> transfer_memory{
 | 
					    std::shared_ptr<TransferMemory> transfer_memory{
 | 
				
			||||||
        std::make_shared<TransferMemory>(kernel, memory)};
 | 
					        std::make_shared<TransferMemory>(kernel, memory)};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    transfer_memory->base_address = base_address;
 | 
					    transfer_memory->base_address = base_address;
 | 
				
			||||||
    transfer_memory->memory_size = size;
 | 
					    transfer_memory->size = size;
 | 
				
			||||||
    transfer_memory->owner_permissions = permissions;
 | 
					    transfer_memory->owner_permissions = permissions;
 | 
				
			||||||
    transfer_memory->owner_process = kernel.CurrentProcess();
 | 
					    transfer_memory->owner_process = kernel.CurrentProcess();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -39,98 +38,12 @@ const u8* TransferMemory::GetPointer() const {
 | 
				
			|||||||
    return memory.GetPointer(base_address);
 | 
					    return memory.GetPointer(base_address);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
u64 TransferMemory::GetSize() const {
 | 
					 | 
				
			||||||
    return memory_size;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ResultCode TransferMemory::MapMemory(VAddr address, u64 size, MemoryPermission permissions) {
 | 
					 | 
				
			||||||
    if (memory_size != size) {
 | 
					 | 
				
			||||||
        return ERR_INVALID_SIZE;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (owner_permissions != permissions) {
 | 
					 | 
				
			||||||
        return ERR_INVALID_STATE;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (is_mapped) {
 | 
					 | 
				
			||||||
        return ERR_INVALID_STATE;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    backing_block = std::make_shared<PhysicalMemory>(size);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const auto map_state = owner_permissions == MemoryPermission::None
 | 
					 | 
				
			||||||
                               ? MemoryState::TransferMemoryIsolated
 | 
					 | 
				
			||||||
                               : MemoryState::TransferMemory;
 | 
					 | 
				
			||||||
    auto& vm_manager = owner_process->VMManager();
 | 
					 | 
				
			||||||
    const auto map_result = vm_manager.MapMemoryBlock(address, backing_block, 0, size, map_state);
 | 
					 | 
				
			||||||
    if (map_result.Failed()) {
 | 
					 | 
				
			||||||
        return map_result.Code();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    is_mapped = true;
 | 
					 | 
				
			||||||
    return RESULT_SUCCESS;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ResultCode TransferMemory::Reserve() {
 | 
					ResultCode TransferMemory::Reserve() {
 | 
				
			||||||
    auto& vm_manager{owner_process->VMManager()};
 | 
					    return owner_process->PageTable().ReserveTransferMemory(base_address, size, owner_permissions);
 | 
				
			||||||
    const auto check_range_result{vm_manager.CheckRangeState(
 | 
					 | 
				
			||||||
        base_address, memory_size, MemoryState::FlagTransfer | MemoryState::FlagMemoryPoolAllocated,
 | 
					 | 
				
			||||||
        MemoryState::FlagTransfer | MemoryState::FlagMemoryPoolAllocated, VMAPermission::All,
 | 
					 | 
				
			||||||
        VMAPermission::ReadWrite, MemoryAttribute::Mask, MemoryAttribute::None,
 | 
					 | 
				
			||||||
        MemoryAttribute::IpcAndDeviceMapped)};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (check_range_result.Failed()) {
 | 
					 | 
				
			||||||
        return check_range_result.Code();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    auto [state_, permissions_, attribute] = *check_range_result;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (const auto result{vm_manager.ReprotectRange(
 | 
					 | 
				
			||||||
            base_address, memory_size, SharedMemory::ConvertPermissions(owner_permissions))};
 | 
					 | 
				
			||||||
        result.IsError()) {
 | 
					 | 
				
			||||||
        return result;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return vm_manager.SetMemoryAttribute(base_address, memory_size, MemoryAttribute::Mask,
 | 
					 | 
				
			||||||
                                         attribute | MemoryAttribute::Locked);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ResultCode TransferMemory::Reset() {
 | 
					ResultCode TransferMemory::Reset() {
 | 
				
			||||||
    auto& vm_manager{owner_process->VMManager()};
 | 
					    return owner_process->PageTable().ResetTransferMemory(base_address, size);
 | 
				
			||||||
    if (const auto result{vm_manager.CheckRangeState(
 | 
					 | 
				
			||||||
            base_address, memory_size,
 | 
					 | 
				
			||||||
            MemoryState::FlagTransfer | MemoryState::FlagMemoryPoolAllocated,
 | 
					 | 
				
			||||||
            MemoryState::FlagTransfer | MemoryState::FlagMemoryPoolAllocated, VMAPermission::None,
 | 
					 | 
				
			||||||
            VMAPermission::None, MemoryAttribute::Mask, MemoryAttribute::Locked,
 | 
					 | 
				
			||||||
            MemoryAttribute::IpcAndDeviceMapped)};
 | 
					 | 
				
			||||||
        result.Failed()) {
 | 
					 | 
				
			||||||
        return result.Code();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (const auto result{
 | 
					 | 
				
			||||||
            vm_manager.ReprotectRange(base_address, memory_size, VMAPermission::ReadWrite)};
 | 
					 | 
				
			||||||
        result.IsError()) {
 | 
					 | 
				
			||||||
        return result;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return vm_manager.SetMemoryAttribute(base_address, memory_size, MemoryAttribute::Mask,
 | 
					 | 
				
			||||||
                                         MemoryAttribute::None);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ResultCode TransferMemory::UnmapMemory(VAddr address, u64 size) {
 | 
					 | 
				
			||||||
    if (memory_size != size) {
 | 
					 | 
				
			||||||
        return ERR_INVALID_SIZE;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    auto& vm_manager = owner_process->VMManager();
 | 
					 | 
				
			||||||
    const auto result = vm_manager.UnmapRange(address, size);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (result.IsError()) {
 | 
					 | 
				
			||||||
        return result;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    is_mapped = false;
 | 
					 | 
				
			||||||
    return RESULT_SUCCESS;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Kernel
 | 
					} // namespace Kernel
 | 
				
			||||||
 | 
				
			|||||||
@ -6,6 +6,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <memory>
 | 
					#include <memory>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "core/hle/kernel/memory/memory_block.h"
 | 
				
			||||||
#include "core/hle/kernel/object.h"
 | 
					#include "core/hle/kernel/object.h"
 | 
				
			||||||
#include "core/hle/kernel/physical_memory.h"
 | 
					#include "core/hle/kernel/physical_memory.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -20,8 +21,6 @@ namespace Kernel {
 | 
				
			|||||||
class KernelCore;
 | 
					class KernelCore;
 | 
				
			||||||
class Process;
 | 
					class Process;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum class MemoryPermission : u32;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Defines the interface for transfer memory objects.
 | 
					/// Defines the interface for transfer memory objects.
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// Transfer memory is typically used for the purpose of
 | 
					/// Transfer memory is typically used for the purpose of
 | 
				
			||||||
@ -36,8 +35,8 @@ public:
 | 
				
			|||||||
    static constexpr HandleType HANDLE_TYPE = HandleType::TransferMemory;
 | 
					    static constexpr HandleType HANDLE_TYPE = HandleType::TransferMemory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static std::shared_ptr<TransferMemory> Create(KernelCore& kernel, Core::Memory::Memory& memory,
 | 
					    static std::shared_ptr<TransferMemory> Create(KernelCore& kernel, Core::Memory::Memory& memory,
 | 
				
			||||||
                                                  VAddr base_address, u64 size,
 | 
					                                                  VAddr base_address, std::size_t size,
 | 
				
			||||||
                                                  MemoryPermission permissions);
 | 
					                                                  Memory::MemoryPermission permissions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    TransferMemory(const TransferMemory&) = delete;
 | 
					    TransferMemory(const TransferMemory&) = delete;
 | 
				
			||||||
    TransferMemory& operator=(const TransferMemory&) = delete;
 | 
					    TransferMemory& operator=(const TransferMemory&) = delete;
 | 
				
			||||||
@ -61,29 +60,9 @@ public:
 | 
				
			|||||||
    const u8* GetPointer() const;
 | 
					    const u8* GetPointer() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Gets the size of the memory backing this instance in bytes.
 | 
					    /// Gets the size of the memory backing this instance in bytes.
 | 
				
			||||||
    u64 GetSize() const;
 | 
					    constexpr std::size_t GetSize() const {
 | 
				
			||||||
 | 
					        return size;
 | 
				
			||||||
    /// Attempts to map transfer memory with the given range and memory permissions.
 | 
					    }
 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// @param address     The base address to being mapping memory at.
 | 
					 | 
				
			||||||
    /// @param size        The size of the memory to map, in bytes.
 | 
					 | 
				
			||||||
    /// @param permissions The memory permissions to check against when mapping memory.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// @pre The given address, size, and memory permissions must all match
 | 
					 | 
				
			||||||
    ///      the same values that were given when creating the transfer memory
 | 
					 | 
				
			||||||
    ///      instance.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    ResultCode MapMemory(VAddr address, u64 size, MemoryPermission permissions);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Unmaps the transfer memory with the given range
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// @param address The base address to begin unmapping memory at.
 | 
					 | 
				
			||||||
    /// @param size    The size of the memory to unmap, in bytes.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    /// @pre The given address and size must be the same as the ones used
 | 
					 | 
				
			||||||
    ///      to create the transfer memory instance.
 | 
					 | 
				
			||||||
    ///
 | 
					 | 
				
			||||||
    ResultCode UnmapMemory(VAddr address, u64 size);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Reserves the region to be used for the transfer memory, called after the transfer memory is
 | 
					    /// Reserves the region to be used for the transfer memory, called after the transfer memory is
 | 
				
			||||||
    /// created.
 | 
					    /// created.
 | 
				
			||||||
@ -94,23 +73,17 @@ public:
 | 
				
			|||||||
    ResultCode Reset();
 | 
					    ResultCode Reset();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    /// Memory block backing this instance.
 | 
					 | 
				
			||||||
    std::shared_ptr<PhysicalMemory> backing_block;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// The base address for the memory managed by this instance.
 | 
					    /// The base address for the memory managed by this instance.
 | 
				
			||||||
    VAddr base_address = 0;
 | 
					    VAddr base_address{};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Size of the memory, in bytes, that this instance manages.
 | 
					    /// Size of the memory, in bytes, that this instance manages.
 | 
				
			||||||
    u64 memory_size = 0;
 | 
					    std::size_t size{};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// The memory permissions that are applied to this instance.
 | 
					    /// The memory permissions that are applied to this instance.
 | 
				
			||||||
    MemoryPermission owner_permissions{};
 | 
					    Memory::MemoryPermission owner_permissions{};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// The process that this transfer memory instance was created under.
 | 
					    /// The process that this transfer memory instance was created under.
 | 
				
			||||||
    Process* owner_process = nullptr;
 | 
					    Process* owner_process{};
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Whether or not this transfer memory instance has mapped memory.
 | 
					 | 
				
			||||||
    bool is_mapped = false;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Core::Memory::Memory& memory;
 | 
					    Core::Memory::Memory& memory;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user