GithubHelp home page GithubHelp logo

michaeljclark / rv8 Goto Github PK

View Code? Open in Web Editor NEW
668.0 44.0 97.0 6.18 MB

RISC-V simulator for x86-64

Home Page: https://michaeljclark.github.io/

License: MIT License

Makefile 1.57% C 27.43% C++ 69.71% Assembly 1.01% Shell 0.15% CMake 0.09% Objective-C 0.03%
isa simulator disassembler emulator riscv binary-translation metadata histogram risc macro-op-fusion

rv8's Introduction

rv8

RISC-V simulator for x86-64

Build Status Coverity Status License: MIT Donate

rv8 is a RISC-V simulation suite comprising a high performance x86-64 binary translator, a user mode simulator, a full system emulator, an ELF binary analysis tool and ISA metadata:

  • rv-jit - user mode x86-64 binary translator
  • rv-sim - user mode system call proxy simulator
  • rv-sys - full system emulator with soft MMU
  • rv-bin - ELF disassembler and histogram tool
  • rv-meta - code and documentation generator

The rv8 simulator suite contains libraries and command line tools for creating instruction opcode maps, C headers and source containing instruction set metadata, instruction decoders, a JIT assembler, LaTeX documentation, a metadata based RISC-V disassembler, a histogram tool for generating statistics on RISC-V ELF executables, a RISC-V proxy syscall simulator, a RISC-V full system emulator that implements the RISC-V 1.9.1 privileged specification and an x86-64 binary translator.

rv8 binary translation

RISC-V to x86-64 binary translator

The rv8 binary translation engine works by interpreting code while profiling it for hot paths. Hot paths are translated on the fly to native code. The translation engine maintains a call stack to allow runtime inlining of hot functions. A jump target cache is used to accelerate returns and indirect calls through function pointers. The translator supports hybrid binary translation and interpretation to handle instructions that do not have native translations. Currently ‘IM’ code is translated and ‘AFD’ is interpreted. The translator supports RVC compressed code.

The rv8 binary translator supports a number of simple optimisations:

  • Hybrid interpretation and compilation of hot code paths
  • Incremental translation with dynamic trace linking
  • Inline caching of function calls in hot code paths
  • L1 jump target cache for indirect calls and returns
  • Macro-op fusion for common RISC-V instruction sequences

RISC-V full system emulator

The rv8 suite includes a full system emulator that implements the RISC-V privileged ISA with support for interrupts, MMIO (memory mapped input output) devices, a soft MMU (memory management unit) with separate instruction and data TLBs (translation lookaside buffers). The full system emulator has a simple integrated debugger that allows setting breakpoints, single stepping and disassembling instructions as they are executed.

The rv8 full system emulator has the following features:

  • RISC-V IMAFD Base plus Privileged ISA (riscv32 and riscv64)
  • Simple integrated debug command line interface
  • Histograms (registers, instruction and program counter frequency)
  • Soft MMU supporting sv32, sv39, sv48 page translation modes
  • Abstract MMIO device interface for device emulation
  • Extensible interpreter generated from ISA metadata
  • Protected address space

RISC-V user mode simulator

The rv8 user mode simulator is a single address space implementation of the RISC-V ISA that implements a subset of the RISC-V Linux syscall ABI (application binary interface) and delegates system calls to the underlying native host operating system. The user mode simulator can run RISC-V Linux binaries on non-Linux operating systems via system call emulation. The current user mode simulator implements a small number of system calls to allow running RISC-V Linux ELF static binaries.

The rv8 user mode simulator has the following features:

  • RISC-V IMAFD Base ISA (riscv32 and riscv64)
  • Simple integrated debug command line interface
  • A small set of emulated Linux system calls for simple file IO
  • Extensible interpreter generated from ISA metadata
  • Instruction logging mode for tracing program execution
  • Shared address space
    • 0x000000000000 - 0x000000000fff (zero)
    • 0x000000001000 - 0x7ffdffffffff (guest)
    • 0x7ffe00000000 - 0x7fffffffffff (host)

Project Goals

The future goals of the rv8 project are:

  • Concise metadata representing the RISC-V ISA
  • Tools for metadata-based generation of source and documentation
  • High performance emulation, sandboxing and binary translation
  • RISC-V-(n) → RISC-V-(n+1)
  • RISC-V-(n) → Intel i7 / AMD64 + AVX-512
  • RISC-V Linux ABI emulation on MacOS, Windows, Linux and *BSD
  • RISC-V Linux ABI randomisation and entropy coding
  • RISC-V Specification undefined behaviour investigation
  • RISC-V Virtualization and memory protection investigation

Supported Platforms

  • Target
    • RV32IMAFDC
    • RV64IMAFDC
    • Privilged ISA 1.9.1
  • Host
    • Linux (Debian 9.0 x86-64, Ubuntu 16.04 x86-64, Fedora 25 x86-64) (stable)
    • macOS (Sierra 10.11 x86-64) (stable)
    • FreeBSD (11 x86-64) (alpha)

Getting Started

Building riscv-gnu-toolchain

$ sudo apt-get install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev
$ git clone https://github.com/riscv/riscv-gnu-toolchain.git
$ cd riscv-gnu-toolchain
$ git submodule update --init --recursive
$ ./configure --prefix=/opt/riscv/toolchain
$ make

Building rv8

$ export RISCV=/opt/riscv/toolchain
$ git clone https://github.com/rv8-io/rv8.git
$ cd rv8
$ git submodule update --init --recursive
$ make
$ sudo make install

Running rv8

$ make test-build
$ rv-jit build/riscv64-unknown-elf/bin/test-dhrystone

Build Dependencies

  • gmake
  • gcc-5.4 or clang-3.4 (Linux minimum)
  • gcc-6.3 or clang-3.8 (Linux recommended)
  • RISC-V GNU Toolchain
  • RISCV environment variable

Ubuntu 14.04LTS Dependencies

