mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-05-20 18:34:58 +00:00
core: Implement new memory manager (#133)
* core: Implement new memory manager * ci: Attempt to fix linux build * code: Fix a few build errors
This commit is contained in:
parent
67f6d8b2e4
commit
55855b4195
22 changed files with 792 additions and 239 deletions
128
src/core/memory.h
Normal file
128
src/core/memory.h
Normal file
|
@ -0,0 +1,128 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <boost/icl/split_interval_map.hpp>
|
||||
#include "common/enum.h"
|
||||
#include "common/singleton.h"
|
||||
#include "common/types.h"
|
||||
#include "core/address_space.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
enum class MemoryProt : u32 {
|
||||
NoAccess = 0,
|
||||
CpuRead = 1,
|
||||
CpuReadWrite = 2,
|
||||
GpuRead = 16,
|
||||
GpuWrite = 32,
|
||||
GpuReadWrite = 38,
|
||||
};
|
||||
|
||||
enum class MemoryMapFlags : u32 {
|
||||
NoFlags = 0,
|
||||
Fixed = 0x10,
|
||||
NoOverwrite = 0x0080,
|
||||
NoCoalesce = 0x400000,
|
||||
};
|
||||
DECLARE_ENUM_FLAG_OPERATORS(MemoryMapFlags)
|
||||
|
||||
enum class VMAType : u32 {
|
||||
Free = 0,
|
||||
Reserved = 1,
|
||||
Direct = 2,
|
||||
Flexible = 3,
|
||||
Pooled = 4,
|
||||
Stack = 5,
|
||||
};
|
||||
|
||||
struct DirectMemoryArea {
|
||||
PAddr base = 0;
|
||||
size_t size = 0;
|
||||
int memory_type = 0;
|
||||
};
|
||||
|
||||
struct VirtualMemoryArea {
|
||||
VAddr base = 0;
|
||||
size_t size = 0;
|
||||
PAddr phys_base = 0;
|
||||
VMAType type = VMAType::Free;
|
||||
MemoryProt prot = MemoryProt::NoAccess;
|
||||
bool disallow_merge = false;
|
||||
std::string name = "";
|
||||
|
||||
bool CanMergeWith(const VirtualMemoryArea& next) const {
|
||||
if (disallow_merge || next.disallow_merge) {
|
||||
return false;
|
||||
}
|
||||
if (base + size != next.base) {
|
||||
return false;
|
||||
}
|
||||
if (type == VMAType::Direct && phys_base + size != next.phys_base) {
|
||||
return false;
|
||||
}
|
||||
if (prot != next.prot || type != next.type) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
constexpr VAddr SYSTEM_RESERVED = 0x800000000u;
|
||||
constexpr VAddr CODE_BASE_OFFSET = 0x100000000u;
|
||||
constexpr VAddr SYSTEM_MANAGED_MIN = 0x0000040000u;
|
||||
constexpr VAddr SYSTEM_MANAGED_MAX = 0x07FFFFBFFFu;
|
||||
constexpr VAddr USER_MIN = 0x1000000000u;
|
||||
constexpr VAddr USER_MAX = 0xFBFFFFFFFFu;
|
||||
|
||||
class MemoryManager {
|
||||
using VMAMap = std::map<VAddr, VirtualMemoryArea>;
|
||||
using VMAHandle = VMAMap::iterator;
|
||||
|
||||
public:
|
||||
explicit MemoryManager();
|
||||
~MemoryManager();
|
||||
|
||||
PAddr Allocate(PAddr search_start, PAddr search_end, size_t size, u64 alignment,
|
||||
int memory_type);
|
||||
|
||||
void Free(PAddr phys_addr, size_t size);
|
||||
|
||||
int MapMemory(void** out_addr, VAddr virtual_addr, size_t size, MemoryProt prot,
|
||||
MemoryMapFlags flags, VMAType type, std::string_view name = "",
|
||||
PAddr phys_addr = 0, u64 alignment = 0);
|
||||
|
||||
void UnmapMemory(VAddr virtual_addr, size_t size);
|
||||
|
||||
private:
|
||||
bool HasOverlap(VAddr addr, size_t size) const {
|
||||
return vma_map.find(addr) != vma_map.end();
|
||||
}
|
||||
|
||||
VMAHandle FindVMA(VAddr target) {
|
||||
// Return first the VMA with base >= target.
|
||||
const auto it = vma_map.lower_bound(target);
|
||||
if (it->first == target) {
|
||||
return it;
|
||||
}
|
||||
return std::prev(it);
|
||||
}
|
||||
|
||||
VirtualMemoryArea& AddMapping(VAddr virtual_addr, size_t size);
|
||||
|
||||
VMAHandle Split(VMAHandle vma_handle, u32 offset_in_vma);
|
||||
|
||||
VMAHandle MergeAdjacent(VMAHandle iter);
|
||||
|
||||
private:
|
||||
AddressSpace impl;
|
||||
std::vector<DirectMemoryArea> allocations;
|
||||
VMAMap vma_map;
|
||||
};
|
||||
|
||||
using Memory = Common::Singleton<MemoryManager>;
|
||||
|
||||
} // namespace Core
|
Loading…
Add table
Add a link
Reference in a new issue