xref: /haiku/src/system/kernel/arch/riscv64/RISCV64VMTranslationMap.h (revision 688acf41a377f25d4048dc6092edb86ac9179677)
1  /*
2   * Copyright 2020-2021, Haiku, Inc. All rights reserved.
3   * Distributed under the terms of the MIT License.
4   *
5   * Authors:
6   *   X512 <danger_mail@list.ru>
7   */
8  #ifndef _RISCV64VMTRANSLATIONMAP_H_
9  #define _RISCV64VMTRANSLATIONMAP_H_
10  
11  
12  #include <vm/VMTranslationMap.h>
13  #include <arch_cpu_defs.h>
14  #include <kernel/smp.h>
15  
16  
17  enum {
18  	PAGE_INVALIDATE_CACHE_SIZE = 64
19  };
20  
21  
22  struct RISCV64VMTranslationMap: public VMTranslationMap {
23  								RISCV64VMTranslationMap(bool kernel,
24  									phys_addr_t pageTable = 0);
25  	virtual						~RISCV64VMTranslationMap();
26  
27  	virtual	bool				Lock();
28  	virtual	void				Unlock();
29  
30  	virtual	addr_t				MappedSize() const;
31  	virtual	size_t				MaxPagesNeededToMap(addr_t start,
32  									addr_t end) const;
33  
34  	virtual	status_t			Map(addr_t virtualAddress,
35  									phys_addr_t physicalAddress,
36  									uint32 attributes, uint32 memoryType,
37  									vm_page_reservation* reservation);
38  	virtual	status_t			Unmap(addr_t start, addr_t end);
39  
40  	virtual	status_t			DebugMarkRangePresent(addr_t start, addr_t end,
41  									bool markPresent);
42  
43  	virtual	status_t			UnmapPage(VMArea* area, addr_t address,
44  									bool updatePageQueue);
45  	virtual	void				UnmapPages(VMArea* area, addr_t base,
46  									size_t size, bool updatePageQueue);
47  	virtual	void				UnmapArea(VMArea* area,
48  									bool deletingAddressSpace,
49  									bool ignoreTopCachePageFlags);
50  
51  	virtual	status_t			Query(addr_t virtualAddress,
52  									phys_addr_t* _physicalAddress,
53  									uint32* _flags);
54  	virtual	status_t			QueryInterrupt(addr_t virtualAddress,
55  									phys_addr_t* _physicalAddress,
56  									uint32* _flags);
57  
58  	virtual	status_t			Protect(addr_t base, addr_t top,
59  									uint32 attributes, uint32 memoryType);
60  			status_t			ProtectPage(VMArea* area, addr_t address,
61  									uint32 attributes);
62  			status_t			ProtectArea(VMArea* area,
63  									uint32 attributes);
64  
65  			status_t			SetFlags(addr_t virtualAddress,
66  									uint32 flags);
67  
68  	virtual	status_t			ClearFlags(addr_t virtualAddress,
69  									uint32 flags);
70  
71  	virtual	bool				ClearAccessedAndModified(
72  									VMArea* area, addr_t address,
73  									bool unmapIfUnaccessed,
74  									bool& _modified);
75  
76  	virtual	void				Flush();
77  
78  	virtual	void				DebugPrintMappingInfo(addr_t virtualAddress);
79  	virtual	bool				DebugGetReverseMappingInfo(
80  									phys_addr_t physicalAddress,
81  									ReverseMappingInfoCallback& callback);
82  
83  	inline	phys_addr_t			PageTable();
84  	inline	uint64				Satp();
85  
86  			status_t			MemcpyToMap(addr_t to, const char *from,
87  									size_t size);
88  			status_t			MemcpyFromMap(char *to, addr_t from,
89  									size_t size);
90  			status_t			MemsetToMap(addr_t to, char c, size_t count);
91  			ssize_t				StrlcpyFromMap(char *to, addr_t from,
92  									size_t size);
93  			ssize_t				StrlcpyToMap(addr_t to, const char *from,
94  									size_t size);
95  
96  	inline	CPUSet&				ActiveOnCpus();
97  	inline	void				InvalidatePage(addr_t address);
98  
99  private:
100  			Pte*				LookupPte(addr_t virtAdr, bool alloc,
101  									vm_page_reservation* reservation);
102  			phys_addr_t			LookupAddr(addr_t virtAdr);
103  
104  			bool				fIsKernel;
105  			phys_addr_t			fPageTable;
106  			uint64				fPageTableSize; // in page units
107  			CPUSet				fActiveOnCpus;
108  			int					fInvalidPagesCount;
109  			addr_t				fInvalidPages[PAGE_INVALIDATE_CACHE_SIZE];
110  			bool				fInvalidCode;
111  };
112  
113  
114  inline phys_addr_t
115  RISCV64VMTranslationMap::PageTable()
116  {
117  	return fPageTable;
118  }
119  
120  
121  inline uint64
122  RISCV64VMTranslationMap::Satp()
123  {
124  	SatpReg satp;
125  	satp.ppn = fPageTable / B_PAGE_SIZE;
126  	satp.asid = 0;
127  	satp.mode = satpModeSv39;
128  	return satp.val;
129  }
130  
131  
132  CPUSet&
133  RISCV64VMTranslationMap::ActiveOnCpus()
134  {
135  	return fActiveOnCpus;
136  }
137  
138  
139  void
140  RISCV64VMTranslationMap::InvalidatePage(addr_t address)
141  {
142  	if (fInvalidPagesCount < PAGE_INVALIDATE_CACHE_SIZE)
143  		fInvalidPages[fInvalidPagesCount] = address;
144  
145  	fInvalidPagesCount++;
146  }
147  
148  
149  struct RISCV64VMPhysicalPageMapper: public VMPhysicalPageMapper {
150  								RISCV64VMPhysicalPageMapper();
151  	virtual						~RISCV64VMPhysicalPageMapper();
152  
153  	virtual	status_t			GetPage(phys_addr_t physicalAddress,
154  									addr_t* _virtualAddress,
155  									void** _handle);
156  	virtual	status_t			PutPage(addr_t virtualAddress,
157  									void* handle);
158  
159  	virtual	status_t			GetPageCurrentCPU(
160  									phys_addr_t physicalAddress,
161  									addr_t* _virtualAddress,
162  									void** _handle);
163  	virtual	status_t			PutPageCurrentCPU(addr_t virtualAddress,
164  									void* _handle);
165  
166  	virtual	status_t			GetPageDebug(phys_addr_t physicalAddress,
167  									addr_t* _virtualAddress,
168  									void** _handle);
169  	virtual	status_t			PutPageDebug(addr_t virtualAddress,
170  									void* handle);
171  
172  	virtual	status_t			MemsetPhysical(phys_addr_t address, int value,
173  									phys_size_t length);
174  	virtual	status_t			MemcpyFromPhysical(void* to, phys_addr_t from,
175  									size_t length, bool user);
176  	virtual	status_t			MemcpyToPhysical(phys_addr_t to,
177  									const void* from, size_t length,
178  									bool user);
179  	virtual	void				MemcpyPhysicalPage(phys_addr_t to,
180  									phys_addr_t from);
181  };
182  
183  
184  #endif	// _RISCV64VMTRANSLATIONMAP_H_
185