The compiler in Ubuntu 14.04LTS doesn't support C++14. These instructions will install g++6 from the ubuntu toolchain repository and build the project using g++6.

sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
sudo apt-get update
sudo apt-get install g++-6
make CXX=g++-6 CC=gcc-6

Screenshots

ASCII map screenshot

Example ASCII map output from make map

Histogram screenshot

Example Instructions Histogram from rv-bin histogram

Histogram screenshot

Example Registers Histogram from rv-bin histogram

RISC-V disassembly screenshot

Example Disassembly output from rv-bin dump

See RISC-V Instruction Set Listing and RISC-V Instruction Types for sample LaTeX output.

Useful Commands

Command Description
make map print a colour opcode map
make latex output a LaTeX opcode tex
make pdf output a LaTeX opcode pdf
make test-spike run the ABI Proxy Simulator tests with spike
make test-sim run the ABI Proxy Simulator tests with rv-sim
make qemu-tests run the QEMU tests with rv-sim
make test-sys run the Privileged System Emulator tests with rv-sys
make linux bootstrap bbl, linux kernel and busybox image
sudo make install install to /usr/local/bin

Notes

  • The linux target requires the RISC-V GNU Linux Toolchain
  • The test-build target requires the RISC-V ELF Toolchain
  • The qemu-tests target requires the third_party/qemu-tests to be built

Project Structure

Directories

Directory Description
meta Instruction set metadata
src/abi Application binary interface
src/app Test programs and utilities
src/asm Assembler metadata library
src/elf ELF parser library
src/emu ISA simulator and emulator headers
src/mem Memory allocator library
src/model ISA metamodel library
src/rom Boot ROM generator
src/test ISA simulator and emulator tests
src/util Miscellaneous utilities library
doc/pdf Generated documentation

Libraries

The following table shows the RISC-V Meta libraries:

Name Description Scale
libriscv_asm.a ISA metadata and disassembly formatting micro
libriscv_elf.a ELF parser micro
libriscv_gen.a Source and documentation generators macro
libriscv_model.a Instruction set metamodel macro
libriscv_util.a Utility functions for tools mini

Program Options

RISC-V x86-64 Simulator

RISC-V x86-64 JIT Simulator command line options:

$ rv-jit -h
usage: rv-jit [<emulator_options>] [--] <elf_file> [<options>]
            --log-instructions, -l            Log Instructions
                --log-operands, -o            Log Instructions and Operands
                 --symbolicate, -S            Symbolicate addresses in instruction log
              --log-memory-map, -m            Log Memory Map Information
                --log-syscalls, -c            Log System Calls
               --log-registers, -r            Log Registers (defaults to integer registers)
               --log-jit-trace, -T            Log JIT trace
            --log-jit-regalloc, -T            Log JIT register allocation
              --log-exit-stats, -E            Log Registers and Statistics at Exit
             --save-exit-stats, -D <string>   Save Registers and Statistics at Exit
          --pc-usage-histogram, -P            Record program counter usage
    --register-usage-histogram, -R            Record register usage
 --instruction-usage-histogram, -I            Record instruction usage
                       --debug, -d            Start up in debugger CLI
                   --no-pseudo, -x            Disable Pseudoinstruction decoding
                   --no-fusion, -N            Disable JIT macro-op fusion
     --memory-mapped-registers, -M            Disable JIT host register mapping
              --update-instret, -i            Update instret in JIT code
                    --no-trace, -t            Disable JIT tracer
                       --audit, -a            Enable JIT audit
                 --trace-iters, -I <string>   Trace iterations
                        --seed, -s <string>   Random seed
                        --help, -h            Show help

Notes

  • Currently only the Linux syscall ABI proxy is implemented for the JIT simulator

RISC-V Proxy Simulator

The ABI Proxy Simulator command line options:

$ rv-sim -h
usage: rv-sim [<emulator_options>] [--] <elf_file> [<options>]
            --log-instructions, -l            Log Instructions
                --log-operands, -o            Log Instructions and Operands
                 --symbolicate, -S            Symbolicate addresses in instruction log
              --log-memory-map, -m            Log Memory Map Information
                --log-syscalls, -c            Log System Calls
               --log-registers, -r            Log Registers (defaults to integer registers)
              --log-exit-stats, -E            Log Registers and Statistics at Exit
             --save-exit-stats, -D <string>   Save Registers and Statistics at Exit
          --pc-usage-histogram, -P            Record program counter usage
    --register-usage-histogram, -R            Record register usage
 --instruction-usage-histogram, -I            Record instruction usage
                       --debug, -d            Start up in debugger CLI
                   --no-pseudo, -x            Disable Pseudoinstruction decoding
                        --seed, -s <string>   Random seed
                        --help, -h            Show help

To run the simple Hello World program (Proxy Mode):

rv-sim build/riscv64-unknown-elf/bin/hello-world-libc

RISC-V Full System Emulator

The Privilged ISA Full System Emulator command line options:

$ rv-sys -h
usage: rv-sys [<options>] <elf_file>
            --log-instructions, -l            Log Instructions
                --log-operands, -o            Log Instructions and Operands
                    --log-mmio, -O            Log Memory Mapped IO
              --log-memory-map, -m            Log Memory Map Information
               --log-mmode-csr, -M            Log Machine Control and Status Registers
               --log-smode-csr, -S            Log Supervisor Control and Status Registers
               --log-registers, -r            Log Registers (defaults to integer registers)
               --log-pagewalks, -v            Log Pagewalks
                  --log-config, -c            Log Config
                   --log-traps, -t            Log Traps
              --log-exit-stats, -E            Log Registers and Statistics at Exit
             --save-exit-stats, -D <string>   Save Registers and Statistics at Exit
          --pc-usage-histogram, -P            Record program counter usage
    --register-usage-histogram, -R            Record register usage
 --instruction-usage-histogram, -I            Record instruction usage
                       --debug, -d            Start up in debugger
                  --debug-trap, -T            Start up in debugger and enter debugger on trap
                   --no-pseudo, -x            Disable Pseudoinstruction decoding
                --map-physical, -p <string>   Map execuatable at physical address
                      --binary, -b <string>   Boot Binary ( 32, 64 )
                        --seed, -s <string>   Random seed
                        --help, -h            Show help

