Browse Source

Merge pull request #1210 from riscv-software-src/dynamic-dirty-enable

Control mmu-dirtying via command line
pull/1211/head
Andrew Waterman 4 years ago
committed by GitHub
parent
commit
0eec0c9119
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 39
      ci-tests/testlib.c
  2. 3
      config.h.in
  3. 16
      configure
  4. 3
      riscv/cfg.h
  5. 34
      riscv/mmu.cc
  6. 9
      riscv/mmu.h
  7. 5
      riscv/riscv.ac
  8. 1
      spike_main/spike-log-parser.cc
  9. 3
      spike_main/spike.cc

39
ci-tests/testlib.c

@ -17,16 +17,17 @@ int main()
std::vector<mem_cfg_t> mem_cfg { mem_cfg_t(0x80000000, 0x10000000) };
std::vector<int> hartids = {0};
cfg_t cfg(std::make_pair(0, 0),
nullptr,
"rv64gcv",
"MSU",
"vlen:128,elen:64",
false,
endianness_little,
16,
mem_cfg,
hartids,
false);
nullptr,
"rv64gcv",
"MSU",
"vlen:128,elen:64",
false,
endianness_little,
false,
16,
mem_cfg,
hartids,
false);
std::vector<std::pair<reg_t, abstract_device_t*>> plugin_devices;
std::vector<std::string> htif_args {"pk", "hello"};
debug_module_config_t dm_config = {
@ -42,14 +43,14 @@ int main()
};
std::vector<std::pair<reg_t, mem_t*>> mems = make_mems(cfg.mem_layout());
sim_t sim(&cfg, false,
mems,
plugin_devices,
htif_args,
dm_config,
nullptr,
true,
nullptr,
false,
nullptr);
mems,
plugin_devices,
htif_args,
dm_config,
nullptr,
true,
nullptr,
false,
nullptr);
sim.run();
}

3
config.h.in

@ -99,9 +99,6 @@
/* Define if subproject MCPPBS_SPROJ_NORM is enabled */
#undef RISCV_ENABLED
/* Enable hardware management of PTE accessed and dirty bits */
#undef RISCV_ENABLE_DIRTY
/* Enable support for running target in either endianness */
#undef RISCV_ENABLE_DUAL_ENDIAN

16
configure

@ -1359,8 +1359,6 @@ Optional Features:
--enable-stow Enable stow-based install
--enable-optional-subprojects
Enable all optional subprojects
--enable-dirty Enable hardware management of PTE accessed and dirty
bits
--enable-dual-endian Enable support for running target in either
endianness
@ -6046,20 +6044,6 @@ else
as_fn_error $? "libpthread is required" "$LINENO" 5
fi
# Check whether --enable-dirty was given.
if test "${enable_dirty+set}" = set; then :
enableval=$enable_dirty;
fi
if test "x$enable_dirty" = "xyes"; then :
$as_echo "#define RISCV_ENABLE_DIRTY /**/" >>confdefs.h
fi
# Check whether --enable-dual-endian was given.
if test "${enable_dual_endian+set}" = set; then :
enableval=$enable_dual_endian;

3
riscv/cfg.h

@ -54,6 +54,7 @@ public:
const char *default_varch,
const bool default_misaligned,
const endianness_t default_endianness,
const bool default_dirty_enabled,
const reg_t default_pmpregions,
const std::vector<mem_cfg_t> &default_mem_layout,
const std::vector<int> default_hartids,
@ -65,6 +66,7 @@ public:
varch(default_varch),
misaligned(default_misaligned),
endianness(default_endianness),
dirty_enabled(default_dirty_enabled),
pmpregions(default_pmpregions),
mem_layout(default_mem_layout),
hartids(default_hartids),
@ -79,6 +81,7 @@ public:
cfg_arg_t<const char *> varch;
bool misaligned;
endianness_t endianness;
bool dirty_enabled;
reg_t pmpregions;
cfg_arg_t<std::vector<mem_cfg_t>> mem_layout;
std::optional<reg_t> start_pc;

34
riscv/mmu.cc

@ -413,16 +413,17 @@ reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_ty
break;
} else {
reg_t ad = PTE_A | ((type == STORE) * PTE_D);
#ifdef RISCV_ENABLE_DIRTY
// set accessed and possibly dirty bits.
if ((pte & ad) != ad) {
pte_store(pte_paddr, pte | ad, gva, virt, type, vm.ptesize);
if (proc->cfg->dirty_enabled) {
// set accessed and possibly dirty bits
pte_store(pte_paddr, pte | ad, gva, virt, type, vm.ptesize);
} else {
// take exception if access or possibly dirty bit is not set.
break;
}
}
#else
// take exception if access or possibly dirty bit is not set.
if ((pte & ad) != ad)
break;
#endif
reg_t vpn = gpa >> PGSHIFT;
reg_t page_mask = (reg_t(1) << PGSHIFT) - 1;
@ -500,16 +501,17 @@ reg_t mmu_t::walk(reg_t addr, access_type type, reg_t mode, bool virt, bool hlvx
break;
} else {
reg_t ad = PTE_A | ((type == STORE) * PTE_D);
#ifdef RISCV_ENABLE_DIRTY
// set accessed and possibly dirty bits.
if ((pte & ad) != ad) {
pte_store(pte_paddr, pte | ad, addr, virt, type, vm.ptesize);
if (proc->cfg->dirty_enabled) {
// set accessed and possibly dirty bits.
pte_store(pte_paddr, pte | ad, addr, virt, type, vm.ptesize);
} else {
// take exception if access or possibly dirty bit is not set.
break;
}
}
#else
// take exception if access or possibly dirty bit is not set.
if ((pte & ad) != ad)
break;
#endif
// for superpage or Svnapot NAPOT mappings, make a fake leaf PTE for the TLB's benefit.
reg_t vpn = addr >> PGSHIFT;

9
riscv/mmu.h

@ -274,14 +274,7 @@ public:
void register_memtracer(memtracer_t*);
int is_dirty_enabled()
{
#ifdef RISCV_ENABLE_DIRTY
return 1;
#else
return 0;
#endif
}
int is_dirty_enabled() { return proc && proc->cfg->dirty_enabled; }
int is_misaligned_enabled()
{

5
riscv/riscv.ac

@ -39,11 +39,6 @@ AC_SEARCH_LIBS([dlopen], [dl dld], [
AC_CHECK_LIB(pthread, pthread_create, [], [AC_MSG_ERROR([libpthread is required])])
AC_ARG_ENABLE([dirty], AS_HELP_STRING([--enable-dirty], [Enable hardware management of PTE accessed and dirty bits]))
AS_IF([test "x$enable_dirty" = "xyes"], [
AC_DEFINE([RISCV_ENABLE_DIRTY],,[Enable hardware management of PTE accessed and dirty bits])
])
AC_ARG_ENABLE([dual-endian], AS_HELP_STRING([--enable-dual-endian], [Enable support for running target in either endianness]))
AS_IF([test "x$enable_dual_endian" = "xyes"], [
AC_DEFINE([RISCV_ENABLE_DUAL_ENDIAN],,[Enable support for running target in either endianness])

1
spike_main/spike-log-parser.cc

@ -35,6 +35,7 @@ int main(int UNUSED argc, char** argv)
/*default_varch=*/DEFAULT_VARCH,
/*default_misaligned=*/false,
/*default_endianness*/endianness_little,
/*default_dirty_enabled=*/false,
/*default_pmpregions=*/16,
/*default_mem_layout=*/std::vector<mem_cfg_t>(),
/*default_hartids=*/std::vector<int>(),

3
spike_main/spike.cc

@ -70,6 +70,7 @@ static void help(int exit_code = 1)
fprintf(stderr, " --initrd=<path> Load kernel initrd into memory\n");
fprintf(stderr, " --bootargs=<args> Provide custom bootargs for kernel [default: console=hvc0 earlycon=sbi]\n");
fprintf(stderr, " --real-time-clint Increment clint time at real-time rate\n");
fprintf(stderr, " --mmu-dirty Enable hardware management of PTE accessed and dirty bits\n");
fprintf(stderr, " --dm-progsize=<words> Progsize for the debug module [default 2]\n");
fprintf(stderr, " --dm-sba=<bits> Debug system bus access supports up to "
"<bits> wide accesses [default 0]\n");
@ -330,6 +331,7 @@ int main(int argc, char** argv)
/*default_varch=*/DEFAULT_VARCH,
/*default_misaligned=*/false,
/*default_endianness*/endianness_little,
/*default_dirty_enabled*/false,
/*default_pmpregions=*/16,
/*default_mem_layout=*/parse_mem_layout("2048"),
/*default_hartids=*/std::vector<int>(),
@ -416,6 +418,7 @@ int main(int argc, char** argv)
parser.option(0, "initrd", 1, [&](const char* s){initrd = s;});
parser.option(0, "bootargs", 1, [&](const char* s){cfg.bootargs = s;});
parser.option(0, "real-time-clint", 0, [&](const char UNUSED *s){cfg.real_time_clint = true;});
parser.option(0, "mmu-dirty", 0, [&](const char UNUSED *s){cfg.dirty_enabled = true;});
parser.option(0, "extlib", 1, [&](const char *s){
void *lib = dlopen(s, RTLD_NOW | RTLD_GLOBAL);
if (lib == NULL) {

Loading…
Cancel
Save