aboutsummaryrefslogtreecommitdiff
path: root/src/core/memory.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/memory.h')
-rw-r--r--src/core/memory.h124
1 files changed, 56 insertions, 68 deletions
diff --git a/src/core/memory.h b/src/core/memory.h
index 7e554f394..4b9c482fe 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -8,10 +8,12 @@
#include <cstddef>
#include <map>
#include <string>
+#include <tuple>
#include <vector>
+#include <boost/icl/interval_map.hpp>
#include <boost/optional.hpp>
#include "common/common_types.h"
-#include "core/mmio.h"
+#include "core/memory_hook.h"
namespace Kernel {
class Process;
@@ -23,12 +25,13 @@ namespace Memory {
* Page size used by the ARM architecture. This is the smallest granularity with which memory can
* be mapped.
*/
-const int PAGE_BITS = 12;
-const u64 PAGE_SIZE = 1 << PAGE_BITS;
-const u64 PAGE_MASK = PAGE_SIZE - 1;
-const size_t PAGE_TABLE_NUM_ENTRIES = 1ULL << (36 - PAGE_BITS);
+constexpr size_t PAGE_BITS = 12;
+constexpr u64 PAGE_SIZE = 1 << PAGE_BITS;
+constexpr u64 PAGE_MASK = PAGE_SIZE - 1;
+constexpr size_t ADDRESS_SPACE_BITS = 36;
+constexpr size_t PAGE_TABLE_NUM_ENTRIES = 1ULL << (ADDRESS_SPACE_BITS - PAGE_BITS);
-enum class PageType {
+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.
@@ -38,22 +41,28 @@ enum class PageType {
RasterizerCachedMemory,
/// Page is mapped to a I/O region. Writing and reading to this page is handled by functions.
Special,
- /// Page is mapped to a I/O region, but also needs to check for rasterizer cache flushing and
- /// invalidation
- RasterizerCachedSpecial,
};
struct SpecialRegion {
- VAddr base;
- u64 size;
- MMIORegionPointer handler;
+ enum class Type {
+ DebugHook,
+ IODevice,
+ } type;
+
+ MemoryHookPointer handler;
+
+ bool operator<(const SpecialRegion& other) const {
+ return std::tie(type, handler) < std::tie(other.type, other.handler);
+ }
+
+ bool operator==(const SpecialRegion& other) const {
+ 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, but instead is optimized for minimal decoding and
- * fetching requirements when accessing. In the usual case of an access to regular memory, it only
- * requires an indexed fetch and a check for NULL.
+ * mimics the way a real CPU page table works.
*/
struct PageTable {
/**
@@ -66,19 +75,13 @@ struct PageTable {
* Contains MMIO handlers that back memory regions whose entries in the `attribute` array is of
* type `Special`.
*/
- std::vector<SpecialRegion> special_regions;
+ boost::icl::interval_map<VAddr, std::set<SpecialRegion>> special_regions;
/**
* Array of fine grained page attributes. If it is set to any value other than `Memory`, then
* the corresponding entry in `pointers` MUST be set to null.
*/
std::array<PageType, PAGE_TABLE_NUM_ENTRIES> attributes;
-
- /**
- * Indicates the number of externally cached resources touching a page that should be
- * flushed before the memory is accessed
- */
- std::array<u8, PAGE_TABLE_NUM_ENTRIES> cached_res_count;
};
/// Physical memory regions as seen from the ARM11
@@ -98,12 +101,6 @@ enum : PAddr {
VRAM_SIZE = 0x00600000, ///< VRAM size (6MB)
VRAM_PADDR_END = VRAM_PADDR + VRAM_SIZE,
- /// New 3DS additional memory. Supposedly faster than regular FCRAM. Part of it can be used by
- /// applications and system modules if mapped via the ExHeader.
- N3DS_EXTRA_RAM_PADDR = 0x1F000000,
- N3DS_EXTRA_RAM_SIZE = 0x00400000, ///< New 3DS additional memory size (4MB)
- N3DS_EXTRA_RAM_PADDR_END = N3DS_EXTRA_RAM_PADDR + N3DS_EXTRA_RAM_SIZE,
-
/// DSP memory
DSP_RAM_PADDR = 0x1FF00000,
DSP_RAM_SIZE = 0x00080000, ///< DSP memory size (512KB)
@@ -119,7 +116,6 @@ enum : PAddr {
FCRAM_SIZE = 0x08000000, ///< FCRAM size on the Old 3DS (128MB)
FCRAM_N3DS_SIZE = 0x10000000, ///< FCRAM size on the New 3DS (256MB)
FCRAM_PADDR_END = FCRAM_PADDR + FCRAM_SIZE,
- FCRAM_N3DS_PADDR_END = FCRAM_PADDR + FCRAM_N3DS_SIZE,
};
/// Virtual user-space memory regions
@@ -129,31 +125,12 @@ enum : VAddr {
PROCESS_IMAGE_MAX_SIZE = 0x08000000,
PROCESS_IMAGE_VADDR_END = PROCESS_IMAGE_VADDR + PROCESS_IMAGE_MAX_SIZE,
- /// Area where IPC buffers are mapped onto.
- IPC_MAPPING_VADDR = 0x04000000,
- IPC_MAPPING_SIZE = 0x04000000,
- IPC_MAPPING_VADDR_END = IPC_MAPPING_VADDR + IPC_MAPPING_SIZE,
-
- /// Application heap (includes stack).
- HEAP_VADDR = 0x108000000,
- HEAP_SIZE = 0xF0000000,
- HEAP_VADDR_END = HEAP_VADDR + HEAP_SIZE,
-
- /// Area where shared memory buffers are mapped onto.
- SHARED_MEMORY_VADDR = 0x10000000,
- SHARED_MEMORY_SIZE = 0x04000000,
- SHARED_MEMORY_VADDR_END = SHARED_MEMORY_VADDR + SHARED_MEMORY_SIZE,
-
/// Maps 1:1 to an offset in FCRAM. Used for HW allocations that need to be linear in physical
/// memory.
LINEAR_HEAP_VADDR = 0x14000000,
LINEAR_HEAP_SIZE = 0x08000000,
LINEAR_HEAP_VADDR_END = LINEAR_HEAP_VADDR + LINEAR_HEAP_SIZE,
- /// Maps 1:1 to New 3DS additional memory
- N3DS_EXTRA_RAM_VADDR = 0x1E800000,
- N3DS_EXTRA_RAM_VADDR_END = N3DS_EXTRA_RAM_VADDR + N3DS_EXTRA_RAM_SIZE,
-
/// Maps 1:1 to the IO register area.
IO_AREA_VADDR = 0x1EC00000,
IO_AREA_VADDR_END = IO_AREA_VADDR + IO_AREA_SIZE,
@@ -176,14 +153,39 @@ enum : VAddr {
SHARED_PAGE_SIZE = 0x00001000,
SHARED_PAGE_VADDR_END = SHARED_PAGE_VADDR + SHARED_PAGE_SIZE,
- /// Area where TLS (Thread-Local Storage) buffers are allocated.
- TLS_AREA_VADDR = 0x228000000,
- TLS_ENTRY_SIZE = 0x200,
-
/// Equivalent to LINEAR_HEAP_VADDR, but expanded to cover the extra memory in the New 3DS.
NEW_LINEAR_HEAP_VADDR = 0x30000000,
NEW_LINEAR_HEAP_SIZE = 0x10000000,
NEW_LINEAR_HEAP_VADDR_END = NEW_LINEAR_HEAP_VADDR + NEW_LINEAR_HEAP_SIZE,
+
+ /// Area where TLS (Thread-Local Storage) buffers are allocated.
+ TLS_AREA_VADDR = NEW_LINEAR_HEAP_VADDR_END,
+ TLS_ENTRY_SIZE = 0x200,
+ TLS_AREA_SIZE = 0x10000000,
+ TLS_ADREA_VADDR_END = TLS_AREA_VADDR + TLS_AREA_SIZE,
+
+ /// Application stack
+ STACK_VADDR = TLS_ADREA_VADDR_END,
+ STACK_SIZE = 0x10000,
+ STACK_VADDR_END = STACK_VADDR + STACK_SIZE,
+
+ /// Application heap
+ /// Size is confirmed to be a static value on fw 3.0.0
+ HEAP_VADDR = 0x108000000,
+ HEAP_SIZE = 0x180000000,
+ HEAP_VADDR_END = HEAP_VADDR + HEAP_SIZE,
+
+ /// New map region
+ /// Size is confirmed to be a static value on fw 3.0.0
+ NEW_MAP_REGION_VADDR = HEAP_VADDR_END,
+ NEW_MAP_REGION_SIZE = 0x80000000,
+ NEW_MAP_REGION_VADDR_END = NEW_MAP_REGION_VADDR + NEW_MAP_REGION_SIZE,
+
+ /// Map region
+ /// Size is confirmed to be a static value on fw 3.0.0
+ MAP_REGION_VADDR = NEW_MAP_REGION_VADDR_END,
+ MAP_REGION_SIZE = 0x1000000000,
+ MAP_REGION_VADDR_END = MAP_REGION_VADDR + MAP_REGION_SIZE,
};
/// Currently active page table
@@ -243,25 +245,11 @@ boost::optional<VAddr> PhysicalToVirtualAddress(PAddr addr);
*/
u8* GetPhysicalPointer(PAddr address);
-/**
- * Adds the supplied value to the rasterizer resource cache counter of each
- * page touching the region.
- */
-void RasterizerMarkRegionCached(PAddr start, u64 size, int count_delta);
-
-/**
- * Flushes any externally cached rasterizer resources touching the given region.
- */
-void RasterizerFlushRegion(PAddr start, u64 size);
-
-/**
- * Flushes and invalidates any externally cached rasterizer resources touching the given region.
- */
-void RasterizerFlushAndInvalidateRegion(PAddr start, u64 size);
-
enum class FlushMode {
/// Write back modified surfaces to RAM
Flush,
+ /// Remove region from the cache
+ Invalidate,
/// Write back modified surfaces to RAM, and also remove them from the cache
FlushAndInvalidate,
};