To run the privilged UART echo program (Privileged Mode):

rv-sys build/riscv64-unknown-elf/bin/test-m-mmio-uart

RISC-V ELF Dump Utility

ELF Dump usage command line options:

$ rv-bin dump -h
usage: dump [<options>] <elf_file>
                       --color, -c            Enable Color
            --print-elf-header, -e            Print ELF header
        --print-elf-header-ext, -x            Print ELF header (extended)
       --print-section-headers, -s            Print Section headers
       --print-program-headers, -p            Print Program headers
          --print-symbol-table, -t            Print Symbol Table
           --print-relocations, -r            Print Relocations
           --print-disassembly, -d            Print Disassembly
                      --pseudo, -P            Decode Pseudoinstructions
               --print-headers, -h            Print All Headers
                   --print-all, -a            Print All Headers and Disassembly
                        --help, -h            Show help

To run the ELF parser and disassembler:

rv-bin dump -c -a build/riscv64-unknown-elf/bin/hello-world-pcrel

Notes

  • The ELF dissassembler output requires 125 column terminal window

RISC-V ELF Histogram Utility

The ELF Histogram Utility usage command line options:

$ rv-bin histogram -h
usage: histogram [<options>] <elf_file>
                        --help, -h            Show help
                        --char, -c <string>   Character to use in bars
                        --bars, -b            Print bars next to counts
                --instructions, -I            Instruction Usage Histogram
                   --registers, -R            Register Usage Histogram
          --registers-operands, -P            Register Usage Histogram (with operand positions)
                   --max-chars, -m <string>   Maximum number of characters for bars
                --reverse-sort, -r            Sort in Reverse

To print the top 20 instructions in a RISC-V ELF binary:

rv-bin histogram -I -b -c █ linux/vmlinux | head -20

To print the top 20 registers in a RISC-V ELF binary:

rv-bin histogram -R -b -c █ linux/vmlinux | head -20

RISC-V Metadata Utility

The RV source and documentation generator usage command line options:

$ rv-meta -h
usage: rv-meta [<options>]
                        --help, -h            Show help
                  --isa-subset, -I <string>   ISA subset (e.g. RV32IMA, RV32G, RV32GSC, RV64IMA, RV64G, RV64GSC)
                    --read-isa, -r <string>   Read instruction set metadata from directory
                  --no-comment, -N            Don't emit comments in generated source
           --numeric-constants, -0            Use numeric constants in generated source
         --print-constraints-h, -XC           Print constraints header
            --print-fpu-test-h, -FH           Print FPU test header
            --print-fpu-test-c, -FC           Print FPU test source
              --print-interp-h, -V            Print interpreter header
                 --print-jit-h, -J            Print jit header
                --print-jit-cc, -K            Print jit source
   --substitute-question-marks, -?            Substitute question marks for zeros in LaTeX output
                 --print-latex, -l            Print LaTeX instruction listing
                       --color, -c            Enable ANSI color map
                   --print-map, -m            Print instruction map
      --print-map-pseudocode-c, -mc           Print instruction map with C pseudocode
    --print-map-pseudocode-alt, -ma           Print instruction map with alternate pseudocode
              --print-markdown, -md           Print instruction reference in markdown
                --print-meta-h, -H            Print metadata header
               --print-meta-cc, -C            Print metadata source
            --print-operands-h, -A            Print operands header
             --print-strings-h, -SH           Print strings header
            --print-strings-cc, -SC           Print strings source
              --print-switch-h, -S            Print switch header

To print a colour opcode map for the RV32IMA ISA subset:

rv-meta -I RV32IMA -m -c -r meta

To print a colour opcode map for the RV64IMAFDS ISA subset:

rv-meta -I RV64IMAFDS -m -c -r meta

To output LaTeX for the RV32C ISA subset:

rv-meta -I RV32C -l -r meta

To output LaTeX for the RV64G ISA subset:

rv-meta -I RV64G -l -r meta

References

rv8's People

Contributors

acw1251 avatar charizard71 avatar michaeljclark avatar mwachs5 avatar nurelin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rv8's Issues

Add Win64 Virtual{Alloc,Protect,Free} wrappers for mmap,munmap,mprotect

The current emulator code has been written with Win64 in mind however current testing is being performed on macOS, Linux and FreeBSD. There are some sections of code that need to be abstracted.

The POSIX ABI proxy currently works with the Windows Services for Linux emulation layer however it can be ported to Win64 by using a subset of the Windows compatible POSIX APIs. e.g. std::thread but no fork.

The privileged emulator (when complete) can be made to run as a native Win64 application as it only needs to emulate virtual hardware (timer, framebuffer, virtio block, virtio net), not the POSIX API.

The primary changes required at present are memory mapping abstractions for Virtual{Alloc,Protect,Free} and mmap/munmap/mprotect.

Platform neutral type aliases are defined in asm/riscv-types.h instead of using stdint.h types due to the use of signed long int and unsigned long int for s64 and u64 by some library headers. The asm/riscv-types.h definitions are compatible with ILP32, LLP64 and LP64, which supports Windows and SVR4 ABIs for x86 and RISC-V.

    typedef signed int         s32;
    typedef unsigned int       u32;
    typedef signed long long   s64;
    typedef unsigned long long u64;

The minimum Windows target will be Visual Studio Community 2015.

Fail run make in centos machine

Im tried run the make in centos machine but a have the next error. Somebody can help me.

 AR build/linux_x86_64/lib/libasmjit_x86.a
 CC build/linux_x86_64/obj/mem/mmap-linux.o
 CC build/linux_x86_64/obj/mem/mmap-core.o
