2022-04-23 09:59:50 +01:00
|
|
|
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2021-06-05 10:23:25 +01:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <memory>
|
2023-11-17 19:43:15 +00:00
|
|
|
#include "common/common_funcs.h"
|
2021-06-05 10:23:25 +01:00
|
|
|
#include "common/common_types.h"
|
2021-06-11 10:47:23 +01:00
|
|
|
#include "common/virtual_buffer.h"
|
2021-06-05 10:23:25 +01:00
|
|
|
|
|
|
|
namespace Common {
|
|
|
|
|
2023-11-17 19:43:15 +00:00
|
|
|
enum class MemoryPermission : u32 {
|
|
|
|
Read = 1 << 0,
|
|
|
|
Write = 1 << 1,
|
|
|
|
ReadWrite = Read | Write,
|
|
|
|
Execute = 1 << 2,
|
|
|
|
};
|
|
|
|
DECLARE_ENUM_FLAG_OPERATORS(MemoryPermission)
|
|
|
|
|
2021-06-05 10:23:25 +01:00
|
|
|
/**
|
|
|
|
* A low level linear memory buffer, which supports multiple mappings
|
|
|
|
* Its purpose is to rebuild a given sparse memory layout, including mirrors.
|
|
|
|
*/
|
|
|
|
class HostMemory {
|
|
|
|
public:
|
2021-06-05 10:47:08 +01:00
|
|
|
explicit HostMemory(size_t backing_size_, size_t virtual_size_);
|
2021-06-05 10:23:25 +01:00
|
|
|
~HostMemory();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Copy constructors. They shall return a copy of the buffer without the mappings.
|
|
|
|
* TODO: Implement them with COW if needed.
|
|
|
|
*/
|
|
|
|
HostMemory(const HostMemory& other) = delete;
|
|
|
|
HostMemory& operator=(const HostMemory& other) = delete;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Move constructors. They will move the buffer and the mappings to the new object.
|
|
|
|
*/
|
|
|
|
HostMemory(HostMemory&& other) noexcept;
|
|
|
|
HostMemory& operator=(HostMemory&& other) noexcept;
|
|
|
|
|
2023-11-17 19:43:15 +00:00
|
|
|
void Map(size_t virtual_offset, size_t host_offset, size_t length, MemoryPermission perms);
|
2021-06-05 10:23:25 +01:00
|
|
|
|
|
|
|
void Unmap(size_t virtual_offset, size_t length);
|
|
|
|
|
2023-11-17 19:43:15 +00:00
|
|
|
void Protect(size_t virtual_offset, size_t length, bool read, bool write, bool execute = false);
|
2021-06-05 10:23:25 +01:00
|
|
|
|
2023-11-17 18:57:39 +00:00
|
|
|
void EnableDirectMappedAddress();
|
|
|
|
|
2023-12-13 20:32:25 +00:00
|
|
|
void ClearBackingRegion(size_t physical_offset, size_t length, u32 fill_value);
|
|
|
|
|
2021-06-05 10:23:25 +01:00
|
|
|
[[nodiscard]] u8* BackingBasePointer() noexcept {
|
|
|
|
return backing_base;
|
|
|
|
}
|
|
|
|
[[nodiscard]] const u8* BackingBasePointer() const noexcept {
|
|
|
|
return backing_base;
|
|
|
|
}
|
|
|
|
|
|
|
|
[[nodiscard]] u8* VirtualBasePointer() noexcept {
|
|
|
|
return virtual_base;
|
|
|
|
}
|
|
|
|
[[nodiscard]] const u8* VirtualBasePointer() const noexcept {
|
|
|
|
return virtual_base;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2021-06-05 10:47:08 +01:00
|
|
|
size_t backing_size{};
|
|
|
|
size_t virtual_size{};
|
|
|
|
|
2021-06-05 10:23:25 +01:00
|
|
|
// Low level handler for the platform dependent memory routines
|
|
|
|
class Impl;
|
|
|
|
std::unique_ptr<Impl> impl;
|
|
|
|
u8* backing_base{};
|
|
|
|
u8* virtual_base{};
|
2021-06-05 10:47:08 +01:00
|
|
|
size_t virtual_base_offset{};
|
2021-06-11 10:47:23 +01:00
|
|
|
|
|
|
|
// Fallback if fastmem is not supported on this platform
|
|
|
|
std::unique_ptr<Common::VirtualBuffer<u8>> fallback_buffer;
|
2021-06-05 10:23:25 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace Common
|