From ef1457fa7a3bf3fd58dadd0f30002828b353e573 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Mon, 14 Mar 2016 16:56:34 -0700 Subject: Support RV32 virtual memory tests --- encoding.h | 18 +++++++---- v/riscv_test.h | 6 +++- v/string.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ v/vm.c | 19 +++++++---- 4 files changed, 129 insertions(+), 13 deletions(-) create mode 100644 v/string.c 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 +#include +#include + +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]); -- cgit v1.1