src/mem/mmap-core.c:31:47: error: ‘MAP_ANONYMOUS’ undeclared here (not in a function)
 static const int METADATA_FLAGS = MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE;
                                               ^~~~~~~~~~~~~
make: *** [Makefile:719: build/linux_x86_64/obj/mem/mmap-core.o] Error 1

Add per instruction cycle metadata for cycle count approximation

An initial implementation of cycle metadata would add an additional file meta/opcode-cycles that contains an opcode and a constant number of cycles.

It could be rigged so that the cycle count is a C style expression that has access to the instruction operands. eg mul "log_2(rs1)" (or an appropriate expression for the implementation). Load and Store instructions may also similarly be exposed to variables representing a simple cache model e.g. cache_hit. Latency needs to be considered eventually however an initial model may provide a simple approximation of cycles.

lui    1
auipc  1
jalr   2
beq    2
bne    2
blt    2
jal    2
lb     "cache_hit * 2 + (1-cache_hit) * 50"
lh     "cache_hit * 2 + (1-cache_hit) * 50"
lw     "cache_hit * 2 + (1-cache_hit) * 50"

Fix OS X custom allocator interception

libSystem default zone seems to allocate some memory before we get a chance to change the default allocator. Some libSystem default zone allocations appear to collide with the translated guest address space due to the zero page size being reduced.

-Wl,-pagezero_size,0x1000 -Wl,-no_pie -image_base 0x10000000000

libSystem allocator doesn't start the heap after the application text and instead allocates low memory. Heap corruption can be seen when trapping into the debug CLI in rv-sim or rv-jit on OS X (the two programs that use custom allocators).

No problem exists with the malloc hooks on Linux.

Implement alternative LaTeX instruction table generator

Add a LaTeX instruction table generator that uses some of the additional metadata

  • use C-based pseudo code from meta/opcode-pseudocode-c
  • use math based pseudo code from meta/opcode-pseudocode-alt
  • translate math based pseudo code to LaTeX using meta/notation
  • use instruction names from meta/opcodes-fullnames
  • use instruction descriptions from meta/opcodes-descriptions
  • add immediate decode diagrams (TikZ/PGF _1,_2,*3)

[1] http://www.texample.net/media/pgf/builds/pgfmanualCVS2012-11-04.pdf
[2] http://hastebin.com/ziketikusa.tex
[3] http://i.cubeupload.com/g1J0Vi.png

Add output buffering, labels, relocation and execution to the JIT API

The JIT API currently just checks instruction operands and emits the instruction.

  • Add simple buffer implementation to collect JIT output
  • Add support for labels, and link step
  • Add mprotect handling (W^X) so output JIT can be executed
  • Add host ABI trampoline for calling JIT with arguments and return value

Including reserved space in rv-meta output?

Is there a way to get rv-meta to output the reserved regions of the RISC-V spec in the various tables it outputs?

If not, what do you think would be the best way to add such a feature?

Implement lazy sign extension for 32-bit operations on RV64

The following 32-bit operations are required to sign extend their results:

  • addw, subw, mulw, divw, remw, divuw, remuw, sllw, srlw, sraw, addiw, slliw, srliw, sraiw

The code currently emits sign extension code after each operation. If the emitter keeps track of the width of the last operation, it would be possible to sign extend the register lazily either when it is used as input to a 64-bit operation or at a branch tail or the end of a trace.

Implement optimized operand immediate decoder (PEXT/PDEP)

Add generator to generate encode and decode template specialisations using BMI2 PEXT/PDEP

  • use riscv-host to check for Intel BMI2 support
  • add mechanism to select optimized decoder template

The application currently does not use polymorphism, rather there will be x86 host optimized templates and the instantiation will be selected statically so there is no virtual function call overhead.

The use of virtual is discouraged, and is presently only used in the src/model and src/gen i.e. not in code that is in the fast path.

compress-elf static translation and relocation for well formed subset of static PIE ELF

compress-elf is currently only able to translate very simple ELF executables. There are still issues with ambiguities between constants and addresses, and translated function addresses within ELF data segments.

Further investigation and potential compiler tuning to create a RISC-V target that can be statically translated. e.g. resolve static translation ambiguities using a well formed subset of RISC-V that can differentiate pointers vs integrals (LUI vs AUIPC), and resolve indirect call targets via symbol metadata. e.g. ELF debug symbols / DWARF.

This research into static translation will be feed into a future region or trace based dynamic translator.

Implement address translation in emu/riscv-mmu.h

Implement instruction fetch, loads and stores using current privilege level and flags e.g. MSTATUS.{MPRV,PUM,MXR,VM}

  • fetch_inst
  • load
  • store
  • walk_page_table

Implement a minimal subset of PMA with PMP attributes (emu/riscv-pma.h) to protect M-mode PA from S-mode.

switch (proc.mstatus.vm) {
    case riscv_vm_mbare: /* TODO */ break;
    case riscv_vm_mbb:   /* TODO */ break;
    case riscv_vm_mbid:  /* TODO */ break;
    case riscv_vm_sv32:  /* TODO */ break;
    case riscv_vm_sv39:  /* TODO */ break;
    case riscv_vm_sv48:  /* TODO */ break;
}

Changes on registers names

The RISC-V Instruction Set Manual
Volume II: Privileged Architecture
Document Version 20190608-Priv-MSU-Ratified

mbadaddr : -> mtval?
The mbadaddr register has been subsumed by a more general mtval register that can now
capture bad instruction bits on an illegal instruction fault to speed instruction emulation.
(Preface to Version 1.10 - Page 5)

mbase : ?
mibase : ?
mdbase : ?
mbound : ?
mibound : ?
mdbound : ?

sptbr : -> satp
The supervisor virtual memory configuration has been moved from the mstatus register to
the sptbr register. Accordingly, the sptbr register has been renamed to satp (Supervisor
Address Translation and Protection) to reflect its broadened role.
(Preface to Version 1.10 - Page 5)

sbadaddr : stval?

