mirror of
https://github.com/vortexgpgpu/vortex.git
synced 2025-04-23 21:39:10 -04:00
comments fixed
This commit is contained in:
parent
5821f2a904
commit
a29caf9451
9 changed files with 158 additions and 54 deletions
|
@ -120,37 +120,27 @@ MemoryUnit::MemoryUnit(uint64_t pageSize, uint64_t addrBytes, bool disableVm)
|
|||
ram_ = nullptr;
|
||||
}
|
||||
|
||||
MemoryUnit::MemoryUnit(uint64_t pageSize, uint64_t addrBytes, uint64_t rootPageNumber)
|
||||
: pageSize_(pageSize)
|
||||
, addrBytes_(addrBytes)
|
||||
, disableVM_(false) {
|
||||
tlb_[0] = TLBEntry(0, 077);
|
||||
}
|
||||
|
||||
void MemoryUnit::attach(MemDevice &m, uint64_t start, uint64_t end) {
|
||||
decoder_.map(start, end, m);
|
||||
}
|
||||
|
||||
MemoryUnit::TLBEntry MemoryUnit::tlbLookup(uint64_t vAddr, uint32_t flagMask) {
|
||||
auto iter = tlb_.find(vAddr / pageSize_);
|
||||
std::cout<< "Looking for addr" <<std::bitset<64>(vAddr)<<std::endl;
|
||||
if (iter != tlb_.end()) {
|
||||
if (iter->second.flags & flagMask){
|
||||
iter->second.updateAccessBit(true);
|
||||
return iter->second;
|
||||
}
|
||||
else {
|
||||
std::cout<<"Security viotion"<<std::endl;
|
||||
throw TlbMiss(vAddr);
|
||||
}
|
||||
} else {
|
||||
std::cout<<"Address not found"<<vAddr<<std::endl;
|
||||
throw TlbMiss(vAddr);
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryUnit::read(void *data, uint64_t addr, uint64_t size, bool sup) {
|
||||
updateTLBIfNeeded();
|
||||
accessBitUpdate();
|
||||
uint64_t pAddr;
|
||||
if (disableVM_) {
|
||||
pAddr = addr;
|
||||
|
@ -158,25 +148,23 @@ void MemoryUnit::read(void *data, uint64_t addr, uint64_t size, bool sup) {
|
|||
uint32_t flagMask = sup ? 8 : 1;
|
||||
try{
|
||||
TLBEntry t = this->tlbLookup(addr, flagMask);
|
||||
pAddr = t.pfn * pageSize_ + addr % pageSize_;
|
||||
std::cout<<"Tlb hit. Adress: "<<std::bitset<64>(addr)<<"Physical address"<<std::endl;
|
||||
pAddr = t.pfn * pageSize_ + addr % pageSize_;
|
||||
}
|
||||
catch(TlbMiss e){
|
||||
std::cout<<"Tlb miss Address: "<< std::bitset<64>(addr)<< std::endl;
|
||||
pAddr = handleTlbMiss(addr);
|
||||
std::cout<<"Translate vAddr: "<< std::bitset<64>(addr)<< "To: "<< std::bitset<64>(pAddr) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
return decoder_.read(data, pAddr, size);
|
||||
}
|
||||
|
||||
uint64_t MemoryUnit::translateVirtualToPhysical(uint64_t vAddr, uint32_t flagMask){
|
||||
MultibaleAddressBase* virtualAddress = virtualAddressFactory_->createMultitableAddressFromBits(vAddr);
|
||||
uint64_t MemoryUnit::translateVirtualToPhysical(uint64_t vAddr, uint32_t flagMask){
|
||||
MultitableAddressBase* virtualAddress = virtualAddressFactory_->createMultitableAddressFromBits(vAddr);
|
||||
uint64_t currentPageNumber = supervisorContainer_->satp.getRootPageNumber();
|
||||
uint64_t address;
|
||||
uint64_t pte;
|
||||
uint64_t pAddr;
|
||||
for(int i = virtualAddress->levelCount() - 1;i >=0; i-- ){
|
||||
for (int i = virtualAddress->levelCount() - 1; i >= 0; i--){
|
||||
address = (currentPageNumber << 12) + (virtualAddress->getOffsetForLevel(i))*sizeof(uint64_t);
|
||||
this->ram_->read(&pte, address, sizeof(uint64_t));
|
||||
TablePageEntryBase tableEntry(pte);
|
||||
|
@ -192,7 +180,7 @@ uint64_t MemoryUnit::translateVirtualToPhysical(uint64_t vAddr, uint32_t flagMa
|
|||
}
|
||||
}else{
|
||||
// return invalid address
|
||||
supervisorContainer_->scause.setPageFaultExceptionAccured(true);
|
||||
supervisorContainer_->scause.setPageFaultExceptionOccured(true);
|
||||
supervisorContainer_->stval.updateValue(vAddr);
|
||||
return -1;
|
||||
}
|
||||
|
@ -205,7 +193,7 @@ uint64_t MemoryUnit:: handlePageFault(){
|
|||
uint64_t causeVAddr = supervisorContainer_->stval.value();
|
||||
uint64_t currentPageNumber = supervisorContainer_->satp.getRootPageNumber();
|
||||
auto vAddr = virtualAddressFactory_->createMultitableAddressFromBits(causeVAddr);
|
||||
for(int i=vAddr->levelCount()-1;i>=1;i--){
|
||||
for (int i = vAddr->levelCount()-1; i >= 1; i--){
|
||||
uint64_t address = (currentPageNumber << 12) + (vAddr->getOffsetForLevel(i))*sizeof(uint64_t);
|
||||
uint64_t pteBits;
|
||||
ram_->read(&pteBits,address, sizeof(uint64_t));
|
||||
|
@ -216,7 +204,7 @@ uint64_t MemoryUnit:: handlePageFault(){
|
|||
else{
|
||||
uint64_t newTableAddress;
|
||||
uint16_t flags=1;
|
||||
newTableAddress = allocate_translation_table();
|
||||
newTableAddress = allocateTranslationTable();
|
||||
uint64_t newTableEntry = (newTableAddress << 8) | flags;
|
||||
|
||||
this->ram_->write(&newTableEntry, address, sizeof(uint64_t));
|
||||
|
@ -230,13 +218,13 @@ uint64_t MemoryUnit:: handlePageFault(){
|
|||
uint64_t newRAMPageNumber = ram_->getFirstFreeTable();
|
||||
uint64_t newPageAddress = newRAMPageNumber << 12;
|
||||
uint8_t* virtualPageData = new uint8_t[pageSize_];
|
||||
requestVirtualPage(virtualPageData, causeVAddr);
|
||||
requestVirtualPage(virtualPageData, (causeVAddr>>12)<<12);
|
||||
ram_->write(virtualPageData, newPageAddress, pageSize_);
|
||||
uint64_t newTableEntry = (newRAMPageNumber << 8) | flags;
|
||||
ram_->write(&newTableEntry, address, sizeof(uint64_t));
|
||||
uint64_t pAddr = (newPageAddress) | pageOffset;
|
||||
|
||||
this->supervisorContainer_->scause.setPageFaultExceptionAccured(false);
|
||||
this->supervisorContainer_->scause.setPageFaultExceptionOccured(false);
|
||||
return pAddr;
|
||||
}
|
||||
|
||||
|
@ -244,11 +232,11 @@ void MemoryUnit::requestVirtualPage(uint8_t* data, uint64_t virtualAddress){
|
|||
virtualDevice_->read(data, virtualAddress, pageSize_);
|
||||
}
|
||||
|
||||
uint64_t MemoryUnit::allocate_translation_table(){
|
||||
uint64_t MemoryUnit::allocateTranslationTable(){
|
||||
uint64_t newPageAddress = this->ram_->getFirstFreeTable();
|
||||
uint8_t zeroByte = 0;
|
||||
uint64_t currentPageAddress = newPageAddress << 12;
|
||||
for(int i=0;i< pageSize_;i++){
|
||||
for (int i = 0; i < pageSize_; i++){
|
||||
this->ram_->write(&zeroByte, currentPageAddress, sizeof(uint8_t));
|
||||
currentPageAddress+= 1;
|
||||
}
|
||||
|
@ -256,9 +244,8 @@ uint64_t MemoryUnit::allocate_translation_table(){
|
|||
return newPageAddress;
|
||||
}
|
||||
|
||||
|
||||
void MemoryUnit::write(const void *data, uint64_t addr, uint64_t size, bool sup) {
|
||||
updateTLBIfNeeded();
|
||||
accessBitUpdate();
|
||||
uint64_t pAddr;
|
||||
if (disableVM_) {
|
||||
pAddr = addr;
|
||||
|
@ -277,15 +264,14 @@ void MemoryUnit::write(const void *data, uint64_t addr, uint64_t size, bool sup)
|
|||
}
|
||||
|
||||
void MemoryUnit::tlbAdd(uint64_t virt, uint64_t phys, uint32_t flags) {
|
||||
MultibaleAddressBase* vAddr =virtualAddressFactory_->createMultitableAddressFromBits(virt);
|
||||
MultitableAddressBase* vAddr = virtualAddressFactory_->createMultitableAddressFromBits(virt);
|
||||
TLBEntry entry(phys, flags);
|
||||
std::cout<<"[TlbAdd] vAddr:"<<std::bitset<64>(vAddr->getVirtualAddress())<<"->"<<std::bitset<64>(phys)<<std::endl;
|
||||
entry.updateAccessBit(true);
|
||||
tlb_[vAddr->getVirtualAddress()] = entry;
|
||||
}
|
||||
|
||||
void MemoryUnit::tlbRm() {
|
||||
for(auto& it: tlb_){
|
||||
void MemoryUnit::tlbEvict() {
|
||||
for (auto& it : tlb_){
|
||||
if(!it.second.isAccessBitSet){
|
||||
tlb_.erase(it.first);
|
||||
}
|
||||
|
@ -321,7 +307,7 @@ void MemoryUnit::setupAddressFactories(){
|
|||
}
|
||||
}
|
||||
|
||||
void MemoryUnit::updateTLBIfNeeded(){
|
||||
void MemoryUnit::accessBitUpdate(){
|
||||
if(memoryAccessCount_ == RefreshTblRate){
|
||||
memoryAccessCount_ = 0;
|
||||
}
|
||||
|
@ -339,16 +325,16 @@ void MemoryUnit::updateTLBIfNeeded(){
|
|||
uint64_t MemoryUnit::handleTlbMiss(uint64_t vaddr)
|
||||
{
|
||||
if(tlb_.size() == maxPageTableEntriesCount){
|
||||
tlbRm();
|
||||
tlbEvict();
|
||||
}
|
||||
uint32_t flagMask = 1;
|
||||
|
||||
uint32_t flagMask = 1;
|
||||
uint64_t pAddr = translateVirtualToPhysical(vaddr,flagMask);
|
||||
//check if page not translated because of page fault
|
||||
if(supervisorContainer_->scause.checkIsPageFaultExceptionAccured()){
|
||||
if(supervisorContainer_->scause.checkIsPageFaultExceptionOccured()){
|
||||
pAddr = handlePageFault();
|
||||
|
||||
}
|
||||
|
||||
tlbAdd(vaddr, pAddr / pageSize_, flagMask);
|
||||
return pAddr;
|
||||
}
|
||||
|
|
|
@ -106,9 +106,9 @@ class TablePageEntryBase{
|
|||
|
||||
};
|
||||
|
||||
class MultibaleAddressBase{
|
||||
class MultitableAddressBase{
|
||||
public:
|
||||
MultibaleAddressBase(uint64_t addr){
|
||||
MultitableAddressBase(uint64_t addr){
|
||||
address_ = addr;
|
||||
}
|
||||
|
||||
|
@ -144,7 +144,7 @@ class MultibaleAddressBase{
|
|||
|
||||
class VirtualAddressFactoryBase{
|
||||
public:
|
||||
virtual MultibaleAddressBase* createMultitableAddressFromBits(uint64_t addr) = 0;
|
||||
virtual MultitableAddressBase* createMultitableAddressFromBits(uint64_t addr) = 0;
|
||||
};
|
||||
|
||||
class PhysicalTableEntryFactoryBase{
|
||||
|
@ -225,7 +225,6 @@ public:
|
|||
};
|
||||
|
||||
MemoryUnit(uint64_t pageSize, uint64_t addrBytes, bool disableVm = false);
|
||||
MemoryUnit(uint64_t pageSize, uint64_t addrBytes, uint64_t rootAddress);
|
||||
void attach(MemDevice &m, uint64_t start, uint64_t end);
|
||||
void read(void *data, uint64_t addr, uint64_t size, bool sup);
|
||||
void write(const void *data, uint64_t addr, uint64_t size, bool sup);
|
||||
|
@ -235,7 +234,9 @@ public:
|
|||
void requestVirtualPage(uint8_t* data,uint64_t virtualAddr);
|
||||
|
||||
void tlbAdd(uint64_t virt, uint64_t phys, uint32_t flags);
|
||||
void tlbRm();
|
||||
void tlbEvict();
|
||||
void tlbRm(uint64_t va);
|
||||
|
||||
void tlbFlush() {
|
||||
tlb_.clear();
|
||||
}
|
||||
|
@ -287,11 +288,11 @@ private:
|
|||
uint64_t translateVirtualToPhysical(uint64_t vAddr, uint32_t flagMask);
|
||||
TLBEntry tlbLookup(uint64_t vAddr, uint32_t flagMask);
|
||||
|
||||
void updateTLBIfNeeded();
|
||||
void accessBitUpdate();
|
||||
void markTableAccessed(uint64_t vAddr);
|
||||
void markTableExecutable(uint64_t vAddr);
|
||||
uint64_t handlePageFault();
|
||||
uint64_t allocate_translation_table();
|
||||
uint64_t allocateTranslationTable();
|
||||
void setupAddressFactories();
|
||||
uint64_t handleTlbMiss(uint64_t vaddr);
|
||||
|
||||
|
@ -329,10 +330,10 @@ class SV39TablePageEntry: public TablePageEntryBase
|
|||
SV39TablePageEntry(uint64_t pte): TablePageEntryBase(pte){};
|
||||
};
|
||||
|
||||
class SV39VirtualAddress: public MultibaleAddressBase
|
||||
class SV39VirtualAddress: public MultitableAddressBase
|
||||
{
|
||||
public:
|
||||
SV39VirtualAddress(uint64_t address):MultibaleAddressBase(address){}
|
||||
SV39VirtualAddress(uint64_t address):MultitableAddressBase(address){}
|
||||
int levelCount() override { return 3;}
|
||||
int pageOffsetLength() override { return 12;}
|
||||
protected:
|
||||
|
@ -347,7 +348,7 @@ class SV39PageTableEntryFactory:public PhysicalTableEntryFactoryBase{
|
|||
|
||||
class SV39VirtualAddressFactory: public VirtualAddressFactoryBase{
|
||||
public:
|
||||
MultibaleAddressBase* createMultitableAddressFromBits(uint64_t addr) override{
|
||||
MultitableAddressBase* createMultitableAddressFromBits(uint64_t addr) override{
|
||||
return new SV39VirtualAddress(addr);
|
||||
}
|
||||
};
|
||||
|
|
41
sim/common/supervisorRegs.cpp
Normal file
41
sim/common/supervisorRegs.cpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
#include "processorRegs.h"
|
||||
|
||||
using namespace vortex;
|
||||
|
||||
SATP:: SATP(VirtualAddressTranslationMode mode){
|
||||
updateMode(mode);
|
||||
}
|
||||
|
||||
void SATP::updateMode(VirtualAddressTranslationMode mode){
|
||||
uint64_t bitsMode = mode;
|
||||
regBits_ =(regBits_ & (((uint64_t)1 << 60)-1)) | (bitsMode<< 59);
|
||||
}
|
||||
|
||||
void SATP::updateRootPageTable(uint64_t ppn){
|
||||
regBits_ = ((regBits_ >> rootPageLength) << rootPageLength)
|
||||
| (ppn & ((((uint64_t)1 << rootPageLength) -1)));
|
||||
}
|
||||
|
||||
uint64_t SATP::getRootPageNumber(){
|
||||
auto rootNumber = regBits_ & (((uint64_t)1 << rootPageLength) -1);
|
||||
return rootNumber;
|
||||
}
|
||||
|
||||
bool SCAUSE::checkIsPageFaultExceptionOccured(){
|
||||
return isBitSet(pageFaultBitNumber);
|
||||
}
|
||||
|
||||
void SCAUSE::setPageFaultExceptionOccured(bool isAccured){
|
||||
setBit(isAccured, pageFaultBitNumber);
|
||||
}
|
||||
|
||||
void SCAUSE::setBit(bool isSet, int number){
|
||||
regBits_ = regBits_ | ((uint64_t) 1 << number);
|
||||
}
|
||||
|
||||
bool SCAUSE::isBitSet(int number){
|
||||
return (regBits_ & ((uint64_t)1 << number)) !=0;
|
||||
}
|
||||
|
||||
|
||||
|
76
sim/common/supervisorRegs.h
Normal file
76
sim/common/supervisorRegs.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace vortex{
|
||||
// according to spec https://github.com/riscv/virtual-memory/blob/main/specs/668-Svinval.pdf
|
||||
// mode is defined in the followig way:
|
||||
// - 0 = No translation or protection
|
||||
// - 1-7 = Reserved for standart use
|
||||
// - 8 = SV39 Page-based 39-bit virtual addressing
|
||||
// - 9 = SV48 Page based 48-bit virtual addressing
|
||||
// - 10 = SV57 Page-based 57-bit virtual addressing
|
||||
// - 11 = SV64 Page based virtual addressing
|
||||
// - 12 - 13 = Reserved for standart use
|
||||
// - 14 - 15 = Designed for custom use
|
||||
enum VirtualAddressTranslationMode:uint8_t{
|
||||
NoTranslation = 0,
|
||||
SV39 = 8
|
||||
};
|
||||
|
||||
class SATP{
|
||||
public:
|
||||
SATP(VirtualAddressTranslationMode mode);
|
||||
void updateMode(VirtualAddressTranslationMode mode);
|
||||
void updateRootPageTable(uint64_t ppn);
|
||||
VirtualAddressTranslationMode Mode(){
|
||||
return static_cast<VirtualAddressTranslationMode>(regBits_ >> (length - modeBitsLength-1));
|
||||
}
|
||||
|
||||
uint64_t getRootPageNumber();
|
||||
|
||||
private:
|
||||
static const int modeBitsLength = 4;
|
||||
static const int rootPageLength = 44;
|
||||
static const int length = 64;
|
||||
uint64_t regBits_;
|
||||
};
|
||||
|
||||
class SCAUSE{
|
||||
public:
|
||||
void setPageFaultExceptionOccured(bool isAccured);
|
||||
bool checkIsPageFaultExceptionOccured();
|
||||
private:
|
||||
void setBit(bool isSet, int number);
|
||||
bool isBitSet(int number);
|
||||
static const int pageFaultBitNumber = 12;
|
||||
uint64_t regBits_;
|
||||
};
|
||||
|
||||
class STVAL{
|
||||
public:
|
||||
void updateValue(uint64_t value){
|
||||
regBits_ = value;
|
||||
};
|
||||
|
||||
uint64_t value(){
|
||||
return regBits_;
|
||||
}
|
||||
private:
|
||||
uint64_t regBits_;
|
||||
};
|
||||
|
||||
class SupervisorRegisterContainer{
|
||||
public:
|
||||
SupervisorRegisterContainer(VirtualAddressTranslationMode mode):
|
||||
satp(mode){};
|
||||
// according to spec https://github.com/riscv/virtual-memory/blob/main/specs/668-Svinval.pdf
|
||||
// these registers are used to control virtual page translation.
|
||||
// Satp is used to define virtual address/page table entry/root page table
|
||||
// Scause defines reason why exception/interruption accured
|
||||
// Stval register is used to get the reason why exception is accured
|
||||
SATP satp;
|
||||
SCAUSE scause;
|
||||
STVAL stval;
|
||||
};
|
||||
}
|
|
@ -171,7 +171,7 @@ void Core::attach_ram(RAM* ram) {
|
|||
mmu_.attachRAM(*ram, 0, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
void Core::attach_virtual_device(VirtualDevice* device){
|
||||
void Core::attachVirtualDevice(VirtualDevice* device){
|
||||
mmu_.attachVirtualDevice(*device);
|
||||
}
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ public:
|
|||
|
||||
void attach_ram(RAM* ram);
|
||||
|
||||
void attach_virtual_device(VirtualDevice* virtualDevice);
|
||||
void attachVirtualDevice(VirtualDevice* virtualDevice);
|
||||
|
||||
void attach_supervisor_regs(SupervisorRegisterContainer* supervysorRegs);
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
// attach memory module
|
||||
processor.attach_ram(&ram);
|
||||
processor.attach_virtual_device(& virtualDevice);
|
||||
processor.attachVirtualDevice(& virtualDevice);
|
||||
|
||||
// run simulation
|
||||
exitcode = processor.run();
|
||||
|
|
|
@ -143,9 +143,9 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void attach_virtual_device(VirtualDevice* virtualDevice){
|
||||
void attachVirtualDevice(VirtualDevice* virtualDevice){
|
||||
for (auto core: cores_){
|
||||
core->attach_virtual_device(virtualDevice);
|
||||
core->attachVirtualDevice(virtualDevice);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,8 +186,8 @@ void Processor::attach_ram(RAM* mem) {
|
|||
impl_->attach_ram(mem);
|
||||
}
|
||||
|
||||
void Processor::attach_virtual_device(VirtualDevice* device){
|
||||
impl_->attach_virtual_device(device);
|
||||
void Processor::attachVirtualDevice(VirtualDevice* device){
|
||||
impl_->attachVirtualDevice(device);
|
||||
}
|
||||
|
||||
int Processor::run() {
|
||||
|
|
|
@ -12,7 +12,7 @@ public:
|
|||
~Processor();
|
||||
|
||||
void attach_ram(RAM* mem);
|
||||
void attach_virtual_device(VirtualDevice* virtualDevice);
|
||||
void attachVirtualDevice(VirtualDevice* virtualDevice);
|
||||
|
||||
int run();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue