summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2015-07-06 17:06:04 -0700
committerAndrew Waterman <waterman@cs.berkeley.edu>2015-07-06 17:06:04 -0700
commit93cc8bffa3244a8ab4b507594d453faeb344d3d9 (patch)
treee7a33f7a427c8ae63816254cceeff8ad42701afb
parent4f3e3a8d62cc88040846436b9c505045f7303d88 (diff)
downloadenv-93cc8bffa3244a8ab4b507594d453faeb344d3d9.zip
env-93cc8bffa3244a8ab4b507594d453faeb344d3d9.tar.gz
env-93cc8bffa3244a8ab4b507594d453faeb344d3d9.tar.bz2
Coherence torture test for VM tests
VM tests only support one core, so have the other cores hammer on the memory system to attempt to catch simple coherence regressions.
-rw-r--r--v/vm.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/v/vm.c b/v/vm.c
index 1b9845b..74abadd 100644
--- a/v/vm.c
+++ b/v/vm.c
@@ -12,6 +12,12 @@ void do_tohost(long tohost_value);
#define pa2kva(pa) ((void*)(pa) - MEGAPAGE_SIZE)
+static uint64_t lfsr63(uint64_t x)
+{
+ uint64_t bit = (x ^ (x >> 1)) & 1;
+ return (x >> 1) | (bit << 62);
+}
+
static void cputchar(int x)
{
do_tohost(0x0101000000000000 | (unsigned char)x);
@@ -211,9 +217,26 @@ out:
pop_tf(tf);
}
+static void coherence_torture()
+{
+ // cause coherence misses without affecting program semantics
+ uint64_t random = ENTROPY;
+ while (1) {
+ uintptr_t paddr = (random % (2 * (MAX_TEST_PAGES + 1) * PGSIZE)) & -4;
+#ifdef __riscv_atomic
+ if (random & 1) // perform a no-op write
+ asm volatile ("amoadd.w zero, zero, (%0)" :: "r"(paddr));
+ else // perform a read
+#endif
+ asm volatile ("lw zero, (%0)" :: "r"(paddr));
+ random = lfsr63(random);
+ }
+}
+
void vm_boot(long test_addr, long seed)
{
- while (read_csr(mhartid) > 0); // only core 0 proceeds
+ if (read_csr(mhartid) > 0)
+ coherence_torture();
assert(SIZEOF_TRAPFRAME_T == sizeof(trapframe_t));