thanks for reading and for the great work done with the simulator!

Add more-detailed meta information for CSRs.

Currently, meta/csrs contains basic information about CSRs such as numbers, permissions, and names. meta/enums also lists some of the specific fields of CSRs, such as the possible values and meanings of, for example, mstatus.fs. However, information about the structure of CSRs, such as the location of fields (e.g. which bits of mstatus correspond to fs?) is non-existent in meta/. Currently, this information exists in emu/processor-priv-1.9.h for a few machine-level CSRs.

It would be useful to have this information (along with information about whether a field is WIRI, WPRI, WLRL, or WARL) encoded in plain text in meta/, possibly in the style of meta/operands.

Implement simple RV{32,64,128} test-assembler

To test RV128I in the absence of compiler and binutils support, it will likely take less effort to implement a very simple metadata driven assembler.

The following pieces already exist: string tables, opcode and operand format metadata, pseudo instruction metadata and encoder, compression metadata and encoder, instruction encoders, assembly-like format parser, operand limit verifiers, label support (in riscv-compress-elf) and ELF output support already exist.

In addition to the RISC-V assembly formats that exist in the disassembler, the following directives, label formats and addressing modes need to be implemented to enable compilation of simple test cases:

Directives

Directive Arguments Description
.align integer section alignment
.file "filename" emit filename FILE LOCAL symbol table
.globl symbol_name emit symbol_name NOTYPE? GLOBAL to symbol table
.ident "string" ignore
.section [{.text,.data,.rodata,.bss}] emit section header in argument (if not present, default .text) and make current
.size symbol, symbol ignore
.text emit .text section (if not present) and make current
.data emit .data section (if not present) and make current
.rodata emit .rodata section (if not present) and make current
.bss emit .bss section (if not present) and make current
.string "string" emit string
.type symbol, @function ignore
.option {rvc,norvc,push,pop} RISC-V options
.half 16-bit word
.word 32-bit word
.dword 64-bit word
.dtprelword 32-bit thread local word
.dtpreldword 64-bit thread local word
.p2align p2,[pad_val=0],max power of 2 align
.balign b,[pad_val=0] byte align

Labels

text labels:

labels:

numeric labels for 1f, 1b type expressions:

1:

Addressing modes

absolute addressing

        lui a1, %hi(msg)            # load msg(hi)
        addi a1, a1, %lo(msg)       # load msg(lo)

relative addressing

1:      auipc a1, %pcrel_hi(msg)    # load msg(hi)
        addi a1, a1, %pcrel_lo(1b)  # load msg(lo)

Fix issue with jit-fusion on test-miniz and enable in rv-jit

jit-fusion.h contains a simple state machine that matchs CALL (AUIPC+JALR) and LA (AUIPC+ADDI) to coalesce them into one single operation. It is intended that the state machine can coalesce other instruction sequences however there is currently a bug in the fusion state machine that appears on test-miniz so it is currently disabled.

git diff 452537c51871d6f5670d22b32153e6f294411b6f..edd60409afead0f95628985c98fcb58e0811c000
--- a/src/app/rv-jit.cc
+++ b/src/app/rv-jit.cc
@@ -91,13 +91,13 @@ using proxy_model_rv32imafdc = processor_rv32imafdc_model<
        jit_decode, processor_rv32imafd, mmu_proxy_rv32>;
 using proxy_jit_rv32imafdc = jit_runloop<
        processor_proxy<proxy_model_rv32imafdc>,
-       jit_fusion<jit_emitter_rv32<proxy_model_rv32imafdc>>>;
+       jit_emitter_rv32<proxy_model_rv32imafdc>>;
 
 using proxy_model_rv64imafdc = processor_rv64imafdc_model<
        jit_decode, processor_rv64imafd, mmu_proxy_rv64>;
 using proxy_jit_rv64imafdc = jit_runloop<
        processor_proxy<proxy_model_rv64imafdc>,
-       jit_fusion<jit_emitter_rv64<proxy_model_rv64imafdc>>>;
+       jit_emitter_rv64<proxy_model_rv64imafdc>>;
 
 /* environment variables */

Problem of using function printf for 32bits compiler.

I'm trying to use rv8 to run codes that are compiled by 32bits compiler. My 32bits compiler is built using --with-arch=rv32gc and --with-abi=ilp32d. And the version of my compiler is 7.2.0. I find the output of rv8/src/test/test-fpu-printf.c is not correct.

The content of test-fpu-printf.c:

#include <stdio.h>

int main()
{
	float f1 = 1.0f;
	float f2 = 3.0f;
	float f3 = f1 / f2;
	printf("%.9ef ÷ %.9ef = %.9ef\n", f1, f2, f3);
}

I set RISCV as the path of the 32bits compiler, and run make test-build-rv32 to compile codes.

I also use objdump to see the generated assembly instructions:

test-fpu-printf:     file format elf32-littleriscv


Disassembly of section .text:

00010074 <main>:
   10074:	1101                	addi	sp,sp,-32
   10076:	0000b797          	auipc	a5,0xb
   1007a:	37a7b787          	fld	fa5,890(a5) # 1b3f0 <__clzsi2+0x40>
   1007e:	a43e                	fsd	fa5,8(sp)
   10080:	0000b797          	auipc	a5,0xb
   10084:	3787b787          	fld	fa5,888(a5) # 1b3f8 <__clzsi2+0x48>
   10088:	4822                	lw	a6,8(sp)
   1008a:	48b2                	lw	a7,12(sp)
   1008c:	a43e                	fsd	fa5,8(sp)
   1008e:	0000b697          	auipc	a3,0xb
   10092:	3726b787          	fld	fa5,882(a3) # 1b400 <__clzsi2+0x50>
   10096:	4722                	lw	a4,8(sp)
   10098:	47b2                	lw	a5,12(sp)
   1009a:	a43e                	fsd	fa5,8(sp)
   1009c:	4622                	lw	a2,8(sp)
   1009e:	46b2                	lw	a3,12(sp)
   100a0:	0000b517          	auipc	a0,0xb
   100a4:	36850513          	addi	a0,a0,872 # 1b408 <__clzsi2+0x58>
   100a8:	ce06                	sw	ra,28(sp)
   100aa:	24bd                	jal	10318 <printf>
   100ac:	40f2                	lw	ra,28(sp)
   100ae:	4501                	li	a0,0
   100b0:	6105                	addi	sp,sp,32
   100b2:	8082                	ret


But the otuput is:
image

Besides, I don't know why the compiler emits fld and fsd instructions. Since the variables f1 and f2 are float, the compiler should use flw and fsw.

rv-sim build/riscv64-unknown-elf/bin/hello-world-libc

I tried the above command from all the directories including home and root, riscv,rv8--etc. It keeps giving me the error no such file or directory. can someone help me to generate logfiles and histograms for my elf files or please let me know how to execute the commands like this "rv-sim build/riscv64-unknown-elf/bin/hello-world-libc".

Thanks in advance.

Add (draft) ELF128 definitions

ELF128

There needs to be some discussion around how ELF is mapped to 128-bit, given that there may be ABI variants, and there is a distinction between 128-bit integrals vs 128-bit pointers. i.e. An ELF128 ABI could potentially have an 'offset' concept that is a compact memory representation of a 'pointer' relative to some base pointer.

e.g. define Elf128_Off as u64 as this represents an offset within the ELF image, and likewise define Elf128_Xword and Elf128_Sxword as u64 and s64 respectively, as these are used for segment sizes.

This proposed typing based on ELF64 only promotes the Addr type to 128. Linkers and link loaders may store 'offsets' relative to some reference address. e.g. start of segment.

Draft Elf128 types

  • typedef u128 Elf128_Addr;
  • typedef u16 Elf128_Half;
  • typedef u64 Elf128_Off;
  • typedef s32 Elf128_Sword;
  • typedef u32 Elf128_Word;
  • typedef u64 Elf128_Xword;
  • typedef s64 Elf128_Sxword;
  • typedef u8 Elf128_Byte;

Remove branches and ternary operators from 128-bit operators and pseudocode-c

The 128-bit shift instructions in asm/riscv-operators.h and meta/opcode-pseudocode-c do not all generate constant time assembly (i.e. avoid branch instructions that may leak timing information). The ternary operators need to be replaced with constant time bitwise predicate logic.

A separate version of pseudocode-c may be added that contains simpler to read non predicate form logic that excludes the special cases for NaN, divide by zero, underflow and overflow.

  • all operators used in cryptographic code should be constant time at the expense of performance.
  • an alternative fast math option may be provided that sacrifices precision and the constant time constraint for performance.

Add byte order macros to emu/riscv-{machine,pte}.h

The current bitfield structs in emu/riscv-machine.h and emu/riscv-pte.h require endian macros in a similar fashion to the register structs in emu/riscv-processor.h due to structure bitfield order differences for different emulator host endianness.

#if _BYTE_ORDER == _LITTLE_ENDIAN
    /* */
#else
    /* */
#endif

The alternative is to define enums with bit positions and masks for the various CSRs with sub fields.

The original intent behind using the structure bitfields is that it lends itself to nicer pseudo-code e.g. mstatus.MPRV vs (mstatus & MPRV_MASK)

Support for sorting the rv-meta output?

I was wondering if you would be interested in supporting sorting the output of rv-meta in different ways?

I'm interested in sorted the output via opcode + funct values. (FYI - I'm also interested in knowing if a funct3 / opcode space is fully populated.)

I can imaging wanting to sort by extension and instruction format too.

RiscV rv-sys rv8 potential bug ( TRAP :breakpoint pc:0x112c badaddr:0x112c)

I am working on instruction profile (frequency of instruction) of typical programs and required your program to simulate and make histograms of dynamic instructions that are run on a processor using RiscV executable file. I successfully installed rv8 and riscv-tools but was not able to run a typical hello world program and got the following error,

TRAP :breakpoint pc:0x112c badaddr:0x112c

when I tried running using the command, rv-sys --instruction-usage-histogram helloworld.
I tried to remove printf and scanf in the possibility of rv-sys not supporting system calls but got the same error. I also tried to include -static option to the cross-compiler but with no success.
I tried to get the total instruction count of helloworld using spike pk -s and was able to run the program and get the total dynamic instruction counts. (helloworld seems to be cross-compiled correctly).
I compiled using the tool, riscv64-unknown-elf-gcc

Contents of the file:

#include <stdio.h>

int main(void)
{
printf("Hello Riscv Word!");
return 0;
}

Details:
Ubuntu 16.04 LTS 64-bit
i7-6700 HQ
16 GB DDR4 RAM
UEFI System
GPT Partitioning
Asus ROG GL552VW-CN230T

PS.

I even tried to use the tool rv-sim --instruction-usage-histogram but was not able to get the required histograms. I got only the output specified in the program hello.c.
I tried to run the testing program provided bbl by using the tool rv-sys, but was not able to run it (Terminal gave no output and seemed to be stuck (not frozen)).
I tried on a virtual and a native host machine both, getting the same result.

Replace test-emulate std::mt19937 PRNG with a CSPRNG such as SHA-512

The emulator can use a user supplied seed or hardware random to seed a PRNG to create entropy in all integer registers excluding sp (1920 bit for RV64). sp holds a reference to a (temporary) stack.

In haste a PRNG was used over a CSPRNG as there are no digest algorithms in the standard library. This will be replaced with a CSPRNG such as SHA-2 (SHA-512).

For simulation purposes the use of the mersenne twister PRNG is sufficient however a CSPRNG should be used for productionised binary translation.

Implement M and S mode CSRs and address translation

Implement the privileged CSRs and address translation modes from priv-1.9.

The privileged implementation will primarily involve these files:

  • src/app/riscv-test-emulate.cc
  • src/emu/riscv-mmu.h
  • src/emu/riscv-machine.h

