summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2016-03-14 16:56:34 -0700
committerAndrew Waterman <waterman@cs.berkeley.edu>2016-03-14 16:56:34 -0700
commitef1457fa7a3bf3fd58dadd0f30002828b353e573 (patch)
treed17883848be632baa085628399176c116bb85cd1
parentb7528b89c8673bf38e5e4ec1e8f037ec2bcbee24 (diff)
downloadenv-priv-1.9.zip
env-priv-1.9.tar.gz
env-priv-1.9.tar.bz2
Support RV32 virtual memory testspriv-1.9
-rw-r--r--encoding.h18
-rw-r--r--v/riscv_test.h6
-rw-r--r--v/string.c99
-rw-r--r--v/vm.c19
4 files changed, 129 insertions, 13 deletions
diff --git a/encoding.h b/encoding.h
index f2fab36..6139bb0 100644
--- a/encoding.h
+++ b/encoding.h
@@ -132,22 +132,28 @@
asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
__tmp; })
-#define write_csr(reg, val) \
- asm volatile ("csrw " #reg ", %0" :: "r"(val))
+#define write_csr(reg, val) ({ \
+ if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
+ asm volatile ("csrw " #reg ", %0" :: "i"(val)); \
+ else \
+ asm volatile ("csrw " #reg ", %0" :: "r"(val)); })
-#define swap_csr(reg, val) ({ long __tmp; \
- asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "r"(val)); \
+#define swap_csr(reg, val) ({ unsigned long __tmp; \
+ if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
+ asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "i"(val)); \
+ else \
+ asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "r"(val)); \
__tmp; })
#define set_csr(reg, bit) ({ unsigned long __tmp; \
- if (__builtin_constant_p(bit) && (bit) < 32) \
+ if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
else \
asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \
__tmp; })
#define clear_csr(reg, bit) ({ unsigned long __tmp; \
- if (__builtin_constant_p(bit) && (bit) < 32) \
+ if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
else \
asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \
diff --git a/v/riscv_test.h b/v/riscv_test.h
index 6734713..4e9210a 100644
--- a/v/riscv_test.h
+++ b/v/riscv_test.h
@@ -50,7 +50,11 @@ userstart: \
#define PGSHIFT 12
#define PGSIZE (1UL << PGSHIFT)
-#define SIZEOF_TRAPFRAME_T 288
+#ifdef __riscv64
+# define SIZEOF_TRAPFRAME_T 288
+#else
+# define SIZEOF_TRAPFRAME_T 144
+#endif
#ifndef __ASSEMBLER__
diff --git a/v/string.c b/v/string.c
new file mode 100644
index 0000000..46cd989
--- /dev/null
+++ b/v/string.c
@@ -0,0 +1,99 @@
+#include <string.h>
+#include <stdint.h>
+#include <ctype.h>
+
+void* memcpy(void* dest, const void* src, size_t len)
+{
+ if ((((uintptr_t)dest | (uintptr_t)src | len) & (sizeof(uintptr_t)-1)) == 0) {
+ const uintptr_t* s = src;
+ uintptr_t *d = dest;
+ while (d < (uintptr_t*)(dest + len))
+ *d++ = *s++;
+ } else {
+ const char* s = src;
+ char *d = dest;
+ while (d < (char*)(dest + len))
+ *d++ = *s++;
+ }
+ return dest;
+}
+
+void* memset(void* dest, int byte, size_t len)
+{
+ if ((((uintptr_t)dest | len) & (sizeof(uintptr_t)-1)) == 0) {
+ uintptr_t word = byte & 0xFF;
+ word |= word << 8;
+ word |= word << 16;
+ word |= word << 16 << 16;
+
+ uintptr_t *d = dest;
+ while (d < (uintptr_t*)(dest + len))
+ *d++ = word;
+ } else {
+ char *d = dest;
+ while (d < (char*)(dest + len))
+ *d++ = byte;
+ }
+ return dest;
+}
+
+size_t strlen(const char *s)
+{
+ const char *p = s;
+ while (*p)
+ p++;
+ return p - s;
+}
+
+int strcmp(const char* s1, const char* s2)
+{
+ unsigned char c1, c2;
+
+ do {
+ c1 = *s1++;
+ c2 = *s2++;
+ } while (c1 != 0 && c1 == c2);
+
+ return c1 - c2;
+}
+
+int memcmp(const void* s1, const void* s2, size_t n)
+{
+ while (n--) {
+ unsigned char c1 = *(const unsigned char*)s1++;
+ unsigned char c2 = *(const unsigned char*)s2++;
+ if (c1 != c2)
+ return c1 - c2;
+ }
+
+ return 0;
+}
+
+char* strcpy(char* dest, const char* src)
+{
+ char* d = dest;
+ while ((*d++ = *src++))
+ ;
+ return dest;
+}
+
+long atol(const char* str)
+{
+ long res = 0;
+ int sign = 0;
+
+ while (*str == ' ')
+ str++;
+
+ if (*str == '-' || *str == '+') {
+ sign = *str == '-';
+ str++;
+ }
+
+ while (*str) {
+ res *= 10;
+ res += *str++ - '0';
+ }
+
+ return sign ? -res : res;
+}
diff --git a/v/vm.c b/v/vm.c
index 561578e..2851d38 100644
--- a/v/vm.c
+++ b/v/vm.c
@@ -47,9 +47,14 @@ typedef struct { pte_t addr; void* next; } freelist_t;
pte_t l1pt[PTES_PER_PT] __attribute__((aligned(PGSIZE)));
pte_t user_l2pt[PTES_PER_PT] __attribute__((aligned(PGSIZE)));
-pte_t user_l3pt[PTES_PER_PT] __attribute__((aligned(PGSIZE)));
pte_t kernel_l2pt[PTES_PER_PT] __attribute__((aligned(PGSIZE)));
+#ifdef __riscv64
+pte_t user_l3pt[PTES_PER_PT] __attribute__((aligned(PGSIZE)));
pte_t kernel_l3pt[PTES_PER_PT] __attribute__((aligned(PGSIZE)));
+#else
+# define user_l3pt user_l2pt
+# define kernel_l3pt kernel_l2pt
+#endif
freelist_t user_mapping[MAX_TEST_PAGES];
freelist_t freelist_nodes[MAX_TEST_PAGES];
freelist_t *freelist_head, *freelist_tail;
@@ -170,19 +175,20 @@ void vm_boot(long test_addr, long seed)
if (read_csr(mhartid) > 0)
coherence_torture();
- assert(SIZEOF_TRAPFRAME_T == sizeof(trapframe_t));
+ _Static_assert(SIZEOF_TRAPFRAME_T == sizeof(trapframe_t), "???");
#if MAX_TEST_PAGES > PTES_PER_PT
# error
#endif
+ write_csr(sptbr, (uintptr_t)l1pt >> PGSHIFT);
// map kernel to uppermost megapage
l1pt[PTES_PER_PT-1] = ((pte_t)kernel_l2pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V | PTE_TYPE_TABLE;
- kernel_l2pt[PTES_PER_PT-1] = ((pte_t)kernel_l3pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V | PTE_TYPE_TABLE;
-
// map user to lowermost megapage
l1pt[0] = ((pte_t)user_l2pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V | PTE_TYPE_TABLE;
+#ifdef __riscv64
+ kernel_l2pt[PTES_PER_PT-1] = ((pte_t)kernel_l3pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V | PTE_TYPE_TABLE;
user_l2pt[0] = ((pte_t)user_l3pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V | PTE_TYPE_TABLE;
- write_csr(sptbr, (uintptr_t)l1pt >> PGSHIFT);
+#endif
// set up supervisor trap handling
write_csr(stvec, pa2kva(trap_entry));
@@ -193,8 +199,9 @@ void vm_boot(long test_addr, long seed)
(1 << CAUSE_FAULT_LOAD) |
(1 << CAUSE_FAULT_STORE));
// on ERET, user mode w/interrupts on; FPU on; accelerator on; VM on
+ int vm_choice = sizeof(long) == 8 ? VM_SV39 : VM_SV32;
write_csr(mstatus, MSTATUS_UIE | MSTATUS_FS | MSTATUS_XS |
- (VM_SV39 * (MSTATUS_VM & ~(MSTATUS_VM<<1))));
+ (vm_choice * (MSTATUS_VM & ~(MSTATUS_VM<<1))));
seed = 1 + (seed % MAX_TEST_PAGES);
freelist_head = pa2kva((void*)&freelist_nodes[0]);