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