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;