mirror of
https://github.com/vortexgpgpu/vortex.git
synced 2025-04-23 21:39:10 -04:00
expand MemoryUnit class defs and add some tlb-related functions
This commit is contained in:
parent
cf3f2d4f6f
commit
2b426693f5
3 changed files with 181 additions and 7 deletions
|
@ -14,6 +14,22 @@
|
|||
`ifndef VX_CONFIG_VH
|
||||
`define VX_CONFIG_VH
|
||||
|
||||
`ifndef VM_ADDR_MODE
|
||||
`define VM_ADDR_MODE SV32
|
||||
`endif
|
||||
|
||||
`ifndef PTE_SIZE
|
||||
`define PTE_SIZE 8
|
||||
`endif
|
||||
|
||||
`ifndef TLB_SIZE
|
||||
`define TLB_SIZE 32
|
||||
`endif
|
||||
|
||||
`ifndef SUPER_PAGING
|
||||
`define SUPER_PAGING false
|
||||
`endif
|
||||
|
||||
`ifndef MIN
|
||||
`define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
||||
`endif
|
||||
|
|
|
@ -17,9 +17,22 @@
|
|||
#include <fstream>
|
||||
#include <assert.h>
|
||||
#include "util.h"
|
||||
#include <VX_config.h>
|
||||
#include <bitset>
|
||||
|
||||
using namespace vortex;
|
||||
|
||||
uint64_t bits(uint64_t addr, uint8_t s_idx, uint8_t e_idx)
|
||||
{
|
||||
return (addr >> s_idx) & ((1 << (e_idx - s_idx + 1)) - 1);
|
||||
}
|
||||
|
||||
bool bit(uint64_t addr, uint8_t idx)
|
||||
{
|
||||
return (addr) & (1 << idx);
|
||||
}
|
||||
|
||||
|
||||
RamMemDevice::RamMemDevice(const char *filename, uint32_t wordSize)
|
||||
: wordSize_(wordSize) {
|
||||
std::ifstream input(filename);
|
||||
|
@ -158,12 +171,12 @@ uint64_t MemoryUnit::toPhyAddr(uint64_t addr, uint32_t flagMask) {
|
|||
return pAddr;
|
||||
}
|
||||
|
||||
void MemoryUnit::read(void* data, uint64_t addr, uint64_t size, bool sup) {
|
||||
void MemoryUnit::read(void* data, uint64_t addr, uint64_t size, bool sup, ACCESS_TYPE type) {
|
||||
uint64_t pAddr = this->toPhyAddr(addr, sup ? 8 : 1);
|
||||
return decoder_.read(data, pAddr, size);
|
||||
}
|
||||
|
||||
void MemoryUnit::write(const void* data, uint64_t addr, uint64_t size, bool sup) {
|
||||
void MemoryUnit::write(const void* data, uint64_t addr, uint64_t size, bool sup, ACCESS_TYPE type) {
|
||||
uint64_t pAddr = this->toPhyAddr(addr, sup ? 16 : 1);
|
||||
decoder_.write(data, pAddr, size);
|
||||
amo_reservation_.valid = false;
|
||||
|
@ -179,10 +192,34 @@ bool MemoryUnit::amo_check(uint64_t addr) {
|
|||
uint64_t pAddr = this->toPhyAddr(addr, 1);
|
||||
return amo_reservation_.valid && (amo_reservation_.addr == pAddr);
|
||||
}
|
||||
|
||||
void MemoryUnit::tlbAdd(uint64_t virt, uint64_t phys, uint32_t flags) {
|
||||
tlb_[virt / pageSize_] = TLBEntry(phys / pageSize_, flags);
|
||||
}
|
||||
|
||||
void MemoryUnit::tlbAdd(uint64_t virt, uint64_t phys, uint32_t flags, uint64_t size_bits) {
|
||||
// HW: evict TLB by Most Recently Used
|
||||
if (tlb_.size() == TLB_SIZE - 1) {
|
||||
for (auto& entry : tlb_)
|
||||
{
|
||||
entry.second.mru_bit = false;
|
||||
}
|
||||
|
||||
} else if (tlb_.size() == TLB_SIZE) {
|
||||
uint64_t del;
|
||||
for (auto entry : tlb_) {
|
||||
if (!entry.second.mru_bit)
|
||||
{
|
||||
del = entry.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
tlb_.erase(tlb_.find(del));
|
||||
TLB_EVICT++;
|
||||
}
|
||||
tlb_[virt / pageSize_] = TLBEntry(phys / pageSize_, flags, size_bits);
|
||||
}
|
||||
|
||||
void MemoryUnit::tlbRm(uint64_t va) {
|
||||
if (tlb_.find(va / pageSize_) != tlb_.end())
|
||||
tlb_.erase(tlb_.find(va / pageSize_));
|
||||
|
|
131
sim/common/mem.h
131
sim/common/mem.h
|
@ -18,8 +18,22 @@
|
|||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <cstdint>
|
||||
#include <unordered_set>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace vortex {
|
||||
|
||||
enum VA_MODE {
|
||||
BARE,
|
||||
SV32
|
||||
};
|
||||
|
||||
enum ACCESS_TYPE {
|
||||
LOAD,
|
||||
STORE,
|
||||
FETCH
|
||||
};
|
||||
|
||||
struct BadAddress {};
|
||||
struct OutOfRange {};
|
||||
|
||||
|
@ -73,31 +87,39 @@ public:
|
|||
class MemoryUnit {
|
||||
public:
|
||||
|
||||
// HW: Expand PageFault struct to contain access_type info for debug purposes
|
||||
struct PageFault {
|
||||
PageFault(uint64_t a, bool nf)
|
||||
: faultAddr(a)
|
||||
, notFound(nf)
|
||||
, access_type(ACCESS_TYPE::LOAD)
|
||||
{}
|
||||
uint64_t faultAddr;
|
||||
bool notFound;
|
||||
uint64_t faultAddr;
|
||||
bool notFound;
|
||||
ACCESS_TYPE access_type;
|
||||
};
|
||||
|
||||
MemoryUnit(uint64_t pageSize = 0);
|
||||
|
||||
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);
|
||||
void read(void* data, uint64_t addr, uint64_t size, bool sup, ACCESS_TYPE type = ACCESS_TYPE::LOAD);
|
||||
void write(const void* data, uint64_t addr, uint64_t size, bool sup, ACCESS_TYPE type = ACCESS_TYPE::LOAD);
|
||||
|
||||
void amo_reserve(uint64_t addr);
|
||||
bool amo_check(uint64_t addr);
|
||||
|
||||
void tlbAdd(uint64_t virt, uint64_t phys, uint32_t flags);
|
||||
void tlbAdd(uint64_t virt, uint64_t phys, uint32_t flags, uint64_t size_bits);
|
||||
|
||||
void tlbRm(uint64_t vaddr);
|
||||
void tlbFlush() {
|
||||
tlb_.clear();
|
||||
}
|
||||
|
||||
uint32_t get_satp();
|
||||
void set_satp(uint32_t satp);
|
||||
|
||||
private:
|
||||
|
||||
struct amo_reservation_t {
|
||||
|
@ -137,11 +159,41 @@ private:
|
|||
TLBEntry(uint32_t pfn, uint32_t flags)
|
||||
: pfn(pfn)
|
||||
, flags(flags)
|
||||
{}
|
||||
, mru_bit(true)
|
||||
{};
|
||||
TLBEntry(uint32_t pfn, uint32_t flags, uint64_t size_bits)
|
||||
: pfn(pfn)
|
||||
, flags(flags)
|
||||
, mru_bit(true)
|
||||
, size_bits (size_bits)
|
||||
{
|
||||
d = bit(7);
|
||||
a = bit(6);
|
||||
g = bit(5);
|
||||
u = bit(4);
|
||||
x = bit(3);
|
||||
w = bit(2);
|
||||
r = bit(1);
|
||||
v = bit(0);
|
||||
}
|
||||
bool bit(uint8_t idx)
|
||||
{
|
||||
return (flags) & (1 << idx);
|
||||
}
|
||||
|
||||
uint32_t pfn;
|
||||
bool d, a, g, u, x, w, r, v;
|
||||
bool mru_bit;
|
||||
uint64_t size_bits;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
std::pair<bool, uint64_t> tlbLookup(uint64_t vAddr, ACCESS_TYPE type, uint64_t* size_bits);
|
||||
|
||||
uint64_t vAddr_to_pAddr(uint64_t vAddr, ACCESS_TYPE type);
|
||||
|
||||
std::pair<uint64_t, uint8_t> page_table_walk(uint64_t vAddr_bits, ACCESS_TYPE type, uint64_t* size_bits);
|
||||
|
||||
TLBEntry tlbLookup(uint64_t vAddr, uint32_t flagMask);
|
||||
|
||||
uint64_t toPhyAddr(uint64_t vAddr, uint32_t flagMask);
|
||||
|
@ -151,6 +203,13 @@ private:
|
|||
ADecoder decoder_;
|
||||
bool enableVM_;
|
||||
|
||||
uint32_t satp;
|
||||
VA_MODE mode;
|
||||
uint32_t ptbr;
|
||||
|
||||
std::unordered_set<uint64_t> unique_translations;
|
||||
uint64_t TLB_HIT, TLB_MISS, TLB_EVICT, PTW, PERF_UNIQUE_PTW;
|
||||
|
||||
amo_reservation_t amo_reservation_;
|
||||
};
|
||||
|
||||
|
@ -219,4 +278,66 @@ private:
|
|||
bool check_acl_;
|
||||
};
|
||||
|
||||
class PTE_SV32_t
|
||||
{
|
||||
|
||||
private:
|
||||
uint64_t address;
|
||||
uint64_t bits(uint64_t addr, uint8_t s_idx, uint8_t e_idx)
|
||||
{
|
||||
return (addr >> s_idx) & ((1 << (e_idx - s_idx + 1)) - 1);
|
||||
}
|
||||
bool bit(uint8_t idx)
|
||||
{
|
||||
return (address) & (1 << idx);
|
||||
}
|
||||
|
||||
public:
|
||||
uint64_t ppn[2];
|
||||
uint32_t rsw;
|
||||
uint32_t flags;
|
||||
bool d, a, g, u, x, w, r, v;
|
||||
PTE_SV32_t(uint64_t address) : address(address)
|
||||
{
|
||||
flags = bits(address,0,7);
|
||||
rsw = bits(address,8,9);
|
||||
ppn[0] = bits(address,10,19);
|
||||
ppn[1] = bits(address,20,31);
|
||||
|
||||
d = bit(7);
|
||||
a = bit(6);
|
||||
g = bit(5);
|
||||
u = bit(4);
|
||||
x = bit(3);
|
||||
w = bit(2);
|
||||
r = bit(1);
|
||||
v = bit(0);
|
||||
}
|
||||
};
|
||||
|
||||
class vAddr_SV32_t
|
||||
{
|
||||
|
||||
private:
|
||||
uint64_t address;
|
||||
uint64_t bits(uint64_t addr, uint8_t s_idx, uint8_t e_idx)
|
||||
{
|
||||
return (addr >> s_idx) & ((1 << (e_idx - s_idx + 1)) - 1);
|
||||
}
|
||||
bool bit(uint64_t addr, uint8_t idx)
|
||||
{
|
||||
return (addr) & (1 << idx);
|
||||
}
|
||||
|
||||
public:
|
||||
uint64_t vpn[2];
|
||||
uint64_t pgoff;
|
||||
vAddr_SV32_t(uint64_t address) : address(address)
|
||||
{
|
||||
vpn[0] = bits(address,12,21);
|
||||
vpn[1] = bits(address,22,31);
|
||||
pgoff = bits(address,0,11);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace vortex
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue