2019-03-02 20:20:28 +00:00
|
|
|
// Copyright 2019 yuzu Emulator Project
|
|
|
|
// Licensed under GPLv2 or any later version
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2020-11-18 00:58:41 +00:00
|
|
|
#include <tuple>
|
|
|
|
|
2019-03-02 20:20:28 +00:00
|
|
|
#include "common/common_types.h"
|
|
|
|
#include "common/memory_hook.h"
|
2020-04-09 03:49:51 +01:00
|
|
|
#include "common/virtual_buffer.h"
|
2019-03-02 20:20:28 +00:00
|
|
|
|
|
|
|
namespace Common {
|
|
|
|
|
|
|
|
enum class PageType : u8 {
|
|
|
|
/// Page is unmapped and should cause an access error.
|
|
|
|
Unmapped,
|
|
|
|
/// Page is mapped to regular memory. This is the only type you can get pointers to.
|
|
|
|
Memory,
|
|
|
|
/// Page is mapped to regular memory, but also needs to check for rasterizer cache flushing and
|
|
|
|
/// invalidation
|
|
|
|
RasterizerCachedMemory,
|
|
|
|
/// Page is mapped to a I/O region. Writing and reading to this page is handled by functions.
|
|
|
|
Special,
|
2019-03-04 04:54:16 +00:00
|
|
|
/// Page is allocated for use.
|
|
|
|
Allocated,
|
2019-03-02 20:20:28 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct SpecialRegion {
|
|
|
|
enum class Type {
|
|
|
|
DebugHook,
|
|
|
|
IODevice,
|
|
|
|
} type;
|
|
|
|
|
|
|
|
MemoryHookPointer handler;
|
|
|
|
|
2020-08-14 14:38:45 +01:00
|
|
|
[[nodiscard]] bool operator<(const SpecialRegion& other) const {
|
2019-03-02 20:20:28 +00:00
|
|
|
return std::tie(type, handler) < std::tie(other.type, other.handler);
|
|
|
|
}
|
|
|
|
|
2020-08-14 14:38:45 +01:00
|
|
|
[[nodiscard]] bool operator==(const SpecialRegion& other) const {
|
2019-03-02 20:20:28 +00:00
|
|
|
return std::tie(type, handler) == std::tie(other.type, other.handler);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A (reasonably) fast way of allowing switchable and remappable process address spaces. It loosely
|
|
|
|
* mimics the way a real CPU page table works.
|
|
|
|
*/
|
|
|
|
struct PageTable {
|
2020-04-09 03:49:51 +01:00
|
|
|
PageTable();
|
2020-11-18 00:58:41 +00:00
|
|
|
~PageTable() noexcept;
|
|
|
|
|
|
|
|
PageTable(const PageTable&) = delete;
|
|
|
|
PageTable& operator=(const PageTable&) = delete;
|
|
|
|
|
|
|
|
PageTable(PageTable&&) noexcept = default;
|
|
|
|
PageTable& operator=(PageTable&&) noexcept = default;
|
2019-03-02 20:20:28 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Resizes the page table to be able to accomodate enough pages within
|
|
|
|
* a given address space.
|
|
|
|
*
|
|
|
|
* @param address_space_width_in_bits The address size width in bits.
|
2020-11-18 00:45:17 +00:00
|
|
|
* @param page_size_in_bits The page size in bits.
|
|
|
|
* @param has_attribute Whether or not this page has any backing attributes.
|
2019-03-02 20:20:28 +00:00
|
|
|
*/
|
2020-04-09 03:49:51 +01:00
|
|
|
void Resize(std::size_t address_space_width_in_bits, std::size_t page_size_in_bits,
|
|
|
|
bool has_attribute);
|
2019-03-02 20:20:28 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Vector of memory pointers backing each page. An entry can only be non-null if the
|
|
|
|
* corresponding entry in the `attributes` vector is of type `Memory`.
|
|
|
|
*/
|
2020-04-09 03:49:51 +01:00
|
|
|
VirtualBuffer<u8*> pointers;
|
2020-03-13 20:33:47 +00:00
|
|
|
|
2020-04-09 03:49:51 +01:00
|
|
|
VirtualBuffer<u64> backing_addr;
|
2020-03-13 20:33:47 +00:00
|
|
|
|
2020-04-09 03:49:51 +01:00
|
|
|
VirtualBuffer<PageType> attributes;
|
2020-03-13 20:33:47 +00:00
|
|
|
};
|
|
|
|
|
2019-03-02 20:20:28 +00:00
|
|
|
} // namespace Common
|