saving current changes
This commit is contained in:
5013
Tests/isa/Baremetal-C-programs/encoding.h
Normal file
5013
Tests/isa/Baremetal-C-programs/encoding.h
Normal file
File diff suppressed because it is too large
Load Diff
164
Tests/isa/Baremetal-C-programs/entry.S
Normal file
164
Tests/isa/Baremetal-C-programs/entry.S
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
#include "riscv_test.h"
|
||||||
|
|
||||||
|
#if __riscv_xlen == 64
|
||||||
|
# define STORE sd
|
||||||
|
# define LOAD ld
|
||||||
|
# define REGBYTES 8
|
||||||
|
#else
|
||||||
|
# define STORE sw
|
||||||
|
# define LOAD lw
|
||||||
|
# define REGBYTES 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define STACK_TOP (_end + RISCV_PGSIZE * 4)
|
||||||
|
|
||||||
|
.section ".text.init","ax",@progbits
|
||||||
|
.globl _start
|
||||||
|
.align 2
|
||||||
|
_start:
|
||||||
|
j handle_reset
|
||||||
|
|
||||||
|
/* NMI vector */
|
||||||
|
.align 2
|
||||||
|
nmi_vector:
|
||||||
|
j wtf
|
||||||
|
|
||||||
|
.align 2
|
||||||
|
trap_vector:
|
||||||
|
j wtf
|
||||||
|
|
||||||
|
handle_reset:
|
||||||
|
li x1, 0
|
||||||
|
li x2, 0
|
||||||
|
li x3, 0
|
||||||
|
li x4, 0
|
||||||
|
li x5, 0
|
||||||
|
li x6, 0
|
||||||
|
li x7, 0
|
||||||
|
li x8, 0
|
||||||
|
li x9, 0
|
||||||
|
li x10, 0
|
||||||
|
li x11, 0
|
||||||
|
li x12, 0
|
||||||
|
li x13, 0
|
||||||
|
li x14, 0
|
||||||
|
li x15, 0
|
||||||
|
li x16, 0
|
||||||
|
li x17, 0
|
||||||
|
li x18, 0
|
||||||
|
li x19, 0
|
||||||
|
li x20, 0
|
||||||
|
li x21, 0
|
||||||
|
li x22, 0
|
||||||
|
li x23, 0
|
||||||
|
li x24, 0
|
||||||
|
li x25, 0
|
||||||
|
li x26, 0
|
||||||
|
li x27, 0
|
||||||
|
li x28, 0
|
||||||
|
li x29, 0
|
||||||
|
li x30, 0
|
||||||
|
li x31, 0
|
||||||
|
|
||||||
|
INIT_RNMI
|
||||||
|
|
||||||
|
la t0, trap_vector
|
||||||
|
csrw mtvec, t0
|
||||||
|
la sp, STACK_TOP - SIZEOF_TRAPFRAME_T
|
||||||
|
csrr t0, mhartid
|
||||||
|
slli t0, t0, 12
|
||||||
|
add sp, sp, t0
|
||||||
|
csrw mscratch, sp
|
||||||
|
call extra_boot
|
||||||
|
la a0, userstart
|
||||||
|
j vm_boot
|
||||||
|
|
||||||
|
.globl pop_tf
|
||||||
|
pop_tf:
|
||||||
|
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)
|
||||||
|
sret
|
||||||
|
|
||||||
|
.global trap_entry
|
||||||
|
.align 2
|
||||||
|
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,stval
|
||||||
|
STORE t0,34*REGBYTES(sp)
|
||||||
|
csrr t0,scause
|
||||||
|
STORE t0,35*REGBYTES(sp)
|
||||||
|
|
||||||
|
move a0, sp
|
||||||
|
j handle_trap
|
||||||
16
Tests/isa/Baremetal-C-programs/link.ld
Normal file
16
Tests/isa/Baremetal-C-programs/link.ld
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
OUTPUT_ARCH( "riscv" )
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x80000000;
|
||||||
|
.text.init : { *(.text.init) }
|
||||||
|
. = ALIGN(0x1000);
|
||||||
|
.tohost : { *(.tohost) }
|
||||||
|
. = ALIGN(0x1000);
|
||||||
|
.text : { *(.text) }
|
||||||
|
. = ALIGN(0x1000);
|
||||||
|
.data : { *(.data) }
|
||||||
|
.bss : { *(.bss) }
|
||||||
|
_end = .;
|
||||||
|
}
|
||||||
98
Tests/isa/Baremetal-C-programs/riscv_test.h
Normal file
98
Tests/isa/Baremetal-C-programs/riscv_test.h
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
// 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_VECTOR_ENABLE
|
||||||
|
#define RVTEST_VECTOR_ENABLE \
|
||||||
|
csrwi fcsr, 0; \
|
||||||
|
csrwi vcsr, 0;
|
||||||
|
|
||||||
|
#undef RVTEST_ZVE32X_ENABLE
|
||||||
|
#define RVTEST_ZVE32X_ENABLE \
|
||||||
|
csrwi vcsr, 0;
|
||||||
|
|
||||||
|
#undef RVTEST_CODE_BEGIN
|
||||||
|
#define RVTEST_CODE_BEGIN \
|
||||||
|
.text; \
|
||||||
|
.global extra_boot; \
|
||||||
|
extra_boot: \
|
||||||
|
EXTRA_INIT \
|
||||||
|
ret; \
|
||||||
|
.global trap_filter; \
|
||||||
|
trap_filter: \
|
||||||
|
FILTER_TRAP \
|
||||||
|
li a0, 0; \
|
||||||
|
ret; \
|
||||||
|
.global pf_filter; \
|
||||||
|
pf_filter: \
|
||||||
|
FILTER_PAGE_FAULT \
|
||||||
|
li a0, 0; \
|
||||||
|
ret; \
|
||||||
|
.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_END
|
||||||
|
#define RVTEST_DATA_END
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
// Supervisor mode definitions and macros
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef LFSR_BITS
|
||||||
|
#define LFSR_BITS 6
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MAX_TEST_PAGES ((1 << LFSR_BITS)-1) // this must be the period of the LFSR below
|
||||||
|
#define LFSR_NEXT(x) (((((x)^((x)>>1)) & 1) << (LFSR_BITS-1)) | ((x) >> 1))
|
||||||
|
|
||||||
|
#define PGSHIFT 12
|
||||||
|
#define PGSIZE (1UL << PGSHIFT)
|
||||||
|
|
||||||
|
#define SIZEOF_TRAPFRAME_T ((__riscv_xlen / 8) * 36)
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLER__
|
||||||
|
|
||||||
|
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;
|
||||||
|
} trapframe_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
295
Tests/isa/Baremetal-C-programs/riscv_test_p.h
Normal file
295
Tests/isa/Baremetal-C-programs/riscv_test_p.h
Normal file
@@ -0,0 +1,295 @@
|
|||||||
|
// See LICENSE for license details.
|
||||||
|
|
||||||
|
#ifndef _ENV_PHYSICAL_SINGLE_CORE_H
|
||||||
|
#define _ENV_PHYSICAL_SINGLE_CORE_H
|
||||||
|
|
||||||
|
#include "../encoding.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
// Begin Macro
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define RVTEST_RV64U \
|
||||||
|
.macro init; \
|
||||||
|
.endm
|
||||||
|
|
||||||
|
#define RVTEST_RV64UF \
|
||||||
|
.macro init; \
|
||||||
|
RVTEST_FP_ENABLE; \
|
||||||
|
.endm
|
||||||
|
|
||||||
|
#define RVTEST_RV64UV \
|
||||||
|
.macro init; \
|
||||||
|
RVTEST_VECTOR_ENABLE; \
|
||||||
|
.endm
|
||||||
|
|
||||||
|
#define RVTEST_RV64UVX \
|
||||||
|
.macro init; \
|
||||||
|
RVTEST_ZVE32X_ENABLE; \
|
||||||
|
.endm
|
||||||
|
|
||||||
|
#define RVTEST_RV32U \
|
||||||
|
.macro init; \
|
||||||
|
.endm
|
||||||
|
|
||||||
|
#define RVTEST_RV32UF \
|
||||||
|
.macro init; \
|
||||||
|
RVTEST_FP_ENABLE; \
|
||||||
|
.endm
|
||||||
|
|
||||||
|
#define RVTEST_RV32UV \
|
||||||
|
.macro init; \
|
||||||
|
RVTEST_VECTOR_ENABLE; \
|
||||||
|
.endm
|
||||||
|
|
||||||
|
#define RVTEST_RV32UVX \
|
||||||
|
.macro init; \
|
||||||
|
RVTEST_ZVE32X_ENABLE; \
|
||||||
|
.endm
|
||||||
|
|
||||||
|
#define RVTEST_RV64M \
|
||||||
|
.macro init; \
|
||||||
|
RVTEST_ENABLE_MACHINE; \
|
||||||
|
.endm
|
||||||
|
|
||||||
|
#define RVTEST_RV64S \
|
||||||
|
.macro init; \
|
||||||
|
RVTEST_ENABLE_SUPERVISOR; \
|
||||||
|
.endm
|
||||||
|
|
||||||
|
#define RVTEST_RV32M \
|
||||||
|
.macro init; \
|
||||||
|
RVTEST_ENABLE_MACHINE; \
|
||||||
|
.endm
|
||||||
|
|
||||||
|
#define RVTEST_RV32S \
|
||||||
|
.macro init; \
|
||||||
|
RVTEST_ENABLE_SUPERVISOR; \
|
||||||
|
.endm
|
||||||
|
|
||||||
|
#if __riscv_xlen == 64
|
||||||
|
# define CHECK_XLEN li a0, 1; slli a0, a0, 31; bgez a0, 1f; RVTEST_PASS; 1:
|
||||||
|
#else
|
||||||
|
# define CHECK_XLEN li a0, 1; slli a0, a0, 31; bltz a0, 1f; RVTEST_PASS; 1:
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define INIT_XREG \
|
||||||
|
li x1, 0; \
|
||||||
|
li x2, 0; \
|
||||||
|
li x3, 0; \
|
||||||
|
li x4, 0; \
|
||||||
|
li x5, 0; \
|
||||||
|
li x6, 0; \
|
||||||
|
li x7, 0; \
|
||||||
|
li x8, 0; \
|
||||||
|
li x9, 0; \
|
||||||
|
li x10, 0; \
|
||||||
|
li x11, 0; \
|
||||||
|
li x12, 0; \
|
||||||
|
li x13, 0; \
|
||||||
|
li x14, 0; \
|
||||||
|
li x15, 0; \
|
||||||
|
li x16, 0; \
|
||||||
|
li x17, 0; \
|
||||||
|
li x18, 0; \
|
||||||
|
li x19, 0; \
|
||||||
|
li x20, 0; \
|
||||||
|
li x21, 0; \
|
||||||
|
li x22, 0; \
|
||||||
|
li x23, 0; \
|
||||||
|
li x24, 0; \
|
||||||
|
li x25, 0; \
|
||||||
|
li x26, 0; \
|
||||||
|
li x27, 0; \
|
||||||
|
li x28, 0; \
|
||||||
|
li x29, 0; \
|
||||||
|
li x30, 0; \
|
||||||
|
li x31, 0;
|
||||||
|
|
||||||
|
#define INIT_PMP \
|
||||||
|
la t0, 1f; \
|
||||||
|
csrw mtvec, t0; \
|
||||||
|
/* Set up a PMP to permit all accesses */ \
|
||||||
|
li t0, (1 << (31 + (__riscv_xlen / 64) * (53 - 31))) - 1; \
|
||||||
|
csrw pmpaddr0, t0; \
|
||||||
|
li t0, PMP_NAPOT | PMP_R | PMP_W | PMP_X; \
|
||||||
|
csrw pmpcfg0, t0; \
|
||||||
|
.align 2; \
|
||||||
|
1:
|
||||||
|
|
||||||
|
#define INIT_RNMI \
|
||||||
|
la t0, 1f; \
|
||||||
|
csrw mtvec, t0; \
|
||||||
|
csrwi CSR_MNSTATUS, MNSTATUS_NMIE; \
|
||||||
|
.align 2; \
|
||||||
|
1:
|
||||||
|
|
||||||
|
#define INIT_SATP \
|
||||||
|
la t0, 1f; \
|
||||||
|
csrw mtvec, t0; \
|
||||||
|
csrwi satp, 0; \
|
||||||
|
.align 2; \
|
||||||
|
1:
|
||||||
|
|
||||||
|
#define DELEGATE_NO_TRAPS \
|
||||||
|
csrwi mie, 0; \
|
||||||
|
la t0, 1f; \
|
||||||
|
csrw mtvec, t0; \
|
||||||
|
csrwi medeleg, 0; \
|
||||||
|
csrwi mideleg, 0; \
|
||||||
|
.align 2; \
|
||||||
|
1:
|
||||||
|
|
||||||
|
#define RVTEST_ENABLE_SUPERVISOR \
|
||||||
|
li a0, MSTATUS_MPP & (MSTATUS_MPP >> 1); \
|
||||||
|
csrs mstatus, a0; \
|
||||||
|
li a0, SIP_SSIP | SIP_STIP; \
|
||||||
|
csrs mideleg, a0; \
|
||||||
|
|
||||||
|
#define RVTEST_ENABLE_MACHINE \
|
||||||
|
li a0, MSTATUS_MPP; \
|
||||||
|
csrs mstatus, a0; \
|
||||||
|
|
||||||
|
#define RVTEST_FP_ENABLE \
|
||||||
|
li a0, MSTATUS_FS & (MSTATUS_FS >> 1); \
|
||||||
|
csrs mstatus, a0; \
|
||||||
|
csrwi fcsr, 0
|
||||||
|
|
||||||
|
#define RVTEST_VECTOR_ENABLE \
|
||||||
|
li a0, (MSTATUS_VS & (MSTATUS_VS >> 1)) | \
|
||||||
|
(MSTATUS_FS & (MSTATUS_FS >> 1)); \
|
||||||
|
csrs mstatus, a0; \
|
||||||
|
csrwi fcsr, 0; \
|
||||||
|
csrwi vcsr, 0;
|
||||||
|
|
||||||
|
#define RVTEST_ZVE32X_ENABLE \
|
||||||
|
li a0, (MSTATUS_VS & (MSTATUS_VS >> 1)); \
|
||||||
|
csrs mstatus, a0; \
|
||||||
|
csrwi vcsr, 0;
|
||||||
|
|
||||||
|
#define RISCV_MULTICORE_DISABLE \
|
||||||
|
csrr a0, mhartid; \
|
||||||
|
1: bnez a0, 1b
|
||||||
|
|
||||||
|
#define EXTRA_TVEC_USER
|
||||||
|
#define EXTRA_TVEC_MACHINE
|
||||||
|
#define EXTRA_INIT
|
||||||
|
#define EXTRA_INIT_TIMER
|
||||||
|
#define FILTER_TRAP
|
||||||
|
#define FILTER_PAGE_FAULT
|
||||||
|
|
||||||
|
#define INTERRUPT_HANDLER j other_exception /* No interrupts should occur */
|
||||||
|
|
||||||
|
#define RVTEST_CODE_BEGIN \
|
||||||
|
.section .text.init; \
|
||||||
|
.align 6; \
|
||||||
|
.weak stvec_handler; \
|
||||||
|
.weak mtvec_handler; \
|
||||||
|
.globl _start; \
|
||||||
|
_start: \
|
||||||
|
/* reset vector */ \
|
||||||
|
j reset_vector; \
|
||||||
|
.align 2; \
|
||||||
|
trap_vector: \
|
||||||
|
/* test whether the test came from pass/fail */ \
|
||||||
|
csrr t5, mcause; \
|
||||||
|
li t6, CAUSE_USER_ECALL; \
|
||||||
|
beq t5, t6, write_tohost; \
|
||||||
|
li t6, CAUSE_SUPERVISOR_ECALL; \
|
||||||
|
beq t5, t6, write_tohost; \
|
||||||
|
li t6, CAUSE_MACHINE_ECALL; \
|
||||||
|
beq t5, t6, write_tohost; \
|
||||||
|
/* if an mtvec_handler is defined, jump to it */ \
|
||||||
|
la t5, mtvec_handler; \
|
||||||
|
beqz t5, 1f; \
|
||||||
|
jr t5; \
|
||||||
|
/* was it an interrupt or an exception? */ \
|
||||||
|
1: csrr t5, mcause; \
|
||||||
|
bgez t5, handle_exception; \
|
||||||
|
INTERRUPT_HANDLER; \
|
||||||
|
handle_exception: \
|
||||||
|
/* we don't know how to handle whatever the exception was */ \
|
||||||
|
other_exception: \
|
||||||
|
/* some unhandlable exception occurred */ \
|
||||||
|
1: ori TESTNUM, TESTNUM, 1337; \
|
||||||
|
write_tohost: \
|
||||||
|
sw TESTNUM, tohost, t5; \
|
||||||
|
sw zero, tohost + 4, t5; \
|
||||||
|
j write_tohost; \
|
||||||
|
reset_vector: \
|
||||||
|
INIT_XREG; \
|
||||||
|
RISCV_MULTICORE_DISABLE; \
|
||||||
|
INIT_RNMI; \
|
||||||
|
INIT_SATP; \
|
||||||
|
INIT_PMP; \
|
||||||
|
DELEGATE_NO_TRAPS; \
|
||||||
|
li TESTNUM, 0; \
|
||||||
|
la t0, trap_vector; \
|
||||||
|
csrw mtvec, t0; \
|
||||||
|
CHECK_XLEN; \
|
||||||
|
/* if an stvec_handler is defined, delegate exceptions to it */ \
|
||||||
|
la t0, stvec_handler; \
|
||||||
|
beqz t0, 1f; \
|
||||||
|
csrw stvec, t0; \
|
||||||
|
li t0, (1 << CAUSE_LOAD_PAGE_FAULT) | \
|
||||||
|
(1 << CAUSE_STORE_PAGE_FAULT) | \
|
||||||
|
(1 << CAUSE_FETCH_PAGE_FAULT) | \
|
||||||
|
(1 << CAUSE_MISALIGNED_FETCH) | \
|
||||||
|
(1 << CAUSE_USER_ECALL) | \
|
||||||
|
(1 << CAUSE_BREAKPOINT); \
|
||||||
|
csrw medeleg, t0; \
|
||||||
|
1: csrwi mstatus, 0; \
|
||||||
|
init; \
|
||||||
|
EXTRA_INIT; \
|
||||||
|
EXTRA_INIT_TIMER; \
|
||||||
|
la t0, 1f; \
|
||||||
|
csrw mepc, t0; \
|
||||||
|
csrr a0, mhartid; \
|
||||||
|
mret; \
|
||||||
|
1:
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
// End Macro
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define RVTEST_CODE_END \
|
||||||
|
unimp
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
// Pass/Fail Macro
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define RVTEST_PASS \
|
||||||
|
fence; \
|
||||||
|
li TESTNUM, 1; \
|
||||||
|
li a7, 93; \
|
||||||
|
li a0, 0; \
|
||||||
|
ecall
|
||||||
|
|
||||||
|
#define TESTNUM gp
|
||||||
|
#define RVTEST_FAIL \
|
||||||
|
fence; \
|
||||||
|
1: beqz TESTNUM, 1b; \
|
||||||
|
sll TESTNUM, TESTNUM, 1; \
|
||||||
|
or TESTNUM, TESTNUM, 1; \
|
||||||
|
li a7, 93; \
|
||||||
|
addi a0, TESTNUM, 0; \
|
||||||
|
ecall
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
// Data Section Macro
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define EXTRA_DATA
|
||||||
|
|
||||||
|
#define RVTEST_DATA_BEGIN \
|
||||||
|
EXTRA_DATA \
|
||||||
|
.pushsection .tohost,"aw",@progbits; \
|
||||||
|
.align 6; .global tohost; tohost: .dword 0; .size tohost, 8; \
|
||||||
|
.align 6; .global fromhost; fromhost: .dword 0; .size fromhost, 8;\
|
||||||
|
.popsection; \
|
||||||
|
.align 4; .global begin_signature; begin_signature:
|
||||||
|
|
||||||
|
#define RVTEST_DATA_END .align 4; .global end_signature; end_signature:
|
||||||
|
|
||||||
|
#endif
|
||||||
114
Tests/isa/Baremetal-C-programs/string.c
Normal file
114
Tests/isa/Baremetal-C-programs/string.c
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
#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)
|
||||||
|
{
|
||||||
|
if ((((uintptr_t)s1 | (uintptr_t)s2) & (sizeof(uintptr_t)-1)) == 0) {
|
||||||
|
const uintptr_t* u1 = s1;
|
||||||
|
const uintptr_t* u2 = s2;
|
||||||
|
const uintptr_t* end = u1 + (n / sizeof(uintptr_t));
|
||||||
|
while (u1 < end) {
|
||||||
|
if (*u1 != *u2)
|
||||||
|
break;
|
||||||
|
u1++;
|
||||||
|
u2++;
|
||||||
|
}
|
||||||
|
n -= (const void*)u1 - s1;
|
||||||
|
s1 = u1;
|
||||||
|
s2 = u2;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
300
Tests/isa/Baremetal-C-programs/vm.c
Normal file
300
Tests/isa/Baremetal-C-programs/vm.c
Normal file
@@ -0,0 +1,300 @@
|
|||||||
|
// See LICENSE for license details.
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "riscv_test.h"
|
||||||
|
|
||||||
|
#define SYS_write 64
|
||||||
|
|
||||||
|
# define SATP_MODE_CHOICE SATP_MODE_SV39
|
||||||
|
|
||||||
|
void trap_entry();
|
||||||
|
void pop_tf(trapframe_t*);
|
||||||
|
|
||||||
|
extern volatile uint64_t tohost;
|
||||||
|
extern volatile uint64_t fromhost;
|
||||||
|
|
||||||
|
static void do_tohost(uint64_t tohost_value)
|
||||||
|
{
|
||||||
|
while (tohost)
|
||||||
|
fromhost = 0;
|
||||||
|
tohost = tohost_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define pa2kva(pa) ((void*)(pa) - DRAM_BASE - MEGAPAGE_SIZE)
|
||||||
|
#define uva2kva(pa) ((void*)(pa) - MEGAPAGE_SIZE)
|
||||||
|
|
||||||
|
#define flush_page(addr) asm volatile ("sfence.vma %0" : : "r" (addr) : "memory")
|
||||||
|
|
||||||
|
static uint64_t lfsr63(uint64_t x)
|
||||||
|
{
|
||||||
|
uint64_t bit = (x ^ (x >> 1)) & 1;
|
||||||
|
return (x >> 1) | (bit << 62);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cputchar(int x)
|
||||||
|
{
|
||||||
|
#if __riscv_xlen == 32
|
||||||
|
// HTIF devices are not supported on RV32, so proxy a write system call
|
||||||
|
volatile uint64_t syscall_struct[8];
|
||||||
|
volatile int buff = x;
|
||||||
|
syscall_struct[0] = SYS_write;
|
||||||
|
syscall_struct[1] = 1;
|
||||||
|
syscall_struct[2] = (uintptr_t)&buff;
|
||||||
|
syscall_struct[3] = 1;
|
||||||
|
do_tohost((uintptr_t)&syscall_struct);
|
||||||
|
// Wait for response as struct has to be read by HTIF
|
||||||
|
while(!fromhost);
|
||||||
|
#else
|
||||||
|
do_tohost(0x0101000000000000 | (unsigned char)x);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cputstring(const char* s)
|
||||||
|
{
|
||||||
|
while (*s)
|
||||||
|
cputchar(*s++);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void terminate(int code)
|
||||||
|
{
|
||||||
|
do_tohost(code);
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wtf()
|
||||||
|
{
|
||||||
|
terminate(841);
|
||||||
|
}
|
||||||
|
|
||||||
|
#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)
|
||||||
|
|
||||||
|
#define l1pt pt[0]
|
||||||
|
#define user_l2pt pt[1]
|
||||||
|
# define NPT 4
|
||||||
|
# define kernel_l2pt pt[2]
|
||||||
|
# define user_llpt pt[3]
|
||||||
|
pte_t pt[NPT][PTES_PER_PT] __attribute__((aligned(PGSIZE)));
|
||||||
|
|
||||||
|
typedef struct { pte_t addr; void* next; } freelist_t;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
static 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 accessed and dirty bits
|
||||||
|
assert(user_llpt[addr/PGSIZE] & PTE_A);
|
||||||
|
uintptr_t sstatus = set_csr(sstatus, SSTATUS_SUM);
|
||||||
|
if (memcmp((void*)addr, uva2kva(addr), PGSIZE)) {
|
||||||
|
assert(user_llpt[addr/PGSIZE] & PTE_D);
|
||||||
|
memcpy(uva2kva(addr), (void*)addr, PGSIZE);
|
||||||
|
}
|
||||||
|
write_csr(sstatus, sstatus);
|
||||||
|
|
||||||
|
user_mapping[addr/PGSIZE].addr = 0;
|
||||||
|
|
||||||
|
if (freelist_tail == 0)
|
||||||
|
freelist_head = freelist_tail = node;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
freelist_tail->next = node;
|
||||||
|
freelist_tail = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern int pf_filter(uintptr_t addr, uintptr_t *pte, int *copy);
|
||||||
|
extern int trap_filter(trapframe_t *tf);
|
||||||
|
|
||||||
|
void handle_fault(uintptr_t addr, uintptr_t cause)
|
||||||
|
{
|
||||||
|
uintptr_t filter_encodings = 0;
|
||||||
|
int copy_page = 1;
|
||||||
|
|
||||||
|
assert(addr >= PGSIZE && addr < MAX_TEST_PAGES * PGSIZE);
|
||||||
|
addr = addr/PGSIZE*PGSIZE;
|
||||||
|
|
||||||
|
if (user_llpt[addr/PGSIZE]) {
|
||||||
|
if (!(user_llpt[addr/PGSIZE] & PTE_A)) {
|
||||||
|
user_llpt[addr/PGSIZE] |= PTE_A;
|
||||||
|
} else {
|
||||||
|
assert(!(user_llpt[addr/PGSIZE] & PTE_D) && cause == CAUSE_STORE_PAGE_FAULT);
|
||||||
|
user_llpt[addr/PGSIZE] |= PTE_D;
|
||||||
|
}
|
||||||
|
flush_page(addr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
freelist_t* node = freelist_head;
|
||||||
|
assert(node);
|
||||||
|
freelist_head = node->next;
|
||||||
|
if (freelist_head == freelist_tail)
|
||||||
|
freelist_tail = 0;
|
||||||
|
|
||||||
|
uintptr_t new_pte = (node->addr >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V | PTE_U | PTE_R | PTE_W | PTE_X;
|
||||||
|
|
||||||
|
if (pf_filter(addr, &filter_encodings, ©_page)) {
|
||||||
|
new_pte = (node->addr >> PGSHIFT << PTE_PPN_SHIFT) | filter_encodings;
|
||||||
|
}
|
||||||
|
|
||||||
|
user_llpt[addr/PGSIZE] = new_pte | PTE_A | PTE_D;
|
||||||
|
flush_page(addr);
|
||||||
|
|
||||||
|
assert(user_mapping[addr/PGSIZE].addr == 0);
|
||||||
|
user_mapping[addr/PGSIZE] = *node;
|
||||||
|
|
||||||
|
uintptr_t sstatus = set_csr(sstatus, SSTATUS_SUM);
|
||||||
|
memcpy((void*)addr, uva2kva(addr), PGSIZE);
|
||||||
|
write_csr(sstatus, sstatus);
|
||||||
|
|
||||||
|
user_llpt[addr/PGSIZE] = new_pte;
|
||||||
|
flush_page(addr);
|
||||||
|
|
||||||
|
asm volatile ("fence.i");
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_trap(trapframe_t* tf)
|
||||||
|
{
|
||||||
|
if (trap_filter(tf)) {
|
||||||
|
pop_tf(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_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_FETCH_PAGE_FAULT || tf->cause == CAUSE_LOAD_PAGE_FAULT || tf->cause == CAUSE_STORE_PAGE_FAULT)
|
||||||
|
handle_fault(tf->badvaddr, tf->cause);
|
||||||
|
else
|
||||||
|
assert(!"unexpected exception");
|
||||||
|
|
||||||
|
pop_tf(tf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void coherence_torture()
|
||||||
|
{
|
||||||
|
// cause coherence misses without affecting program semantics
|
||||||
|
uint64_t random = ENTROPY;
|
||||||
|
while (1) {
|
||||||
|
uintptr_t paddr = DRAM_BASE + ((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(uintptr_t test_addr)
|
||||||
|
{
|
||||||
|
uint64_t random = ENTROPY;
|
||||||
|
if (read_csr(mhartid) > 0)
|
||||||
|
coherence_torture();
|
||||||
|
|
||||||
|
_Static_assert(SIZEOF_TRAPFRAME_T == sizeof(trapframe_t), "???");
|
||||||
|
|
||||||
|
#if (MAX_TEST_PAGES > PTES_PER_PT) || (DRAM_BASE % MEGAPAGE_SIZE) != 0
|
||||||
|
# error
|
||||||
|
#endif
|
||||||
|
// map user to lowermost megapage
|
||||||
|
l1pt[0] = ((pte_t)user_l2pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
|
||||||
|
// map kernel to uppermost megapage
|
||||||
|
l1pt[PTES_PER_PT-1] = ((pte_t)kernel_l2pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
|
||||||
|
kernel_l2pt[PTES_PER_PT-1] = (DRAM_BASE/RISCV_PGSIZE << PTE_PPN_SHIFT) | PTE_V | PTE_R | PTE_W | PTE_X | PTE_A | PTE_D;
|
||||||
|
user_l2pt[0] = ((pte_t)user_llpt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V;
|
||||||
|
uintptr_t vm_choice = SATP_MODE_CHOICE;
|
||||||
|
uintptr_t satp_value = ((uintptr_t)l1pt >> PGSHIFT)
|
||||||
|
| (vm_choice * (SATP_MODE & ~(SATP_MODE<<1)));
|
||||||
|
write_csr(satp, satp_value);
|
||||||
|
if (read_csr(satp) != satp_value)
|
||||||
|
assert(!"unsupported satp mode");
|
||||||
|
flush_page(DRAM_BASE);
|
||||||
|
|
||||||
|
// Set up PMPs if present, ignoring illegal instruction trap if not.
|
||||||
|
uintptr_t pmpc = PMP_NAPOT | PMP_R | PMP_W | PMP_X;
|
||||||
|
uintptr_t pmpa = ((uintptr_t)1 << (__riscv_xlen == 32 ? 31 : 53)) - 1;
|
||||||
|
asm volatile ("la t0, 1f\n\t"
|
||||||
|
"csrrw t0, mtvec, t0\n\t"
|
||||||
|
"csrw pmpaddr0, %1\n\t"
|
||||||
|
"csrw pmpcfg0, %0\n\t"
|
||||||
|
".align 2\n\t"
|
||||||
|
"1: csrw mtvec, t0"
|
||||||
|
: : "r" (pmpc), "r" (pmpa) : "t0");
|
||||||
|
|
||||||
|
// set up supervisor trap handling
|
||||||
|
write_csr(stvec, pa2kva(trap_entry));
|
||||||
|
write_csr(sscratch, pa2kva(read_csr(mscratch)));
|
||||||
|
write_csr(medeleg,
|
||||||
|
(1 << CAUSE_USER_ECALL) |
|
||||||
|
(1 << CAUSE_FETCH_PAGE_FAULT) |
|
||||||
|
(1 << CAUSE_LOAD_PAGE_FAULT) |
|
||||||
|
(1 << CAUSE_STORE_PAGE_FAULT));
|
||||||
|
// FPU on; accelerator on; vector unit on
|
||||||
|
write_csr(mstatus, MSTATUS_FS | MSTATUS_XS | MSTATUS_VS);
|
||||||
|
write_csr(mie, 0);
|
||||||
|
|
||||||
|
random = 1 + (random % 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 = DRAM_BASE + (MAX_TEST_PAGES + random)*PGSIZE;
|
||||||
|
freelist_nodes[i].next = pa2kva(&freelist_nodes[i+1]);
|
||||||
|
random = LFSR_NEXT(random);
|
||||||
|
}
|
||||||
|
freelist_nodes[MAX_TEST_PAGES-1].next = 0;
|
||||||
|
|
||||||
|
trapframe_t tf;
|
||||||
|
memset(&tf, 0, sizeof(tf));
|
||||||
|
tf.epc = test_addr - DRAM_BASE;
|
||||||
|
pop_tf(&tf);
|
||||||
|
}
|
||||||
37
Tests/isa/Cheri.S
Normal file
37
Tests/isa/Cheri.S
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
.section .bss
|
||||||
|
.align 6 # 64-byte alignment helps bounds encoding
|
||||||
|
buffer:
|
||||||
|
.space 64
|
||||||
|
|
||||||
|
.section .text
|
||||||
|
.globl _start
|
||||||
|
_start:
|
||||||
|
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
# 1. Create capability to buffer using DDC (c0)
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
la t0, buffer
|
||||||
|
cincoffset c1, c0, t0 # c1 -> buffer capability
|
||||||
|
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
# 2. Set bounds to first 16 bytes
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
li t1, 16
|
||||||
|
csetbounds c2, c1, t1 # c2 = bounded capability
|
||||||
|
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
# 3. Store value 0x42 into buffer[0] using capability
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
li t2, 0x42
|
||||||
|
csb t2, 0(c2) # capability store byte
|
||||||
|
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
# 4. Load the value back from buffer[0]
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
clbu t3, 0(c2) # t3 should now contain 0x42
|
||||||
|
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
# 5. Infinite loop (bare-metal halt)
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
1:
|
||||||
|
j 1b
|
||||||
Binary file not shown.
@@ -2,164 +2,176 @@
|
|||||||
.option norelax
|
.option norelax
|
||||||
|
|
||||||
# ==================================================
|
# ==================================================
|
||||||
# Text section
|
# Constants
|
||||||
|
# ==================================================
|
||||||
|
.equ PTE_V, 0x001
|
||||||
|
.equ PTE_R, 0x002
|
||||||
|
.equ PTE_W, 0x004
|
||||||
|
.equ PTE_X, 0x008
|
||||||
|
.equ PTE_A, 0x040
|
||||||
|
.equ PTE_D, 0x080
|
||||||
|
|
||||||
|
.equ SATP_MODE_SV39, (8 << 60)
|
||||||
|
|
||||||
|
# ==================================================
|
||||||
|
# Text
|
||||||
# ==================================================
|
# ==================================================
|
||||||
.section .text
|
.section .text
|
||||||
.globl _start
|
.globl _start
|
||||||
.globl vm_boot
|
|
||||||
|
|
||||||
_start:
|
_start:
|
||||||
vm_boot:
|
# only hart 0
|
||||||
# Only hart 0 runs
|
csrr a0, mhartid
|
||||||
csrr a0, mhartid
|
bnez a0, hang
|
||||||
bnez a0, hang
|
|
||||||
|
# install trap vector (required)
|
||||||
|
la t0, trap_vector
|
||||||
|
csrw stvec, t0
|
||||||
|
|
||||||
# --------------------------------------------------
|
# --------------------------------------------------
|
||||||
# Page tables (Sv39, identity map)
|
# Build page tables (Sv39 identity map 1 GiB)
|
||||||
# --------------------------------------------------
|
# --------------------------------------------------
|
||||||
la t0, l1_pt
|
|
||||||
srli t0, t0, 12
|
|
||||||
slli t0, t0, 10
|
|
||||||
ori t0, t0, 1
|
|
||||||
la t1, root_pt
|
|
||||||
sd t0, 0(t1)
|
|
||||||
|
|
||||||
la t0, l0_pt
|
# root_pt[0] -> l1_pt
|
||||||
srli t0, t0, 12
|
la t0, l1_pt
|
||||||
slli t0, t0, 10
|
srli t0, t0, 12
|
||||||
ori t0, t0, 1
|
slli t0, t0, 10
|
||||||
la t1, l1_pt
|
ori t0, t0, PTE_V
|
||||||
sd t0, 0(t1)
|
la t1, root_pt
|
||||||
|
sd t0, 0(t1)
|
||||||
|
|
||||||
li t0, (1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<6) # V R W X A
|
# l1_pt[0] -> l0_pt
|
||||||
la t1, l0_pt
|
la t0, l0_pt
|
||||||
sd t0, 0(t1)
|
srli t0, t0, 12
|
||||||
|
slli t0, t0, 10
|
||||||
|
ori t0, t0, PTE_V
|
||||||
|
la t1, l1_pt
|
||||||
|
sd t0, 0(t1)
|
||||||
|
|
||||||
|
# l0_pt[0] = 1GiB RWX identity leaf
|
||||||
|
li t0, (PTE_V|PTE_R|PTE_W|PTE_X|PTE_A|PTE_D)
|
||||||
|
la t1, l0_pt
|
||||||
|
sd t0, 0(t1)
|
||||||
|
|
||||||
|
# --------------------------------------------------
|
||||||
# Enable Sv39
|
# Enable Sv39
|
||||||
la t0, root_pt
|
# --------------------------------------------------
|
||||||
srli t0, t0, 12
|
la t0, root_pt
|
||||||
li t1, (8 << 60)
|
srli t0, t0, 12
|
||||||
or t0, t0, t1
|
li t1, SATP_MODE_SV39
|
||||||
csrw satp, t0
|
or t0, t0, t1
|
||||||
sfence.vma zero, zero
|
csrw satp, t0
|
||||||
|
# sfence.vma zero, zero
|
||||||
|
|
||||||
# --------------------------------------------------
|
# --------------------------------------------------
|
||||||
# Init allocator (explicit, no .bss)
|
# Init allocator
|
||||||
# --------------------------------------------------
|
# --------------------------------------------------
|
||||||
la t0, heap_base
|
la t0, heap_base
|
||||||
la t1, heap_ptr
|
la t1, heap_ptr
|
||||||
sd t0, 0(t1)
|
sd t0, 0(t1)
|
||||||
|
|
||||||
la t0, free_list
|
la t0, free_list
|
||||||
sd zero, 0(t0)
|
sd zero, 0(t0)
|
||||||
|
|
||||||
# --------------------------------------------------
|
# --------------------------------------------------
|
||||||
# Allocate → free → reuse test
|
# Allocate → free → reuse test
|
||||||
# --------------------------------------------------
|
# --------------------------------------------------
|
||||||
li a0, 16
|
li a0, 16
|
||||||
jal ra, alloc
|
call alloc
|
||||||
mv s1, a0
|
mv s1, a0
|
||||||
|
|
||||||
li t0, 0x1122334455667788
|
li t0, 0x1122334455667788
|
||||||
sd t0, 0(s1)
|
sd t0, 0(s1)
|
||||||
|
|
||||||
mv a0, s1
|
mv a0, s1
|
||||||
jal ra, free
|
call free
|
||||||
|
|
||||||
li a0, 16
|
li a0, 16
|
||||||
jal ra, alloc
|
call alloc
|
||||||
mv s2, a0
|
mv s2, a0
|
||||||
|
|
||||||
ld t1, 0(s2)
|
ld t1, 0(s2)
|
||||||
li t0, 0x1122334455667788
|
li t0, 0x1122334455667788
|
||||||
bne t1, t0, hang
|
bne t1, t0, hang
|
||||||
|
|
||||||
# success
|
# success
|
||||||
la t0, tohost
|
la t0, tohost
|
||||||
li t1, 1
|
li t1, 1
|
||||||
sd t1, 0(t0)
|
sd t1, 0(t0)
|
||||||
|
|
||||||
hang:
|
hang:
|
||||||
wfi
|
wfi
|
||||||
j hang
|
j hang
|
||||||
|
|
||||||
|
# ==================================================
|
||||||
|
# Minimal trap handler (required)
|
||||||
|
# ==================================================
|
||||||
|
.align 2
|
||||||
|
trap_vector:
|
||||||
|
csrr t0, scause
|
||||||
|
j hang
|
||||||
|
|
||||||
# ==================================================
|
# ==================================================
|
||||||
# alloc(size)
|
# alloc(size)
|
||||||
# a0 = size
|
|
||||||
# returns a0 = ptr
|
|
||||||
# ==================================================
|
# ==================================================
|
||||||
.globl alloc
|
.globl alloc
|
||||||
alloc:
|
alloc:
|
||||||
la t0, free_list
|
la t0, free_list
|
||||||
ld t1, 0(t0)
|
ld t1, 0(t0)
|
||||||
beqz t1, alloc_bump
|
beqz t1, alloc_bump
|
||||||
|
|
||||||
# pop free list
|
ld t2, 0(t1)
|
||||||
ld t2, 0(t1)
|
sd t2, 0(t0)
|
||||||
sd t2, 0(t0)
|
addi a0, t1, 8
|
||||||
addi a0, t1, 8
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
alloc_bump:
|
alloc_bump:
|
||||||
la t0, heap_ptr
|
la t0, heap_ptr
|
||||||
ld t1, 0(t0)
|
ld t1, 0(t0)
|
||||||
addi t2, a0, 8
|
addi t2, a0, 8
|
||||||
add t3, t1, t2
|
add t3, t1, t2
|
||||||
la t4, heap_end
|
la t4, heap_end
|
||||||
bgtu t3, t4, hang
|
bgtu t3, t4, hang
|
||||||
|
sd t3, 0(t0)
|
||||||
sd t3, 0(t0)
|
addi a0, t1, 8
|
||||||
addi a0, t1, 8
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
# ==================================================
|
# ==================================================
|
||||||
# free(ptr)
|
# free(ptr)
|
||||||
# a0 = user pointer
|
|
||||||
# ==================================================
|
# ==================================================
|
||||||
.globl free
|
.globl free
|
||||||
free:
|
free:
|
||||||
addi t0, a0, -8
|
addi t0, a0, -8
|
||||||
la t1, free_list
|
la t1, free_list
|
||||||
ld t2, 0(t1)
|
ld t2, 0(t1)
|
||||||
sd t2, 0(t0)
|
sd t2, 0(t0)
|
||||||
sd t0, 0(t1)
|
sd t0, 0(t1)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
# ==================================================
|
# ==================================================
|
||||||
# Exit symbol
|
# Data (NO .bss)
|
||||||
# ==================================================
|
|
||||||
.globl exit
|
|
||||||
exit:
|
|
||||||
j exit
|
|
||||||
|
|
||||||
# ==================================================
|
|
||||||
# Data section (NO .bss)
|
|
||||||
# ==================================================
|
# ==================================================
|
||||||
.section .data
|
.section .data
|
||||||
.align 3
|
.align 3
|
||||||
|
|
||||||
# Host interface
|
|
||||||
.globl tohost
|
.globl tohost
|
||||||
.globl fromhost
|
.globl fromhost
|
||||||
tohost: .dword 0
|
tohost: .dword 0
|
||||||
fromhost: .dword 0
|
fromhost: .dword 0
|
||||||
|
|
||||||
# Allocator state (explicitly initialized)
|
|
||||||
.globl heap_ptr
|
.globl heap_ptr
|
||||||
.globl free_list
|
.globl free_list
|
||||||
heap_ptr: .dword 0
|
heap_ptr: .dword 0
|
||||||
free_list: .dword 0
|
free_list: .dword 0
|
||||||
|
|
||||||
# Heap
|
|
||||||
.align 12
|
.align 12
|
||||||
heap_base:
|
heap_base:
|
||||||
.zero 4096
|
.zero 4096
|
||||||
heap_end:
|
heap_end:
|
||||||
|
|
||||||
# Page tables
|
|
||||||
.align 12
|
.align 12
|
||||||
root_pt: .zero 4096
|
root_pt: .zero 4096
|
||||||
.align 12
|
.align 12
|
||||||
l1_pt: .zero 4096
|
l1_pt: .zero 4096
|
||||||
.align 12
|
.align 12
|
||||||
l0_pt: .zero 4096
|
l0_pt: .zero 4096
|
||||||
|
|||||||
BIN
Tests/isa/string
Normal file
BIN
Tests/isa/string
Normal file
Binary file not shown.
@@ -109,7 +109,7 @@ benchmarks:
|
|||||||
|
|
||||||
# ================================================================
|
# ================================================================
|
||||||
# Generate Bluespec CHERI tag controller source file
|
# Generate Bluespec CHERI tag controller source file
|
||||||
CAPSIZE = 128
|
CAPSIZE = 128
|
||||||
TAGS_STRUCT = 0 64
|
TAGS_STRUCT = 0 64
|
||||||
TAGS_ALIGN = 32
|
TAGS_ALIGN = 32
|
||||||
.PHONY: tagsparams
|
.PHONY: tagsparams
|
||||||
|
|||||||
Submodule libs/cheri-cap-lib updated: 27e63bd9fd...b8f7b51e8a
@@ -1003,6 +1003,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode);
|
|||||||
regs.src1 = Valid(tagged Gpr rs1);
|
regs.src1 = Valid(tagged Gpr rs1);
|
||||||
regs.src2 = Valid(tagged Gpr rs2);
|
regs.src2 = Valid(tagged Gpr rs2);
|
||||||
dInst.capFunc = CapModify (SetBounds (SetBoundsRounding));
|
dInst.capFunc = CapModify (SetBounds (SetBoundsRounding));
|
||||||
|
// TODOD Add the delta function under this
|
||||||
end
|
end
|
||||||
f7_cap_CSetBoundsExact: begin
|
f7_cap_CSetBoundsExact: begin
|
||||||
legalInst = True;
|
legalInst = True;
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ typedef enum {
|
|||||||
} ModifyOffsetFunc deriving(Bits, Eq, FShow);
|
} ModifyOffsetFunc deriving(Bits, Eq, FShow);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SetBoundsExact, SetBoundsRounding, CRRL, CRAM
|
SetBoundsExact, SetBoundsRounding, CRRL, CRAM, SetDelta
|
||||||
} SetBoundsFunc deriving(Bits, Eq, FShow);
|
} SetBoundsFunc deriving(Bits, Eq, FShow);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -336,6 +336,8 @@ typedef enum {
|
|||||||
typedef union tagged {
|
typedef union tagged {
|
||||||
ModifyOffsetFunc ModifyOffset;
|
ModifyOffsetFunc ModifyOffset;
|
||||||
SetBoundsFunc SetBounds;
|
SetBoundsFunc SetBounds;
|
||||||
|
// TODOD: Delta add type here
|
||||||
|
// SetDeltaFunc SetDelta;
|
||||||
SpecialRWFunc SpecialRW;
|
SpecialRWFunc SpecialRW;
|
||||||
AddrSource SetAddr;
|
AddrSource SetAddr;
|
||||||
void Seal;
|
void Seal;
|
||||||
@@ -1068,7 +1070,7 @@ function Fmt showInst(Instruction inst);
|
|||||||
return ret;
|
return ret;
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function x addPc(x cap, Bit#(12) inc) provisos (Add#(f, 12, c), CHERICap::CHERICap#(x, a, b, c, d, e)) = setAddrUnsafe(cap, getAddr(cap) + signExtend(inc));
|
function x addPc(x cap, Bit#(12) inc) provisos (Add#(f, 12, c), CHERICap::CHERICap#(x, a, b, c, d, e, f)) = setAddrUnsafe(cap, getAddr(cap) + signExtend(inc));
|
||||||
|
|
||||||
`ifdef PERFORMANCE_MONITORING
|
`ifdef PERFORMANCE_MONITORING
|
||||||
typedef 8 Report_Width;
|
typedef 8 Report_Width;
|
||||||
|
|||||||
Reference in New Issue
Block a user