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 19enum { 20 PAGE_INVALIDATE_CACHE_SIZE = 64 21}; 22 23 24struct 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 101private: 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 116inline phys_addr_t 117RISCV64VMTranslationMap::PageTable() 118{ 119 return fPageTable; 120} 121 122 123inline uint64 124RISCV64VMTranslationMap::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 134CPUSet& 135RISCV64VMTranslationMap::ActiveOnCpus() 136{ 137 return fActiveOnCpus; 138} 139 140 141void 142RISCV64VMTranslationMap::InvalidatePage(addr_t address) 143{ 144 if (fInvalidPagesCount < PAGE_INVALIDATE_CACHE_SIZE) 145 fInvalidPages[fInvalidPagesCount] = address; 146 147 fInvalidPagesCount++; 148} 149 150 151struct 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