Browse Source

add clean_invalidate function for caches

pull/891/head
liweiwei 4 years ago
committed by Weiwei Li
parent
commit
456913b2c9
  1. 25
      riscv/cachesim.cc
  2. 5
      riscv/cachesim.h
  3. 14
      riscv/memtracer.h

25
riscv/cachesim.cc

@ -159,6 +159,31 @@ void cache_sim_t::access(uint64_t addr, size_t bytes, bool store)
*check_tag(addr) |= DIRTY;
}
void cache_sim_t::clean_invalidate(uint64_t addr, size_t bytes, bool clean, bool inval)
{
uint64_t start_addr = addr & ~(linesz-1);
uint64_t end_addr = (addr + bytes + linesz-1) & ~(linesz-1);
uint64_t cur_addr = start_addr;
while (cur_addr < end_addr) {
uint64_t* hit_way = check_tag(cur_addr);
if (likely(hit_way != NULL))
{
if (clean) {
if (*hit_way & DIRTY) {
writebacks++;
*hit_way &= ~DIRTY;
}
}
if (inval)
*hit_way &= ~VALID;
}
cur_addr += linesz;
}
if (miss_handler)
miss_handler->clean_invalidate(addr, bytes, clean, inval);
}
fa_cache_sim_t::fa_cache_sim_t(size_t ways, size_t linesz, const char* name)
: cache_sim_t(1, ways, linesz, name)
{

5
riscv/cachesim.h

@ -27,6 +27,7 @@ class cache_sim_t
virtual ~cache_sim_t();
void access(uint64_t addr, size_t bytes, bool store);
void clean_invalidate(uint64_t addr, size_t bytes, bool clean, bool inval);
void print_stats();
void set_miss_handler(cache_sim_t* mh) { miss_handler = mh; }
void set_log(bool _log) { log = _log; }
@ -90,6 +91,10 @@ class cache_memtracer_t : public memtracer_t
{
cache->set_miss_handler(mh);
}
void clean_invalidate(uint64_t addr, size_t bytes, bool clean, bool inval)
{
cache->clean_invalidate(addr, bytes, clean, inval);
}
void set_log(bool log)
{
cache->set_log(log);

14
riscv/memtracer.h

@ -21,6 +21,7 @@ class memtracer_t
virtual bool interested_in_range(uint64_t begin, uint64_t end, access_type type) = 0;
virtual void trace(uint64_t addr, size_t bytes, access_type type) = 0;
virtual void clean_invalidate(uint64_t addr, size_t bytes, bool clean, bool inval) = 0;
};
class memtracer_list_t : public memtracer_t
@ -29,15 +30,20 @@ class memtracer_list_t : public memtracer_t
bool empty() { return list.empty(); }
bool interested_in_range(uint64_t begin, uint64_t end, access_type type)
{
for (std::vector<memtracer_t*>::iterator it = list.begin(); it != list.end(); ++it)
if ((*it)->interested_in_range(begin, end, type))
for (auto it: list)
if (it->interested_in_range(begin, end, type))
return true;
return false;
}
void trace(uint64_t addr, size_t bytes, access_type type)
{
for (std::vector<memtracer_t*>::iterator it = list.begin(); it != list.end(); ++it)
(*it)->trace(addr, bytes, type);
for (auto it: list)
it->trace(addr, bytes, type);
}
void clean_invalidate(uint64_t addr, size_t bytes, bool clean, bool inval)
{
for (auto it: list)
it->clean_invalidate(addr, bytes, clean, inval);
}
void hook(memtracer_t* h)
{

Loading…
Cancel
Save