Snippet from src/emu/riscv-mmu.h

        template <typename P> u64 fetch_inst(P &proc, UX pc)
        {
            return 0; // TODO
        }

        // T is one of u64, u32, u16, u8
        template <typename P, typename T, bool aligned> bool load(P &proc, UX va, T &val)
        {
            return false; // TODO
        }

        // T is one of u64, u32, u16, u8
        template <typename P, typename T, bool aligned> bool store(P &proc, UX va, T val)
        {
            return false; // TODO
        }

        // T is one of u64, u32, u16, u8
        template <typename P> uintptr_t translate_addr(P &proc, UX va)
        {
            switch (proc.mstatus.vm) {
                case riscv_vm_mbare: /* TODO */ break;
                case riscv_vm_mbb:   /* TODO */ break;
                case riscv_vm_mbid:  /* TODO */ break;
                case riscv_vm_sv32:  /* TODO */ break;
                case riscv_vm_sv39:  /* TODO */ break;
                case riscv_vm_sv48:  /* TODO */ break;
            }
            return -1;
        }

        // PTM is one of sv32, sv39, sv48
        template <typename PTM> bool walk_page_table(UX va, typename PTM::pte_type &pte)
        {
            return false; // TODO
        }

Decoder performance experiment

Reduce size of decode structure in asm/riscv-codec.h from 16 bytes to 12 bytes with the intention of increasing decode performance. The immediate can also be stored as a signed 32 bit value.

The current decode model was based primarily around compression and it decodes all items from the instruction into the decode structure, including registers which have fixed locations in the Base ISA.

The proposal is to change the decode structure so that the fixed place items (registers) are no longer decoded until access (using bitfield unions) and to make changes to the interpreter generator to reference the registers within union structures. This will reduce the decode memory bandwidth and reduce the number of host instructions (icache pressure) required to decode an instruction, however inlining may increase icache pressure as there will be shift/and to access registers within each emulated instruction instead of in the codec.

This new proposal, while it saves space for the decoded immediate and registers, requires an additional 2 bytes to store the compressed version of the instruction (which will be zeroed if not compressed) as the 32-bit instruction will be used to store the decoded operands for compressed instructions. Primarily this approach defers register decode nearer to instruction execution and cache locality for operand access to the instruction.

32 bytes

  • 4 bytes (encoded instruction)
  • 4 bytes (decoded operands)
  • 4 bytes (redundant immediate bits)
  • 2 bytes (compressed instruction)

Register assignments within the Base ISA codecs (asm/riscv-decode.h and asm/riscv-encode.h) will be removed for the IMAFD i.e. they will only be required to decode the immediate as the registers will be referenced in place. This change will also allow the inst field to be removed from asm/riscv-disasm.h and will reduce struct disasm it from 32 bytes to 20 bytes.

Compressed instructions will need to store their instruction in a 16-bit element so that their operands can be decompressed into the union register aliases.

Disadvantage with this approach is that it will no longer be possible to have byte addresses for the register operands. The existing approach may be better suited to binary translation?

Alternative: use 64-bit union with inst_64, inst_32 and inst_16, to allow decode of 48-bit and 64-bit instructions. Size would remain 16 bytes for the structure however the decode order and 32-bit base ISA codecs would be simplified. i.e. registers can be accessed in place.

    struct decode
    {
        int32_t imm    : 32;
        union {
            uint32_t inst_32   : 32;
            struct {
                /* register and operands bit field */
            } operand;
        } base;
        uint32_t inst_16   : 16;
        uint32_t  op    : 8;
        uint32_t  codec : 8;
        /* uint32_t  rd    : 5; // move into union that aliases inst_32 */ 
        /* uint32_t  rs1   : 5; // move into union that aliases inst_32 */ 
        /* uint32_t  rs2   : 5; // move into union that aliases inst_32 */ 
        /* uint32_t  rs3   : 5; // move into union that aliases inst_32 */ 
        /* uint32_t  rm    : 3; // move into union that aliases inst_32 */ 
        /* uint32_t  aq    : 1; // move into union that aliases inst_32 */ 
        /* uint32_t  rl    : 1; // move into union that aliases inst_32 */ 
        /* uint32_t  pred  : 4; // move into union that aliases inst_32 */ 
        /* uint32_t  succ  : 4; // move into union that aliases inst_32 */ 
    };

Implement command line, env and auxv stack setup for proxy emulator

The proxy emulator needs the stack frame setup so that command line arguments and environment can be read from the host system. The current stack frame is just a empty stack that allows running programs with no command line arguments. The host environment passed to the emulator should be verified (a selected subset).

   STACK TOP
   env data
   arg data
   padding, align 16
   auxv table, AT_NULL terminated
   envp array, null terminated
   argv pointer array, null terminated
   argc <- stack pointer

Ioctl handling seems to be a stub

Hi,

Having fun and playing with the idea of generating graphics with linux framebuffer and riscv assembly code of my computer. I already got my random generator to flush the screen with noise. But it's handcoded with the buffer size. I stumbled upon the ioctl calls not seeming to work.

Peeked into the rv8 src/abi/. It looks like the ioctl only supports one command and for everything else it's been programmed to give EINVAL.

The ioctl commands I tried to get to work:

FBIOGET_VSCREENINFO = 0x4600
FBIOGET_FSCREENINFO = 0x4602

The code I tried:

addi sp, sp, -fb_fix_screeninfo_size
mv a0, gp                           # fbfd
li a1, FBIOGET_VSCREENINFO
mv a2, sp                           # The screeninfo size pointer. 
li a7, sys_ioctl
ecall
blt a0, zero, fail

Could add few lines into the rv8 to make this work. But should I? It feels laborious to add some check for every single one ioctl that's been used by Linux.

Add riscv128 opcodes

