xref: /haiku/src/system/kernel/arch/arm64/VMSAv8TranslationMap.h (revision 9a6a20d4689307142a7ed26a1437ba47e244e73f)
1 /*
2  * Copyright 2022 Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef VMSA_V8_TRANSLATION_MAP_H
6 #define VMSA_V8_TRANSLATION_MAP_H
7 
8 
9 #include <arch_cpu_defs.h>
10 #include <vm/VMTranslationMap.h>
11 
12 
13 static constexpr uint64_t kPteAddrMask = (((1UL << 36) - 1) << 12);
14 static constexpr uint64_t kPteAttrMask = ~(kPteAddrMask | 0x3);
15 static constexpr uint64_t kPteTLBCompatMask = (kPteAddrMask | (0x3 << 2) | (0x3 << 8));
16 
17 static constexpr uint64_t kPteValidMask = 0x1;
18 static constexpr uint64_t kPteTypeMask = 0x3;
19 static constexpr uint64_t kPteTypeL012Table = 0x3;
20 static constexpr uint64_t kPteTypeL12Block = 0x1;
21 static constexpr uint64_t kPteTypeL3Page = 0x3;
22 
23 static constexpr uint64_t kAttrSWDIRTY = (1UL << 56);
24 static constexpr uint64_t kAttrSWDBM = (1UL << 55);
25 static constexpr uint64_t kAttrUXN = (1UL << 54);
26 static constexpr uint64_t kAttrPXN = (1UL << 53);
27 static constexpr uint64_t kAttrDBM = (1UL << 51);
28 static constexpr uint64_t kAttrNG = (1UL << 11);
29 static constexpr uint64_t kAttrAF = (1UL << 10);
30 static constexpr uint64_t kAttrShareability = (3UL << 8);
31 static constexpr uint64_t kAttrSHInnerShareable = (3UL << 8);
32 static constexpr uint64_t kAttrAPReadOnly = (1UL << 7);
33 static constexpr uint64_t kAttrAPUserAccess = (1UL << 6);
34 static constexpr uint64_t kAttrMemoryAttrIdx = (3UL << 2);
35 
36 static constexpr uint64_t kTLBIMask = ((1UL << 44) - 1);
37 static constexpr uint64_t kASIDMask = 0xFF00000000000000UL;
38 
39 
40 struct VMSAv8TranslationMap : public VMTranslationMap {
41 public:
42 	VMSAv8TranslationMap(
43 		bool kernel, phys_addr_t pageTable, int pageBits, int vaBits, int minBlockLevel);
44 	~VMSAv8TranslationMap();
45 
46 	virtual	bool				Lock();
47 	virtual	void				Unlock();
48 
49 	virtual	addr_t				MappedSize() const;
50 	virtual	size_t				MaxPagesNeededToMap(addr_t start,
51 									addr_t end) const;
52 
53 	virtual	status_t			Map(addr_t virtualAddress,
54 									phys_addr_t physicalAddress,
55 									uint32 attributes, uint32 memoryType,
56 									vm_page_reservation* reservation);
57 	virtual	status_t			Unmap(addr_t start, addr_t end);
58 
59 	virtual	status_t			UnmapPage(VMArea* area, addr_t address,
60 									bool updatePageQueue);
61 	virtual	void				UnmapPages(VMArea* area, addr_t base,
62 									size_t size, bool updatePageQueue);
63 	virtual	void				UnmapArea(VMArea* area,
64 									bool deletingAddressSpace,
65 									bool ignoreTopCachePageFlags);
66 
67 	virtual	status_t			Query(addr_t virtualAddress,
68 									phys_addr_t* _physicalAddress,
69 									uint32* _flags);
70 	virtual	status_t			QueryInterrupt(addr_t virtualAddress,
71 									phys_addr_t* _physicalAddress,
72 									uint32* _flags);
73 
74 	virtual	status_t			Protect(addr_t base, addr_t top,
75 									uint32 attributes, uint32 memoryType);
76 
77 	virtual	status_t			ClearFlags(addr_t virtualAddress,
78 									uint32 flags);
79 
80 	virtual	bool				ClearAccessedAndModified(
81 									VMArea* area, addr_t address,
82 									bool unmapIfUnaccessed,
83 									bool& _modified);
84 
85 	virtual	void				Flush();
86 
87 	enum HWFeature {
88 		// Can HW update Access and Dirty flags, respectively?
89 		HW_ACCESS = 0x1,
90 		HW_DIRTY = 0x2,
91 
92 		// Can we use the CNP bit to indicate that ASIDs are consistent across cores?
93 		HW_COMMON_NOT_PRIVATE = 0x4
94 	};
95 
96 	static uint32_t fHwFeature;
97 	static uint64_t fMair;
98 
99 	static uint64_t GetMemoryAttr(uint32 attributes, uint32 memoryType, bool isKernel);
100 	static int CalcStartLevel(int vaBits, int pageBits);
101 
102 	static void SwitchUserMap(VMSAv8TranslationMap *from, VMSAv8TranslationMap *to);
103 
104 private:
105 	bool fIsKernel;
106 	phys_addr_t fPageTable;
107 	int fPageBits;
108 	int fVaBits;
109 	int fMinBlockLevel;
110 	int fInitialLevel;
111 	int fASID;
112 	int fRefcount;
113 
114 private:
115 	static uint8_t MairIndex(uint8_t type);
116 	bool ValidateVa(addr_t va);
117 	uint64_t* TableFromPa(phys_addr_t pa);
118 	template<typename EntryRemoved>
119 	void FreeTable(phys_addr_t ptPa, uint64_t va, int level, EntryRemoved &&entryRemoved);
120 	phys_addr_t GetOrMakeTable(phys_addr_t ptPa, int level, int index, vm_page_reservation* reservation);
121 	template<typename UpdatePte>
122 	void ProcessRange(phys_addr_t ptPa, int level, addr_t va, size_t size,
123 		vm_page_reservation* reservation, UpdatePte &&updatePte);
124 	bool AttemptPteBreakBeforeMake(uint64_t* ptePtr, uint64_t oldPte, addr_t va);
125 	bool FlushVAIfAccessed(uint64_t pte, addr_t va);
126 };
127 
128 
129 #endif
130