Commit de6bfd7b authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

test suite running

parent 4ad34eca
.section .boot, "ax", @progbits
#define MSTATUS_IE 0x00000001
#define EXCEPT_IRQ (1<<10)
#define EXCEPT_TIMER (1<<9)
.section .boot, "ax", @progbits
.global _start
.global _start
_start:
j _entry
.org 0x40
.org 0x8
.extern trap_entry
_exception_handler:
j trap_entry
_exception_entry:
j trap_entry
_entry:
nop
nop
la gp, _gp # Initialize global pointer
la sp, _fstack
la t0, _fexception_stack
csrrw t0, mscratch, t0
la gp, _gp # Initialize global pointer
la sp, _fstack
la t0, _fexception_stack
csrrw t0, mscratch, t0
# clear the bss segment
la t0, _fbss
la t1, _end
la t0, _fbss
la t1, _end
1:
#ifdef __riscv64
sd zero,0(t0)
addi t0, t0, 8
sd zero,0(t0)
addi t0, t0, 8
#else
sw zero,0(t0)
addi t0, t0, 4
sw zero,0(t0)
addi t0, t0, 4
#endif
bltu t0, t1, 1b
bltu t0, t1, 1b
call main
\ No newline at end of file
call main
.section .boot, "ax", @progbits
#define MSTATUS_IE 0x00000001
#define EXCEPT_IRQ (1<<10)
#define EXCEPT_TIMER (1<<9)
.global _start
_start:
j _entry
_trap:
j handle_trap
_entry:
nop
nop
la gp, _gp # Initialize global pointer
la sp, _fstack
la t0, _fexception_stack
csrrw t0, mscratch, t0
# clear the bss segment
la t0, _fbss
la t1, _end
1:
#ifdef __riscv64
sd zero,0(t0)
addi t0, t0, 8
#else
sw zero,0(t0)
addi t0, t0, 4
#endif
bltu t0, t1, 1b
call main
\ No newline at end of file
#include <stdint.h>
struct rv_trap_context {
uint32_t r[32];
uint32_t mstatus;
uint32_t mepc;
uint32_t mbadaddr;
uint32_t mcause;
};
void undefined_insn_handler( struct rv_trap_context *ctx )
{
uint32_t insn = *(volatile uint32_t *)( ctx->mepc );
ctx->r[0] = 0;
uint32_t rs1 = ctx->r[(insn >> 15) & 0x1f];
uint32_t rs2 = ctx->r[(insn >> 20) & 0x1f];
uint32_t rdi = (insn >> 7) & 0x1f;
// we support MUL natively
if ( (insn & 0xfe00707f) == 0x2001033 ) // MULH
ctx->r[rdi] = ( (int64_t)(int32_t)rs1 * (int64_t)(int32_t) rs2) >> 32;
else if ( (insn & 0xfe00707f) == 0x2002033 ) // MULHSU
ctx->r[rdi] = ((int64_t)(int32_t)rs1 * (uint64_t) rs2) >> 32;
else if ( (insn & 0xfe00707f) == 0x2003033 ) // MULHU
ctx->r[rdi] = ((uint64_t) rs1 * (uint64_t) rs2) >> 32;
else if ( (insn & 0xfe00707f) == 0x2004033 ) // DIV
ctx->r[rdi] = (int32_t)rs1 / (int32_t) rs2;
else if ( (insn & 0xfe00707f) == 0x2005033 ) // DIVU
ctx->r[rdi] = (uint32_t)rs1 / (uint32_t) rs2;
else if ( (insn & 0xfe00707f) == 0x2006033 ) // REM
ctx->r[rdi] = (int32_t)rs1 % (int32_t) rs2;
else if ( (insn & 0xfe00707f) == 0x2007033 ) // REMU
ctx->r[rdi] = (uint32_t)rs1 % (uint32_t) rs2;
ctx->mepc += 4;
asm volatile ("csrc mip, 0x4"); // clear exception
}
\ No newline at end of file
.section .text
.global trap_entry
trap_entry:
csrrw sp,mscratch,sp
addi sp,sp,-320
sw ra,4(sp)
sw gp,12(sp)
sw tp,16(sp)
sw t0,20(sp)
sw t1,24(sp)
sw t2,28(sp)
sw s0,32(sp)
sw s1,36(sp)
sw a0,40(sp)
sw a1,44(sp)
sw a2,48(sp)
sw a3,52(sp)
sw a4,56(sp)
sw a5,60(sp)
sw a6,64(sp)
sw a7,68(sp)
sw s2,72(sp)
sw s3,76(sp)
sw s4,80(sp)
sw s5,84(sp)
sw s6,88(sp)
sw s7,92(sp)
sw s8,96(sp)
sw s9,100(sp)
sw s10,104(sp)
sw s11,108(sp)
sw t3,112(sp)
sw t4,116(sp)
sw t5,120(sp)
sw t6,124(sp)
csrr t0,mscratch
csrr s0,mstatus
csrr t1,mepc
csrr t2,mbadaddr
csrr t3,mcause
sw t0,8(sp)
sw s0,128(sp)
sw t1,132(sp)
sw t2,136(sp)
sw t3,140(sp)
li t0,-1
sw t0,144(sp)
mv a0,sp
la t0, jump_table
sll t3, t3, 2
add t0, t0, t3
lw t0, 0(t0)
la ra, jump_table_return
jr t0
jump_table:
.word undefined_handler
.word undefined_handler
.word undefined_insn_handler
.word undefined_handler
.word undefined_handler
.word undefined_handler
.word undefined_handler
.word undefined_handler
.word undefined_handler
.word undefined_handler
.word undefined_handler
.word undefined_handler
.word undefined_handler
.word undefined_handler
.word undefined_handler
.word undefined_handler
jump_table_return:
mv a0,sp
lw t1,128(a0)
lw t2,132(a0)
addi sp,sp,320
csrw mscratch,sp
csrw mepc,t2
lw ra,4(a0)
lw sp,8(a0)
lw gp,12(a0)
lw tp,16(a0)
lw t0,20(a0)
lw t1,24(a0)
lw t2,28(a0)
lw s0,32(a0)
lw s1,36(a0)
lw a1,44(a0)
lw a2,48(a0)
lw a3,52(a0)
lw a4,56(a0)
lw a5,60(a0)
lw a6,64(a0)
lw a7,68(a0)
lw s2,72(a0)
lw s3,76(a0)
lw s4,80(a0)
lw s5,84(a0)
lw s6,88(a0)
lw s7,92(a0)
lw s8,96(a0)
lw s9,100(a0)
lw s10,104(a0)
lw s11,108(a0)
lw t3,112(a0)
lw t4,116(a0)
lw t5,120(a0)
lw t6,124(a0)
lw a0,40(a0)
eret
.weak undefined_handler
undefined_handler:
j undefined_handler
.weak undefined_insn_handler
undefined_insn_handler:
j undefined_insn_handler
#include <stdarg.h>
extern int pp_printf(const char *fmt, ...)
__attribute__((format(printf,1,2)));
extern int pp_sprintf(char *s, const char *fmt, ...)
__attribute__((format(printf,2,3)));
extern int pp_vprintf(const char *fmt, va_list args);
extern int pp_vsprintf(char *buf, const char *, va_list)
__attribute__ ((format (printf, 2, 0)));
/* This is what we rely on for output */
extern int puts(const char *s);
/*
* Basic printf based on vprintf based on vsprintf
*
* Alessandro Rubini for CERN, 2011 -- public domain
* (please note that the vsprintf is not public domain but GPL)
*/
#include <stdarg.h>
#include <pp-printf.h>
#define CONFIG_PRINT_BUFSIZE 128
static char print_buf[CONFIG_PRINT_BUFSIZE];
int pp_vprintf(const char *fmt, va_list args)
{
int ret;
ret = pp_vsprintf(print_buf, fmt, args);
puts(print_buf);
return ret;
}
int pp_sprintf(char *s, const char *fmt, ...)
{
va_list args;
int ret;
va_start(args, fmt);
ret = pp_vsprintf(s, fmt, args);
va_end(args);
return ret;
}
int pp_printf(const char *fmt, ...)
{
va_list args;
int ret;
va_start(args, fmt);
ret = pp_vprintf(fmt, args);
va_end(args);
return ret;
}
#ifndef __RISCV_H
#define __RISCV_H
#ifdef __GNUC__
#define read_csr(reg) ({ unsigned long __tmp; \
asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
__tmp; })
#define write_csr(reg, val) \
asm volatile ("csrw " #reg ", %0" :: "r"(val))
#define swap_csr(reg, val) ({ long __tmp; \
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) \
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) \
asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
else \
asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \
__tmp; })
#define rdtime() read_csr(time)
#define rdcycle() read_csr(cycle)
#define rdinstret() read_csr(instret)
#endif
#endif
#include <stdint.h>
void rv_test_pass(int num)
{
pp_printf("Test passed\n");
}
void rv_test_fail(int num)
{
pp_printf("Test %d failed\n", num);
}
\ No newline at end of file
OUTPUT_FORMAT("elf32-littleriscv")
ENTRY(_start)
SECTIONS
{
/*--------------------------------------------------------------------*/
/* Code and read-only segment */
/*--------------------------------------------------------------------*/
/* Begining of code and text segment */
. = 0x00000800;
_ftext = .;
PROVIDE( eprol = . );
/* text: Program code section */
.text :
{
*(.boot)
*(.text)
*(.text.*)
*(.gnu.linkonce.t.*)
}
/* init: Code to execute before main (called by crt0.S) */
.init :
{
KEEP( *(.init) )
}
/* fini: Code to execute after main (called by crt0.S) */
.fini :
{
KEEP( *(.fini) )
}
/* rodata: Read-only data */
.rodata :
{
*(.rdata)
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
}
/* End of code and read-only segment */
PROVIDE( etext = . );
_etext = .;
/*--------------------------------------------------------------------*/
/* Global constructor/destructor segement */
/*--------------------------------------------------------------------*/
/* The .ctors/.dtors sections are special sections which contain a
list of constructor/destructor function pointers. crtbegin.o
includes code in a .init section which goes through the .ctors list
and calls each constuctor. crtend.o includes code in a .fini
section which goes through the .dtors list and calls each
destructor. crtbegin.o includes a special null pointer in its own
.ctors/.dtors sections which acts as a start indicator for those
lists. crtend.o also includes a special null pointer in its own
.ctors/.dtors sections which acts as an end indictor. The linker
commands below are setup so that crtbegin.o's .ctors/.dtors
sections are always first and crtend.o's .ctors/.dtors sections are
always last. This is the only way the list of functions will have
the begin and end indicators in the right place. */
/* ctors : Array of global constructor function pointers */
/*--------------------------------------------------------------------*/
/* Initialized data segment */
/*--------------------------------------------------------------------*/
/* Start of initialized data segment */
. = ALIGN(16);
_fdata = .;
/* data: Writable data */
.data :
{
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
}
/* End of initialized data segment */
PROVIDE( edata = . );
_edata = .;
/* Have _gp point to middle of sdata/sbss to maximize displacement range */
. = ALIGN(16);
_gp = . + 0x800;
/* Writable small data segment */
.sdata :
{
*(.sdata)
*(.sdata.*)
*(.srodata.*)
*(.gnu.linkonce.s.*)
}
/*--------------------------------------------------------------------*/
/* Uninitialized data segment */
/*--------------------------------------------------------------------*/
/* Start of uninitialized data segment */
. = ALIGN(8);
_fbss = .;
/* Writable uninitialized small data segment */
.sbss :
{
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
}
/* bss: Uninitialized writeable data section */
. = .;
_bss_start = .;
.bss :
{
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
}
/* End of uninitialized data segment (used by syscalls.c for heap) */
PROVIDE( end = . );
_end = ALIGN(8);
PROVIDE( _fstack = 0xfffc - 0x400 );
PROVIDE( _fexception_stack = 0xfffc );
}
/*
* vsprintf-xint: a possible free-software replacement for mprintf
*
* public domain
*/
#include <stdarg.h>
#include <stdint.h>
static const char hex[] = "0123456789abcdef";
static int number(char *out, unsigned value, int base, int lead, int wid)
{
char tmp[16];
int i = 16, ret, negative = 0;
/* No error checking at all: it is as ugly as possible */
if ((signed)value < 0 && base == 10) {
negative = 1;
value = -value;
}
while (value && i) {
tmp[--i] = hex[value % base];
value /= base;
}
if (i == 16)
tmp[--i] = '0';
if (negative && lead == ' ') {
tmp[--i] = '-';
negative = 0;
}
while (i > 16 - wid + negative)
tmp[--i] = lead;
if (negative)
tmp[--i] = '-';
ret = 16 - i;
while (i < 16)
*(out++) = tmp[i++];
return ret;
}
int pp_vsprintf(char *buf, const char *fmt, va_list args)
{
char *s, *str = buf;
int base, lead, wid;
for (; *fmt ; ++fmt) {
if (*fmt != '%') {
*str++ = *fmt;
continue;
}
base = 10;
lead = ' ';
wid = 1;
repeat:
fmt++; /* Skip '%' initially, other stuff later */
switch(*fmt) {
case '\0':
goto ret;
case '0':
lead = '0';
goto repeat;
case '*':
/* should be precision, just eat it */
base = va_arg(args, int);
/* fall through: discard unknown stuff */
default:
if (*fmt >= '1' && *fmt <= '9')
wid = *fmt - '0';
goto repeat;
/* Special cases for conversions */
case 'c': /* char: supported */
*str++ = (unsigned char) va_arg(args, int);
break;
case 's': /* string: supported */
s = va_arg(args, char *);
while (*s)
*str++ = *s++;
break;
case 'n': /* number-thus-far: not supported */
break;
case '%': /* supported */
*str++ = '%';
break;
/* integers are more or less printed */
case 'p':
case 'x':
case 'X':
base = 16;
case 'o':
if (base == 10) /* yet unchaged */
base = 8;
case 'd':
case 'i':
case 'u':
str += number(str, va_arg(args, int), base, lead, wid);
break;
}
}
ret:
*str = '\0';
return str - buf;
}
This diff is collapsed.
// See LICENSE for license details.
#include <stdint.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <limits.h>
#include "util.h"
void setStats(int enable)
{
// syscall(SYS_stats, enable, 0, 0);
}
void printstr(const char* s)
{
// syscall(SYS_write, 1, (long)s, strlen(s));
}
// See LICENSE for license details.
#ifndef __UTIL_H
#define __UTIL_H
//--------------------------------------------------------------------------
// Macros
// Set HOST_DEBUG to 1 if you are going to compile this for a host
// machine (ie Athena/Linux) for debug purposes and set HOST_DEBUG
// to 0 if you are compiling with the smips-gcc toolchain.
#ifndef HOST_DEBUG
#define HOST_DEBUG 0
#endif
// Set PREALLOCATE to 1 if you want to preallocate the benchmark
// function before starting stats. If you have instruction/data
// caches and you don't want to count the overhead of misses, then
// you will need to use preallocation.
#ifndef PREALLOCATE
#define PREALLOCATE 0
#endif
// Set SET_STATS to 1 if you want to carve out the piece that actually
// does the computation.
#if HOST_DEBUG
#include <stdio.h>
static void setStats(int enable) {}
#else
extern void setStats(int enable);
#endif
#include <stdint.h>
extern int have_vec;
#define static_assert(cond) switch(0) { case 0: case !!(long)(cond): ; }
static void printArray(const char name[], int n, const int arr[])
{
#if HOST_DEBUG
int i;
printf( " %10s :", name );
for ( i = 0; i < n; i++ )
printf( " %3d ", arr[i] );
printf( "\n" );
#endif
}
static void printDoubleArray(const char name[], int n, const double arr[])
{
#if HOST_DEBUG
int i;
printf( " %10s :", name );
for ( i = 0; i < n; i++ )
printf( " %g ", arr[i] );
printf( "\n" );
#endif
}
static int verify(int n, const volatile int* test, const int* verify)
{
int i;
// Unrolled for faster verification
for (i = 0; i < n/2*2; i+=2)
{
int t0 = test[i], t1 = test[i+1];
int v0 = verify[i], v1 = verify[i+1];
if (t0 != v0) return i+1;
if (t1 != v1) return i+2;
}
if (n % 2 != 0 && test[n-1] != verify[n-1])
return n;
return 0;
}
static int verifyDouble(int n, const volatile double* test, const double* verify)
{
int i;
// Unrolled for faster verification
for (i = 0; i < n/2*2; i+=2)
{
double t0 = test[i], t1 = test[i+1];
double v0 = verify[i], v1 = verify[i+1];
int eq1 = t0 == v0, eq2 = t1 == v1;
if (!(eq1 & eq2)) return i+1+eq1;
}
if (n % 2 != 0 && test[n-1] != verify[n-1])
return n;
return 0;
}
static void __attribute__((noinline)) barrier(int ncores)
{
static volatile int sense;
static volatile int count;
static __thread int threadsense;
__sync_synchronize();
threadsense = !threadsense;
if (__sync_fetch_and_add(&count, 1) == ncores-1)
{
count = 0;
sense = threadsense;
}
else while(sense != threadsense)
;
__sync_synchronize();
}
static uint64_t lfsr(uint64_t x)
{
uint64_t bit = (x ^ (x >> 1)) & 1;
return (x >> 1) | (bit << 62);
}
#ifdef __riscv
#include "encoding.h"
#endif
#define stringify_1(s) #s
#define stringify(s) stringify_1(s)
#define stats(code, iter) do { \
unsigned long _c = -rdcycle(), _i = -rdinstret(); \
code; \
_c += rdcycle(), _i += rdinstret(); \
if (cid == 0) \
printf("\n%s: %ld cycles, %ld.%ld cycles/iter, %ld.%ld CPI\n", \
stringify(code), _c, _c/iter, 10*_c/iter%10, _c/_i, 10*_c/_i%10); \
} while(0)
#endif //__UTIL_H
# and don't touch the rest unless you know what you're doing.
CROSS_COMPILE ?= /opt/gcc-riscv/bin/riscv64-unknown-elf-
CC = $(CROSS_COMPILE)gcc
LD = $(CROSS_COMPILE)ld
OBJDUMP = $(CROSS_COMPILE)objdump
OBJCOPY = $(CROSS_COMPILE)objcopy
SIZE = $(CROSS_COMPILE)size
CFLAGS = -m32 -DSIM -I../common -march=RV32IM -O2
OBJS = dhrystone.o dhrystone_main.o ../../../common/crt0.o ../../../common/irq.o ../../../common/uart.o ../../../common/printf.o ../../../common/vsprintf-xint.o ../common/syscalls.o
LDS = ../../../common/ram2.ld
OUTPUT=dhrystone
$(OUTPUT): $(LDS) $(OBJS)
${CC} -m32 -o $(OUTPUT).elf -nostartfiles $(OBJS) -T $(LDS) ../../../common/_emulate.o -lc
${OBJCOPY} -O binary $(OUTPUT).elf $(OUTPUT).bin
${OBJDUMP} -D $(OUTPUT).elf > disasm.S
$(SIZE) $(OUTPUT).elf
# ../genramvhd -p wrc_simulation_firmware $(OUTPUT).bin > wrc_simulation_firmware_pkg.vhd
../../../genraminit $(OUTPUT).bin 16384 > $(OUTPUT).ram
clean:
rm -f $(OUTPUT).elf $(OUTPUT).bin $(OBJS)
%.o: %.S
${CC} -c -m32 $^ -o $@
\ No newline at end of file
#=======================================================================
# UCB CS250 Makefile fragment for benchmarks
#-----------------------------------------------------------------------
#
# Each benchmark directory should have its own fragment which
# essentially lists what the source files are and how to link them
# into an riscv and/or host executable. All variables should include
# the benchmark name as a prefix so that they are unique.
#
dhrystone_c_src = \
dhrystone_main.c \
dhrystone.c \
syscalls.c \
dhrystone_riscv_src = \
crt.S \
dhrystone_c_objs = $(patsubst %.c, %.o, $(dhrystone_c_src))
dhrystone_riscv_objs = $(patsubst %.S, %.o, $(dhrystone_riscv_src))
dhrystone_host_bin = dhrystone.host
$(dhrystone_host_bin): $(dhrystone_c_src)
$(HOST_COMP) $^ -o $(dhrystone_host_bin)
dhrystone_riscv_bin = dhrystone.riscv
$(dhrystone_riscv_bin): $(dhrystone_c_objs) $(dhrystone_riscv_objs)
$(RISCV_LINK) $(dhrystone_c_objs) $(dhrystone_riscv_objs) \
-o $(dhrystone_riscv_bin) $(RISCV_LINK_OPTS)
junk += $(dhrystone_c_objs) $(dhrystone_riscv_objs) \
$(dhrystone_host_bin) $(dhrystone_riscv_bin)
// See LICENSE for license details.
#pragma GCC optimize ("no-inline")
#include "dhrystone.h"
#ifndef REG
#define REG
/* REG becomes defined as empty */
/* i.e. no register variables */
#else
#undef REG
#define REG register
#endif
extern int Int_Glob;
extern char Ch_1_Glob;
Proc_6 (Enum_Val_Par, Enum_Ref_Par)
/*********************************/
/* executed once */
/* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
Enumeration Enum_Val_Par;
Enumeration *Enum_Ref_Par;
{
*Enum_Ref_Par = Enum_Val_Par;
if (! Func_3 (Enum_Val_Par))
/* then, not executed */
*Enum_Ref_Par = Ident_4;
switch (Enum_Val_Par)
{
case Ident_1:
*Enum_Ref_Par = Ident_1;
break;
case Ident_2:
if (Int_Glob > 100)
/* then */
*Enum_Ref_Par = Ident_1;
else *Enum_Ref_Par = Ident_4;
break;
case Ident_3: /* executed */
*Enum_Ref_Par = Ident_2;
break;
case Ident_4: break;
case Ident_5:
*Enum_Ref_Par = Ident_3;
break;
} /* switch */
} /* Proc_6 */
Proc_7 (Int_1_Par_Val, Int_2_Par_Val, Int_Par_Ref)
/**********************************************/
/* executed three times */
/* first call: Int_1_Par_Val == 2, Int_2_Par_Val == 3, */
/* Int_Par_Ref becomes 7 */
/* second call: Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
/* Int_Par_Ref becomes 17 */
/* third call: Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
/* Int_Par_Ref becomes 18 */
One_Fifty Int_1_Par_Val;
One_Fifty Int_2_Par_Val;
One_Fifty *Int_Par_Ref;
{
One_Fifty Int_Loc;
Int_Loc = Int_1_Par_Val + 2;
*Int_Par_Ref = Int_2_Par_Val + Int_Loc;
} /* Proc_7 */
Proc_8 (Arr_1_Par_Ref, Arr_2_Par_Ref, Int_1_Par_Val, Int_2_Par_Val)
/*********************************************************************/
/* executed once */
/* Int_Par_Val_1 == 3 */
/* Int_Par_Val_2 == 7 */
Arr_1_Dim Arr_1_Par_Ref;
Arr_2_Dim Arr_2_Par_Ref;
int Int_1_Par_Val;
int Int_2_Par_Val;
{
REG One_Fifty Int_Index;
REG One_Fifty Int_Loc;
Int_Loc = Int_1_Par_Val + 5;
Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val;
Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc];
Arr_1_Par_Ref [Int_Loc+30] = Int_Loc;
for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index)
Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc;
Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1;
Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc];
Int_Glob = 5;
} /* Proc_8 */
Enumeration Func_1 (Ch_1_Par_Val, Ch_2_Par_Val)
/*************************************************/
/* executed three times */
/* first call: Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R' */
/* second call: Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C' */
/* third call: Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C' */
Capital_Letter Ch_1_Par_Val;
Capital_Letter Ch_2_Par_Val;
{
Capital_Letter Ch_1_Loc;
Capital_Letter Ch_2_Loc;
Ch_1_Loc = Ch_1_Par_Val;
Ch_2_Loc = Ch_1_Loc;
if (Ch_2_Loc != Ch_2_Par_Val)
/* then, executed */
return (Ident_1);
else /* not executed */
{
Ch_1_Glob = Ch_1_Loc;
return (Ident_2);
}
} /* Func_1 */
Boolean Func_2 (Str_1_Par_Ref, Str_2_Par_Ref)
/*************************************************/
/* executed once */
/* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
/* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
Str_30 Str_1_Par_Ref;
Str_30 Str_2_Par_Ref;
{
REG One_Thirty Int_Loc;
Capital_Letter Ch_Loc;
Int_Loc = 2;
while (Int_Loc <= 2) /* loop body executed once */
if (Func_1 (Str_1_Par_Ref[Int_Loc],
Str_2_Par_Ref[Int_Loc+1]) == Ident_1)
/* then, executed */
{
Ch_Loc = 'A';
Int_Loc += 1;
} /* if, while */
if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
/* then, not executed */
Int_Loc = 7;
if (Ch_Loc == 'R')
/* then, not executed */
return (true);
else /* executed */
{
if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0)
/* then, not executed */
{
Int_Loc += 7;
Int_Glob = Int_Loc;
return (true);
}
else /* executed */
return (false);
} /* if Ch_Loc */
} /* Func_2 */
Boolean Func_3 (Enum_Par_Val)
/***************************/
/* executed once */
/* Enum_Par_Val == Ident_3 */
Enumeration Enum_Par_Val;
{
Enumeration Enum_Loc;
Enum_Loc = Enum_Par_Val;
if (Enum_Loc == Ident_3)
/* then, executed */
return (true);
else /* not executed */
return (false);
} /* Func_3 */
/*void debug_printf(const char* str, ...)
{
}*/
This diff is collapsed.
This diff is collapsed.
Copyright (c) 2012-2015, The Regents of the University of California (Regents).
All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the Regents nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
This diff is collapsed.
// See LICENSE for license details.
#ifndef _HWACHA_XCPT_H
#define _HWACHA_XCPT_H
#include "encoding.h"
#define HWACHA_CAUSE_ILLEGAL_CFG CAUSE_ILLEGAL_INSTRUCTION // AUX: 0=illegal nxpr, 1=illegal nfpr
#define HWACHA_CAUSE_ILLEGAL_INSTRUCTION CAUSE_ILLEGAL_INSTRUCTION // AUX: instruction
#define HWACHA_CAUSE_PRIVILEGED_INSTRUCTION CAUSE_ILLEGAL_INSTRUCTION // AUX: instruction
#define HWACHA_CAUSE_TVEC_ILLEGAL_REGID CAUSE_ILLEGAL_INSTRUCTION // AUX: instruction
#define HWACHA_CAUSE_VF_MISALIGNED_FETCH CAUSE_MISALIGNED_FETCH // AUX: pc
#define HWACHA_CAUSE_VF_FAULT_FETCH CAUSE_FAULT_FETCH // AUX: pc
#define HWACHA_CAUSE_VF_ILLEGAL_INSTRUCTION CAUSE_ILLEGAL_INSTRUCTION // AUX: pc
#define HWACHA_CAUSE_VF_ILLEGAL_REGID CAUSE_ILLEGAL_INSTRUCTION // AUX: pc
#define HWACHA_CAUSE_MISALIGNED_LOAD CAUSE_MISALIGNED_LOAD // AUX: badvaddr
#define HWACHA_CAUSE_MISALIGNED_STORE CAUSE_MISALIGNED_STORE // AUX: badvaddr
#define HWACHA_CAUSE_FAULT_LOAD CAUSE_FAULT_LOAD // AUX: badvaddr
#define HWACHA_CAUSE_FAULT_STORE CAUSE_FAULT_STORE // AUX: badvaddr
#endif
OUTPUT_ARCH( "riscv" )
SECTIONS
{
. = 0x100;
.text.init : { *(.text.init) }
.text : { *(.text) }
.data ALIGN(0x1000) : { *(.data) }
.bss : { *(.bss) }
_end = .;
}
// See LICENSE for license details.
#ifndef _ENV_PHYSICAL_SINGLE_CORE_H
#define _ENV_PHYSICAL_SINGLE_CORE_H
#include "../encoding.h"
#include "../hwacha_xcpt.h"
//-----------------------------------------------------------------------
// Begin Macro
//-----------------------------------------------------------------------
#define RVTEST_RV64U \
.macro init; \
.endm
#define RVTEST_RV64UF \
.macro init; \
RVTEST_FP_ENABLE; \
.endm
#define RVTEST_RV64UV \
.macro init; \
RVTEST_FP_ENABLE; \
RVTEST_VEC_ENABLE; \
.endm
#define RVTEST_RV32U \
.macro init; \
.endm
#define RVTEST_RV32UF \
.macro init; \
RVTEST_FP_ENABLE; \
.endm
#define RVTEST_RV32UV \
.macro init; \
RVTEST_FP_ENABLE; \
RVTEST_VEC_ENABLE; \
.endm
#define RVTEST_RV64M \
.macro init; \
RVTEST_ENABLE_MACHINE; \
.endm
#define RVTEST_RV64S \
.macro init; \
RVTEST_ENABLE_SUPERVISOR; \
.endm
#define RVTEST_RV64SV \
.macro init; \
RVTEST_ENABLE_SUPERVISOR; \
RVTEST_VEC_ENABLE; \
.endm
#define RVTEST_RV32M \
.macro init; \
RVTEST_ENABLE_MACHINE; \
.endm
#define RVTEST_RV32S \
.macro init; \
RVTEST_ENABLE_SUPERVISOR; \
.endm
#ifdef __riscv64
# define CHECK_XLEN csrr a0, mcpuid; bltz a0, 1f; RVTEST_PASS; 1:
#else
# define CHECK_XLEN csrr a0, mcpuid; bgez a0, 1f; RVTEST_PASS; 1:
#endif
#define RVTEST_ENABLE_SUPERVISOR \
li a0, MSTATUS_PRV1 & (MSTATUS_PRV1 >> 1); \
csrs mstatus, a0; \
#define RVTEST_ENABLE_MACHINE \
li a0, MSTATUS_PRV1; \
csrs mstatus, a0; \
#define RVTEST_FP_ENABLE \
li a0, MSTATUS_FS & (MSTATUS_FS >> 1); \
csrs mstatus, a0; \
csrwi fcsr, 0
#define RVTEST_VEC_ENABLE \
li a0, SSTATUS_XS & (SSTATUS_XS >> 1); \
csrs sstatus, a0; \
#define RISCV_MULTICORE_DISABLE \
csrr a0, mhartid; \
1: bnez a0, 1b
#define EXTRA_TVEC_USER
#define EXTRA_TVEC_SUPERVISOR
#define EXTRA_TVEC_HYPERVISOR
#define EXTRA_TVEC_MACHINE
#define EXTRA_INIT
#define EXTRA_INIT_TIMER
#define RVTEST_CODE_BEGIN \
.text;\
.global main; \
main: \
//-----------------------------------------------------------------------
// End Macro
//-----------------------------------------------------------------------
#define RVTEST_CODE_END \
ecall: ecall; \
j ecall
//-----------------------------------------------------------------------
// Pass/Fail Macro
//-----------------------------------------------------------------------
#define TESTNUM x28
#define RVTEST_PASS \
la sp, _fstack; la gp, _gp; jal rv_test_pass; \
la t0, 0x100004; sw t0, 0(t0); j ecall;
#define RVTEST_FAIL \
la sp, _fstack; la gp, _gp; mv a0, TESTNUM; jal rv_test_fail;\
la t0, 0x100004; sw t0, 0(t0); j ecall;
//-----------------------------------------------------------------------
// Data Section Macro
//-----------------------------------------------------------------------
#define EXTRA_DATA
#define RVTEST_DATA_BEGIN EXTRA_DATA .align 4; .global begin_signature; begin_signature:
#define RVTEST_DATA_END .align 4; .global end_signature; end_signature:
#endif
../p/link.ld
\ No newline at end of file
// See LICENSE for license details.
#ifndef _ENV_PHYSICAL_MULTI_CORE_H
#define _ENV_PHYSICAL_MULTI_CORE_H
#include "../p/riscv_test.h"
#undef RISCV_MULTICORE_DISABLE
#define RISCV_MULTICORE_DISABLE
#endif
../p/link.ld
\ No newline at end of file
// See LICENSE for license details.
#ifndef _ENV_PHYSICAL_SINGLE_CORE_TIMER_H
#define _ENV_PHYSICAL_SINGLE_CORE_TIMER_H
#include "../p/riscv_test.h"
#define TIMER_INTERVAL 2
#undef EXTRA_TVEC_USER
#define EXTRA_TVEC_USER \
csrw mscratch, a0; \
csrr a0, mcause; \
bltz a0, _interrupt_handler; \
_skip: \
#undef EXTRA_INIT_TIMER
#define EXTRA_INIT_TIMER \
ENABLE_TIMER_INTERRUPT; \
j _jump_around_interrupt_handler; \
INTERRUPT_HANDLER; \
_jump_around_interrupt_handler: \
#define ENABLE_TIMER_INTERRUPT \
li a0, MIP_MTIP; \
csrs mie, a0; \
csrr a0, mtime; \
addi a0, a0, TIMER_INTERVAL; \
csrw mtimecmp, a0; \
#if SSTATUS_XS != 0xc000
# error
#endif
#define XS_SHIFT 14
#define INTERRUPT_HANDLER \
_interrupt_handler: \
slli a0, a0, 1; \
srli a0, a0, 1; \
add a0, a0, -IRQ_TIMER; \
bnez a0, _skip; \
srl a0, a0, XS_SHIFT; \
andi a0, a0, 3; \
beqz a0, _skip_vector_restore; \
VECTOR_RESTORE; \
_skip_vector_restore: \
csrr a0, mtime; \
addi a0, a0, TIMER_INTERVAL; \
csrw mtimecmp, a0; \
csrr a0, mscratch; \
eret; \
#ifdef __riscv64
#define VECTOR_RESTORE \
_vector_restore: \
la a0,regspill; \
sd a1,0(a0); \
sd a2,8(a0); \
sd a3,16(a0); \
sd a4,24(a0); \
sd a5,32(a0); \
sd a6,40(a0); \
sd a7,48(a0); \
vgetcfg a6; \
vgetvl a7; \
la a0,evac; \
vxcptevac a0; \
vsetcfg a6; \
vsetvl a7,a7; \
vxcpthold a0; \
li a5,0; \
_handler_loop: \
ld a1,0(a0); \
addi a0,a0,8; \
blt a1,x0,_done; \
srli a2,a1,32; \
andi a2,a2,0x1; \
beq a2,x0,_vcnt; \
_vcmd: \
beq a5,x0,_vcmd_skip; \
venqcmd a4,a3; \
_vcmd_skip: \
li a5,1; \
move a4,a1; \
srli a3,a4,36; \
andi a3,a3,0x1; \
_vimm1: \
srli a2,a4,35; \
andi a2,a2,0x1; \
beq a2,x0,_vimm2; \
ld a1,0(a0); \
addi a0,a0,8; \
venqimm1 a1,a3; \
_vimm2: \
srli a2,a4,34; \
andi a2,a2,0x1; \
beq a2,x0,_end; \
ld a1,0(a0); \
addi a0,a0,8; \
venqimm2 a1,a3; \
j _end; \
_vcnt: \
ld a2,0(a0); \
srli a2,a2,31; \
andi a2,a2,0x2; \
or a3,a3,a2; \
venqcnt a1,a3; \
_end: \
j _handler_loop; \
_done: \
beq a5,x0,_done_skip; \
venqcmd a4,a3; \
_done_skip: \
la a0,regspill; \
ld a1,0(a0); \
ld a2,8(a0); \
ld a3,16(a0); \
ld a4,24(a0); \
ld a5,32(a0); \
ld a6,40(a0); \
ld a7,48(a0); \
#else
#define VECTOR_RESTORE
#endif
//-----------------------------------------------------------------------
// Data Section Macro
//-----------------------------------------------------------------------
#undef EXTRA_DATA
#define EXTRA_DATA \
.align 3; \
regspill: \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
.dword 0xdeadbeefcafebabe; \
evac: \
.skip 32768; \
#endif
#include "riscv_test.h"
#ifdef __riscv64
# define STORE sd
# define LOAD ld
# define REGBYTES 8
#else
# define STORE sw
# define LOAD lw
# define REGBYTES 4
#endif
#define STACK_TOP (_end + 131072)
.section ".text.init","ax",@progbits
.align 6
entry_from_user:
mrts
.align 6
entry_from_supervisor:
csrr t0, mcause
addi t0, t0, -CAUSE_SUPERVISOR_ECALL
beqz t0, handle_tohost
j wtf
.align 6
entry_from_hypervisor:
j wtf
.align 6
entry_from_machine:
csrr t0, mcause
addi t0, t0, -CAUSE_MACHINE_ECALL
beqz t0, handle_tohost
j wtf
.align 6
power_on_reset:
la sp, STACK_TOP - SIZEOF_TRAPFRAME_T
csrw mscratch, sp
li a1, 1337
la a0, userstart
j vm_boot
.globl pop_tf
pop_tf:
csrc sstatus, SSTATUS_IE
LOAD t0,33*REGBYTES(a0)
csrw sepc,t0
LOAD x1,1*REGBYTES(a0)
LOAD x2,2*REGBYTES(a0)
LOAD x3,3*REGBYTES(a0)
LOAD x4,4*REGBYTES(a0)
LOAD x5,5*REGBYTES(a0)
LOAD x6,6*REGBYTES(a0)
LOAD x7,7*REGBYTES(a0)
LOAD x8,8*REGBYTES(a0)
LOAD x9,9*REGBYTES(a0)
LOAD x11,11*REGBYTES(a0)
LOAD x12,12*REGBYTES(a0)
LOAD x13,13*REGBYTES(a0)
LOAD x14,14*REGBYTES(a0)
LOAD x15,15*REGBYTES(a0)
LOAD x16,16*REGBYTES(a0)
LOAD x17,17*REGBYTES(a0)
LOAD x18,18*REGBYTES(a0)
LOAD x19,19*REGBYTES(a0)
LOAD x20,20*REGBYTES(a0)
LOAD x21,21*REGBYTES(a0)
LOAD x22,22*REGBYTES(a0)
LOAD x23,23*REGBYTES(a0)
LOAD x24,24*REGBYTES(a0)
LOAD x25,25*REGBYTES(a0)
LOAD x26,26*REGBYTES(a0)
LOAD x27,27*REGBYTES(a0)
LOAD x28,28*REGBYTES(a0)
LOAD x29,29*REGBYTES(a0)
LOAD x30,30*REGBYTES(a0)
LOAD x31,31*REGBYTES(a0)
LOAD a0,10*REGBYTES(a0)
eret
.global trap_entry
trap_entry:
csrrw sp, sscratch, sp
# save gprs
STORE x1,1*REGBYTES(sp)
STORE x3,3*REGBYTES(sp)
STORE x4,4*REGBYTES(sp)
STORE x5,5*REGBYTES(sp)
STORE x6,6*REGBYTES(sp)
STORE x7,7*REGBYTES(sp)
STORE x8,8*REGBYTES(sp)
STORE x9,9*REGBYTES(sp)
STORE x10,10*REGBYTES(sp)
STORE x11,11*REGBYTES(sp)
STORE x12,12*REGBYTES(sp)
STORE x13,13*REGBYTES(sp)
STORE x14,14*REGBYTES(sp)
STORE x15,15*REGBYTES(sp)
STORE x16,16*REGBYTES(sp)
STORE x17,17*REGBYTES(sp)
STORE x18,18*REGBYTES(sp)
STORE x19,19*REGBYTES(sp)
STORE x20,20*REGBYTES(sp)
STORE x21,21*REGBYTES(sp)
STORE x22,22*REGBYTES(sp)
STORE x23,23*REGBYTES(sp)
STORE x24,24*REGBYTES(sp)
STORE x25,25*REGBYTES(sp)
STORE x26,26*REGBYTES(sp)
STORE x27,27*REGBYTES(sp)
STORE x28,28*REGBYTES(sp)
STORE x29,29*REGBYTES(sp)
STORE x30,30*REGBYTES(sp)
STORE x31,31*REGBYTES(sp)
csrrw t0,sscratch,sp
STORE t0,2*REGBYTES(sp)
# get sr, epc, badvaddr, cause
csrr t0,sstatus
STORE t0,32*REGBYTES(sp)
csrr t0,sepc
STORE t0,33*REGBYTES(sp)
csrr t0,sbadaddr
STORE t0,34*REGBYTES(sp)
csrr t0,scause
STORE t0,35*REGBYTES(sp)
# get hwacha cause if IRQ_COP
# vxcptcause clears hwacha interrupt bit
bgez t0,1f
slli t0,t0,1 # clearing MSB of cause
srli t0,t0,1 # clearing MSB of cause
li t1,IRQ_COP
bne t0,t1,1f
vxcptcause t0
STORE t0,36*REGBYTES(sp)
1:
move a0, sp
csrr t0, sstatus
li t1, SSTATUS_XS
and t0, t0, t1
beqz t0, 2f
# disable saving vector state for now
addi t0,sp,SIZEOF_TRAPFRAME_T_SCALAR
vgetcfg x4
STORE x4,0*REGBYTES(t0)
vgetvl x4
STORE x4,1*REGBYTES(t0)
addi t0,t0,2*REGBYTES
vxcptevac t0
2:j handle_trap
.global do_tohost
do_tohost:
ecall
ret
handle_tohost:
1:csrrw t0, mtohost, a0
bnez t0, 1b
1:csrrw t0, mfromhost, x0
bnez t0, 1b
csrr t0, mepc
addi t0, t0, 4
csrw mepc, t0
eret
wtf:
li a0, 841
1:csrw mtohost, a0
j 1b
../p/link.ld
\ No newline at end of file
// See LICENSE for license details.
#ifndef _ENV_VIRTUAL_SINGLE_CORE_H
#define _ENV_VIRTUAL_SINGLE_CORE_H
#include "../p/riscv_test.h"
//-----------------------------------------------------------------------
// Begin Macro
//-----------------------------------------------------------------------
#undef RVTEST_FP_ENABLE
#define RVTEST_FP_ENABLE fssr x0
#undef RVTEST_RV64UV
#define RVTEST_RV64UV \
RVTEST_RV64UF
#undef RVTEST_CODE_BEGIN
#define RVTEST_CODE_BEGIN \
.text; \
.align 13; \
.global userstart; \
userstart: \
init
//-----------------------------------------------------------------------
// Pass/Fail Macro
//-----------------------------------------------------------------------
#undef RVTEST_PASS
#define RVTEST_PASS li a0, 1; scall
#undef RVTEST_FAIL
#define RVTEST_FAIL sll a0, TESTNUM, 1; 1:beqz a0, 1b; or a0, a0, 1; scall;
//-----------------------------------------------------------------------
// Data Section Macro
//-----------------------------------------------------------------------
#undef RVTEST_DATA_BEGIN
#define RVTEST_DATA_BEGIN
#undef RVTEST_DATA_END
#define RVTEST_DATA_END
//-----------------------------------------------------------------------
// Supervisor mode definitions and macros
//-----------------------------------------------------------------------
#define dword_bit_cmd(dw) ((dw >> 32) & 0x1)
#define dword_bit_cnt(dw) (!dword_bit_cmd(dw))
#define dword_bit_imm1(dw) ((dw >> 35) & 0x1)
#define dword_bit_imm2(dw) ((dw >> 34) & 0x1)
#define dword_bit_pf(dw) ((dw >> 36) & 0x1)
#define fence() ({ \
asm volatile ("fence" ::: "memory"); })
#define vxcptkill() ({ \
asm volatile ("vxcptkill"); })
#define vxcpthold(addr) ({ \
asm volatile ("vxcpthold %0" : : "r"(addr)); })
#define venqcmd(bits, pf) ({ \
asm volatile ("venqcmd %0,%1" : : "r"(bits), "r"(pf)); })
#define venqimm1(bits, pf) ({ \
asm volatile ("venqimm1 %0,%1" : : "r"(bits), "r"(pf)); })
#define venqimm2(bits, pf) ({ \
asm volatile ("venqimm2 %0,%1" : : "r"(bits), "r"(pf)); })
#define venqcnt(bits, pf) ({ \
asm volatile ("venqcnt %0,%1" :: "r"(bits), "r"(pf)); })
#define MAX_TEST_PAGES 63 // this must be the period of the LFSR below
#define LFSR_NEXT(x) (((((x)^((x)>>1)) & 1) << 5) | ((x) >> 1))
#define PGSHIFT 12
#define PGSIZE (1UL << PGSHIFT)
#define SIZEOF_TRAPFRAME_T 20776
#define SIZEOF_TRAPFRAME_T_SCALAR 296
#ifndef __ASSEMBLER__
static inline void vsetcfg(long cfg)
{
asm volatile ("vsetcfg %0" : : "r"(cfg));
}
static inline void vsetvl(long vl)
{
long __tmp;
asm volatile ("vsetvl %0,%1" : "=r"(__tmp) : "r"(vl));
}
static inline long vgetcfg()
{
int cfg;
asm volatile ("vgetcfg %0" : "=r"(cfg) :);
return cfg;
}
static inline long vgetvl()
{
int vl;
asm volatile ("vgetvl %0" : "=r"(vl) :);
}
static inline long vxcptaux()
{
long aux;
asm volatile ("vxcptaux %0" : "=r"(aux) :);
return aux;
}
static inline long vxcptcause()
{
long cause;
asm volatile ("vxcptcause %0" : "=r"(cause) :);
return cause;
}
static inline void vxcptrestore(long* mem)
{
asm volatile("vxcptrestore %0" : : "r"(mem) : "memory");
}
static inline void vxcptevac(long* mem)
{
asm volatile ("vxcptevac %0" : : "r"(mem));
}
typedef unsigned long pte_t;
#define LEVELS (sizeof(pte_t) == sizeof(uint64_t) ? 3 : 2)
#define PTIDXBITS (PGSHIFT - (sizeof(pte_t) == 8 ? 3 : 2))
#define VPN_BITS (PTIDXBITS * LEVELS)
#define VA_BITS (VPN_BITS + PGSHIFT)
#define PTES_PER_PT (1UL << RISCV_PGLEVEL_BITS)
#define MEGAPAGE_SIZE (PTES_PER_PT * PGSIZE)
typedef struct
{
long gpr[32];
long sr;
long epc;
long badvaddr;
long cause;
long hwacha_cause;
long hwacha_opaque[2560];
} trapframe_t;
#endif
#endif
// See LICENSE for license details.
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include "riscv_test.h"
void trap_entry();
void pop_tf(trapframe_t*);
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);
}
static void cputstring(const char* s)
{
while (*s)
cputchar(*s++);
}
static void terminate(int code)
{
do_tohost(code);
while (1);
}
#define stringify1(x) #x
#define stringify(x) stringify1(x)
#define assert(x) do { \
if (x) break; \
cputstring("Assertion failed: " stringify(x) "\n"); \
terminate(3); \
} while(0)
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)));
pte_t kernel_l3pt[PTES_PER_PT] __attribute__((aligned(PGSIZE)));
freelist_t user_mapping[MAX_TEST_PAGES];
freelist_t freelist_nodes[MAX_TEST_PAGES];
freelist_t *freelist_head, *freelist_tail;
void printhex(uint64_t x)
{
char str[17];
for (int i = 0; i < 16; i++)
{
str[15-i] = (x & 0xF) + ((x & 0xF) < 10 ? '0' : 'a'-10);
x >>= 4;
}
str[16] = 0;
cputstring(str);
}
void evict(unsigned long addr)
{
assert(addr >= PGSIZE && addr < MAX_TEST_PAGES * PGSIZE);
addr = addr/PGSIZE*PGSIZE;
freelist_t* node = &user_mapping[addr/PGSIZE];
if (node->addr)
{
// check referenced and dirty bits
assert(user_l3pt[addr/PGSIZE] & PTE_R);
if (memcmp((void*)addr, pa2kva(addr), PGSIZE)) {
assert(user_l3pt[addr/PGSIZE] & PTE_D);
memcpy((void*)addr, pa2kva(addr), PGSIZE);
}
user_mapping[addr/PGSIZE].addr = 0;
if (freelist_tail == 0)
freelist_head = freelist_tail = node;
else
{
freelist_tail->next = node;
freelist_tail = node;
}
}
}
void handle_fault(unsigned long addr)
{
assert(addr >= PGSIZE && addr < MAX_TEST_PAGES * PGSIZE);
addr = addr/PGSIZE*PGSIZE;
freelist_t* node = freelist_head;
assert(node);
freelist_head = node->next;
if (freelist_head == freelist_tail)
freelist_tail = 0;
user_l3pt[addr/PGSIZE] = (node->addr >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V | PTE_TYPE_URWX_SRW;
asm volatile ("sfence.vm");
assert(user_mapping[addr/PGSIZE].addr == 0);
user_mapping[addr/PGSIZE] = *node;
memcpy((void*)addr, pa2kva(addr), PGSIZE);
__builtin___clear_cache(0,0);
}
static void do_vxcptrestore(long* where)
{
vsetcfg(where[0]);
vsetvl(where[1]);
vxcpthold(&where[2]);
int idx = 2;
long dword, cmd, pf;
int first = 1;
while (1)
{
dword = where[idx++];
if (dword < 0) break;
if (dword_bit_cnt(dword))
{
venqcnt(dword, pf | (dword_bit_cmd(where[idx]) << 1));
}
else
{
if (!first)
{
venqcmd(cmd, pf);
}
first = 0;
cmd = dword;
pf = dword_bit_pf(cmd);
if (dword_bit_imm1(cmd))
{
venqimm1(where[idx++], pf);
}
if (dword_bit_imm2(cmd))
{
venqimm2(where[idx++], pf);
}
}
}
if (!first)
{
venqcmd(cmd, pf);
}
}
static void restore_vector(trapframe_t* tf)
{
do_vxcptrestore(tf->hwacha_opaque);
}
void handle_trap(trapframe_t* tf)
{
if (tf->cause == CAUSE_USER_ECALL)
{
int n = tf->gpr[10];
for (long i = 1; i < MAX_TEST_PAGES; i++)
evict(i*PGSIZE);
terminate(n);
}
else if (tf->cause == CAUSE_FAULT_FETCH)
handle_fault(tf->epc);
else if (tf->cause == CAUSE_ILLEGAL_INSTRUCTION)
{
assert(tf->epc % 4 == 0);
int* fssr;
asm ("jal %0, 1f; fssr x0; 1:" : "=r"(fssr));
if (*(int*)tf->epc == *fssr)
terminate(1); // FP test on non-FP hardware. "succeed."
else
assert(!"illegal instruction");
tf->epc += 4;
}
else if (tf->cause == CAUSE_FAULT_LOAD || tf->cause == CAUSE_FAULT_STORE)
handle_fault(tf->badvaddr);
else if ((long)tf->cause < 0 && (uint8_t)tf->cause == IRQ_COP)
{
if (tf->hwacha_cause == HWACHA_CAUSE_VF_FAULT_FETCH ||
tf->hwacha_cause == HWACHA_CAUSE_FAULT_LOAD ||
tf->hwacha_cause == HWACHA_CAUSE_FAULT_STORE)
{
long badvaddr = vxcptaux();
handle_fault(badvaddr);
}
else
assert(!"unexpected interrupt");
}
else
assert(!"unexpected exception");
out:
if (!(tf->sr & SSTATUS_PS) && (tf->sr & SSTATUS_XS))
restore_vector(tf);
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)
{
if (read_csr(mhartid) > 0)
coherence_torture();
assert(SIZEOF_TRAPFRAME_T == sizeof(trapframe_t));
#if MAX_TEST_PAGES > PTES_PER_PT
# error
#endif
// 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;
user_l2pt[0] = ((pte_t)user_l3pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V | PTE_TYPE_TABLE;
write_csr(sptbr, l1pt);
// set up supervisor trap handling
write_csr(stvec, pa2kva(trap_entry));
write_csr(sscratch, pa2kva(read_csr(mscratch)));
// interrupts on; FPU on; accelerator on
set_csr(mstatus, MSTATUS_IE1 | MSTATUS_FS | MSTATUS_XS);
// virtual memory off; set user mode upon eret
clear_csr(mstatus, MSTATUS_VM | MSTATUS_PRV1);
// virtual memory to Sv39
set_csr(mstatus, (long)VM_SV39 << __builtin_ctzl(MSTATUS_VM));
seed = 1 + (seed % MAX_TEST_PAGES);
freelist_head = pa2kva((void*)&freelist_nodes[0]);
freelist_tail = pa2kva(&freelist_nodes[MAX_TEST_PAGES-1]);
for (long i = 0; i < MAX_TEST_PAGES; i++)
{
freelist_nodes[i].addr = (MAX_TEST_PAGES + seed)*PGSIZE;
freelist_nodes[i].next = pa2kva(&freelist_nodes[i+1]);
seed = LFSR_NEXT(seed);
kernel_l3pt[i] = (i << PTE_PPN_SHIFT) | PTE_V | PTE_TYPE_SRWX;
}
freelist_nodes[MAX_TEST_PAGES-1].next = 0;
trapframe_t tf;
memset(&tf, 0, sizeof(tf));
write_csr(mepc, test_addr);
pop_tf(&tf);
}
#=======================================================================
# Makefile for riscv-tests/isa
#-----------------------------------------------------------------------
isa_src_dir := .
#include $(isa_src_dir)/rv64ui/Makefrag
#include $(isa_src_dir)/rv64uf/Makefrag
#include $(isa_src_dir)/rv64uv/Makefrag
#include $(isa_src_dir)/rv64si/Makefrag
#include $(isa_src_dir)/rv64sv/Makefrag
#include $(isa_src_dir)/rv64mi/Makefrag
include $(isa_src_dir)/rv32ui/Makefrag
#include $(isa_src_dir)/rv32si/Makefrag
include $(isa_src_dir)/rv32mi/Makefrag
default: all
#--------------------------------------------------------------------
# Build rules
#--------------------------------------------------------------------
RISCV_PREFIX=riscv64-unknown-elf-
RISCV_GCC = $(RISCV_PREFIX)gcc
ENTROPY = -DENTROPY=$(shell echo $$$$)
RISCV_GCC_OPTS = $(ENTROPY) -mcmodel=medany -nostartfiles -fvisibility=hidden -Wa,-march=RV32IM -DSIM -I../../common
RISCV_OBJDUMP = $(RISCV_PREFIX)objdump --disassemble-all --disassemble-zeroes --section=.text --section=.text.startup --section=.text.init --section=.data
RISCV_SIM = spike --extension=hwacha
COMMON_SRCS = ../../common/crt0.S ../../common/irq.S ../../common/_emulate.o ../../common/test-common.c ../../common/printf.c ../../common/uart.c ../../common/vsprintf-xint.c
vpath %.S $(isa_src_dir)
#------------------------------------------------------------
# Build assembly tests
%.ram: %
riscv64-unknown-elf-objcopy -O binary $< tmp.bin
../../genraminit tmp.bin 16384 > $@
%.dump: %
$(RISCV_OBJDUMP) $< > $@
%.out: %
$(RISCV_SIM) $< 2> $@
%.out32: %
$(RISCV_SIM) --isa=RV32 $< 2> $@
define compile_template
$$($(1)_p_tests): $(1)-p-%: $(1)/%.S
$$(RISCV_GCC) $(2) $$(RISCV_GCC_OPTS) -I$(isa_src_dir)/../env/p -I$(isa_src_dir)/macros/scalar $(COMMON_SRCS) -T ../../common/ram2.ld $$< -o $$@
$(1)_tests += $$($(1)_p_tests)
$(1)_tests_dump = $$(addsuffix .dump, $$($(1)_tests))
$(1)_tests_ram = $$(addsuffix .ram, $$($(1)_tests))
$(1): $$($(1)_tests_dump) $$($(1)_tests_ram)
.PHONY: $(1)
tests += $$($(1)_tests)
endef
$(eval $(call compile_template,rv32ui,-m32))
tests_dump = $(addsuffix .dump, $(tests))
tests_ram = $(addsuffix .ram, $(tests))
tests_out = $(addsuffix .out, $(spike_tests))
tests32_out = $(addsuffix .out32, $(spike32_tests))
run: $(tests_out) $(tests32_out)
echo; perl -ne 'print " [$$1] $$ARGV \t$$2\n" if /\*{3}(.{8})\*{3}(.*)/' \
$(tests_out) $(tests32_out); echo;
junk += $(tests) $(tests_dump) $(tests_ram) $(tests_out) $(tests32_out)
#------------------------------------------------------------
# Default
all: $(tests_dump) $(tests_ram)
#------------------------------------------------------------
# Clean up
clean:
rm -rf $(junk)
This diff is collapsed.
This diff is collapsed.
#=======================================================================
# Makefrag for rv32mi tests
#-----------------------------------------------------------------------
rv32mi_sc_tests = \
csr
rv32mi_mc_tests =
rv32mi_p_tests = $(addprefix rv32mi-p-, $(rv32mi_sc_tests))
rv32mi_pm_tests = $(addprefix rv32mi-pm-, $(rv32mi_mc_tests))
spike32_tests += $(rv32mi_p_tests) $(rv32mi_pm_tests)
# See LICENSE for license details.
#include "riscv_test.h"
#undef RVTEST_RV64S
#define RVTEST_RV64S RVTEST_RV32M
#define __MACHINE_MODE
#include "../rv64si/csr.S"
# See LICENSE for license details.
#include "riscv_test.h"
#undef RVTEST_RV64S
#define RVTEST_RV64S RVTEST_RV32M
#define __MACHINE_MODE
#include "../rv64si/illegal.S"
# See LICENSE for license details.
#include "riscv_test.h"
#undef RVTEST_RV64M
#define RVTEST_RV64M RVTEST_RV32M
#include "../rv64mi/ipi.S"
# See LICENSE for license details.
#include "riscv_test.h"
#undef RVTEST_RV64S
#define RVTEST_RV64S RVTEST_RV32M
#define __MACHINE_MODE
#include "../rv64si/ma_addr.S"
# See LICENSE for license details.
#include "riscv_test.h"
#undef RVTEST_RV64S
#define RVTEST_RV64S RVTEST_RV32M
#define __MACHINE_MODE
#include "../rv64si/ma_fetch.S"
# See LICENSE for license details.
#include "riscv_test.h"
#undef RVTEST_RV64S
#define RVTEST_RV64S RVTEST_RV32M
#define __MACHINE_MODE
#include "../rv64si/sbreak.S"
# See LICENSE for license details.
#include "riscv_test.h"
#undef RVTEST_RV64S
#define RVTEST_RV64S RVTEST_RV32M
#define __MACHINE_MODE
#include "../rv64si/scall.S"
# See LICENSE for license details.
#include "riscv_test.h"
#undef RVTEST_RV64M
#define RVTEST_RV64M RVTEST_RV32M
#include "../rv64mi/timer.S"
#=======================================================================
# Makefrag for rv32si tests
#-----------------------------------------------------------------------
rv32si_sc_tests = \
csr \
shamt \
ma_fetch \
illegal \
scall \
sbreak \
ma_addr \
rv32si_p_tests = $(addprefix rv32si-p-, $(rv32si_sc_tests))
spike32_tests += $(rv32si_p_tests)
# See LICENSE for license details.
#include "riscv_test.h"
#undef RVTEST_RV64S
#define RVTEST_RV64S RVTEST_RV32S
#include "../rv64si/csr.S"
# See LICENSE for license details.
#include "riscv_test.h"
#undef RVTEST_RV64S
#define RVTEST_RV64S RVTEST_RV32S
#include "../rv64si/illegal.S"
# See LICENSE for license details.
#include "riscv_test.h"
#undef RVTEST_RV64S
#define RVTEST_RV64S RVTEST_RV32S
#include "../rv64si/ma_addr.S"
# See LICENSE for license details.
#include "riscv_test.h"
#undef RVTEST_RV64S
#define RVTEST_RV64S RVTEST_RV32S
#include "../rv64si/ma_fetch.S"
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment