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