RV128I

  • LDU, LQ (OP-LOAD, funct3[14:12]=Q.width)
  • SQ (OP-STORE, funct3[14:12]=Q.width)
  • ADDD, SUBD, SLLD, SRLD, SUBD, SRAD (OP-64)
  • ADDID, SLLID, SRLID, SRAID (OP-IMM-64)

RV128M

  • MULD, DIVD, DIVUD, REMD, REMUD (OP-64)

RV128A

  • LR.D, SC.D, AMO{*}.D (OP-AMO, funct3[14:12]=Q.width)

RV32Q, RV64Q

  • FLQ (OP-LOAD-FP, funct3[14:12]=Q.width)
  • FSQ (OP-STORE-FP, funct3[14:12]=Q.width)
  • F{*}.Q (OP-FP, fmt[26:25]=Q.fmt)

RV128FDQ

  • FCVT.{F,D,Q}.C (OP-FP, funct5[31:27]={{F,D,Q}.C}, fmt[26:25]={S,D,Q})
  • FCVT.{F,D,Q}.CU (OP-FP, funct5[31:27]={{F,D,Q}.CU}, fmt[26:25]={S,D,Q})
  • FCVT.C.{F,D,Q} (OP-FP, funct5[31:27]={C.{F,D,Q}}, fmt[26:25]={S,D,Q})
  • FCVT.CU.{F,D,Q} (OP-FP, funct5[31:27]={CU.{F,D,Q}}, fmt[26:25]={S,D,Q})

Fix or replace TLSF allocator to support 16-byte alignment for SSE4.2/AVX

The meta emulator uses the TLSF memory allocator: https://github.com/mattconte/tlsf

It does this due to the non default link location to allow loading RISC-V executables into the lower part in the non privileged common address space proxy model (not --privileged which currently implements a soft-mmu).

MACOS_LDFLAGS = -Wl,-pagezero_size,0x1000 -Wl,-no_pie -image_base 0x40000000
LINUX_LDFLAGS = -Wl,--section-start=.text=0x40000000 -static

The platform allocator is not guaranteed to adjust its allocation area for the new text segment location so we implement a custom allocator that is the same on all platforms.

The issue is Clang generates code like this on x86_64, which requires allocations to be 16-byte aligned:

0000000040068f1e	movaps	%xmm0, 0x70(%rbx)
0000000040068f22	movaps	%xmm0, 0x60(%rbx)
0000000040068f26	movaps	%xmm0, 0x50(%rbx)
0000000040068f2a	movaps	%xmm0, 0x40(%rbx)

There are some pretty deep assumptions made in the TLSF allocator around 4 and 8 byte alignment so the allocator may need to be changed for a more flexible and thread-safe cross platform allocator.

Reconcile asmjit and dlmalloc custom allocators

The base address for the asmjit allocator is currently hardcoded in asmjit/src/asmjit/base/osutils.cppand the base address for the dlmalloc allocator is hardcoded in src/mem/osmorecore.cc.

asmjit needs an interface to pass the mmap base address to JitRuntime / CodeHolder / VMemMgr in asmjit/src/asmjit/base/vmem.cpp.

Consider replacing dlmalloc with tcmalloc.

Add support for multiple extensions in opcodes e.g. RVC FPU instructions

Currently all RVC instructions are labeled with either rv32c or rv64c however some of the compressed opcodes depend on the F or D extensions.

Update meta/opcodes labels on compressed floating point instructions to use rv32cf, rv32cd, rv64cf, rv64cd labels and update the model to interpret multiple suffixes as an 'and' of the extensions.

  • RV32IMAC selects rv32c
  • RV32IMAFC selects rv32c and rv32cf
  • RV64IMAFDC selects rv64c, rv64cf and rv64cd

Implement standard operator overloads for u128 and s128

Complete compiler agnostic u128 and s128 integer operation support.

Implement using operator overloads so that the riscv128 C pseudo-code generated interpreter will work unchanged in terms of the currently defined type system. e.g.

  • ==, !=, <, >= (for both s128 and u128)
  • +, -, bitwise logical operations, bit shifts (for both s128 and u128)

Crash while running tests

  • make test-sim
  • make test-sys
  • rv-jit build/riscv64-unknown-elf/bin/test-dhrystone

All of them crash with an error message illegal hardware instruction (core dumped)

I'm guessing jit emits instructions from sse3 or higher.

Cpu: Intel(R) Core(TM)2 Duo CPU T5900 @ 2.20GHz with flags fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good nopl cpuid aperfmperf pni dtes64 monitor ds_cpl est tm2 ssse3 cx16 xtpr pdcm lahf_lm pti dtherm

Edit: It looks like it crashes here on __asm__ volatile ("rdtscp\n" : "=a" (a), "=d" (d));

Implement additional proxy syscalls

Proxy syscalls are currently defined in src/abi/riscv-unknown-abi.h to match the riscv-unknown-elf toolchain.

The target syscall set is the minimum set required to run apache with mod_ssl / openssl.

Instruction sequence for bit sign extention

I think that you can perform bit sign extension in fewer instructions than claimed. I'm using an ARMish syntax here (since that's what I'm familiar with...)

; a0: argument
; a1: value less than XLEN for the bit position to be extended
addi a1 a1 #-32 ; Assuming 32-bit arch. For RV64 or 128, replace as appropriate
neg a1 a1
sll a0 a0 a1
sra a0 a0 a1

Similarly, for signed bit extend by an immediate, you can just perform the left shift and arithmetic right shift.

Change debug and panic macros to use fmt infrastructure

The debug and panic macros currently use varargs and require length identifiers on integrals.

The new fmt interface is similar to Go and does not require length modifiers for fmt parameters. All integer parameters are sign extended to the largest integer type and are boxed with type width information using CTTI (Compile Time Type Identification).

PRIxPTR, PRIdPTR, PRIuPTR can be replaced with %x, %d and %u
PRIxPTR, PRIdPTR, PRIuPTR can be replaced with %x, %d and %u

'll' or 'l' modifiers can be removed

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.