Skip to content

Add RISC-V exception handler for MARS kernel #1247

Merged
merged 44 commits into from
Mar 5, 2020
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
b907a7d
add myself to the members list
exucutional Oct 14, 2019
b4f533d
Merge branch 'master' into master
exucutional Oct 14, 2019
90413c2
fix
exucutional Oct 14, 2019
ecabd56
fix
exucutional Oct 14, 2019
1ebb53f
fix
exucutional Oct 14, 2019
9a0aaa2
merge conflict
exucutional Oct 25, 2019
0105ce5
Merge branch 'master' of https://github.com/MIPT-ILab/mipt-mips
exucutional Jan 28, 2020
7e9a8ba
Add riscv_driver and get_isa method for CPU_model
exucutional Feb 5, 2020
2af9378
Add connect_exception_handler method
exucutional Feb 14, 2020
77ef85a
Use std::string instead of enum for get_isa method
exucutional Feb 14, 2020
3febaf7
Update risc-v driver and add unit-test for it
exucutional Feb 14, 2020
b11f5e8
Add risc-v exception handler
exucutional Feb 14, 2020
5c554a8
Update ecall, ebreak. Add syscalls for exception handler
exucutional Feb 19, 2020
aa3d900
Use superuser's CSR instead of machine. Update ebreak. Make MARS kern…
exucutional Feb 21, 2020
e716e4f
Add copyright
exucutional Mar 1, 2020
4d0194c
Merge branch 'master' of https://github.com/MIPT-ILab/mipt-mips into …
exucutional Mar 2, 2020
26e0011
Add back no lint comments
exucutional Mar 2, 2020
7e2b385
Add build routine for riscv32_le.bin
exucutional Mar 2, 2020
a218cff
Use absolute paths
exucutional Mar 4, 2020
109b270
Add new line in the end of file
exucutional Mar 4, 2020
bedceb3
Move TRAP_VECTOR_BASE_ADDRESS into function
exucutional Mar 4, 2020
581f64f
Use std::string_view for get_isa
exucutional Mar 4, 2020
aa85971
Make set_isa protected
exucutional Mar 4, 2020
2805048
Pass isa directly to simulator ctor
exucutional Mar 4, 2020
84edf52
Move risc-v driver unit-test to a new file. Separate it into two test…
exucutional Mar 4, 2020
434e435
Remove useless include
exucutional Mar 4, 2020
58561b2
Rename risv32_le.bin to riscv32.bin
exucutional Mar 4, 2020
62e21eb
Separate connect_exception_handler into risc-v and mars cases
exucutional Mar 4, 2020
53b7093
Wrap getting trap vector address into function
exucutional Mar 4, 2020
3cdd5fa
Use std::string isa for ownership
exucutional Mar 4, 2020
a721ea0
Use two constructors instead of default parameter
exucutional Mar 4, 2020
c049102
Use hardcoded aligning for trap_vector_address
exucutional Mar 4, 2020
63c0530
Sort includes in lexicographical order
exucutional Mar 4, 2020
a6609f6
Make TBuilder ctor explicit
exucutional Mar 4, 2020
077619b
Initialize isa in ctor
exucutional Mar 4, 2020
8d5801e
throw 'Unsupported ISA' if MARSKernel doesn't support it
exucutional Mar 5, 2020
817cdb7
Make Simulator class responsible for isa initialization
exucutional Mar 5, 2020
58a5112
Add test for MARS unsupported isa
exucutional Mar 5, 2020
f194dda
Add a new line to the end of file
exucutional Mar 5, 2020
2d9a90d
Move include to the header
exucutional Mar 5, 2020
660404f
Do not use default argument
exucutional Mar 5, 2020
021feee
Remove redundant brackets
exucutional Mar 5, 2020
930e292
Make CycleAccurateSimulator ctor explicit
exucutional Mar 5, 2020
a130ac6
Merge branch 'master' of https://github.com/MIPT-ILab/mipt-mips into …
exucutional Mar 5, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions kernels/Makefile
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
# Building MIPS ElF binaries
# Building MIPS and RISC-V ElF binaries
# @author Alexander Titov <[email protected]>
# Copyright 2012-2019 uArchSim iLab Project

MIPS_AS?=mips-linux-gnu-as
MIPS_LD?=mips-linux-gnu-ld

RISCV_AS?=riscv64-unknown-elf-as
AS_FLAGS?=-march=rv32i -mabi=ilp32
RISCV_LD?=riscv64-unknown-elf-ld
LD_FLAGS?=-melf32lriscv --no-relax

# assemble all the object files
build_all: mars32_le.bin
build_all: mars32_le.bin riscv32.bin

mars32_le.bin: mars32_le.o
@$(MIPS_LD) $< -o $@ -EL -pie
Expand All @@ -16,6 +21,13 @@ mars32_le.bin: mars32_le.o
mars32_le.o: exceptions.s Makefile
@$(MIPS_AS) $< -o $@ -O0 -mips64 -no-break -EL -g -KPIC

riscv32.bin: riscv32.o
@$(RISCV_LD) $(LD_FLAGS) $< -o $@
@echo $@ is built

riscv32.o: riscv_exceptions.s
@$(RISCV_AS) $(AS_FLAGS) $< -o $@

# it is needed to preven make from
# deleting .o files automatically
.PRECIOUS: %.o
Expand All @@ -26,6 +38,6 @@ clean:

.PHONY: help
help:
@echo " This makefile build all MIPS assembly files in the directory."
@echo " This makefile build all MIPS and RISC-V assembly files in the directory."
@echo " To do that just type 'make' or 'make build_all'."
@echo " Note that assembly files should have '.s' extension."
Binary file modified kernels/mars32_le.bin
Binary file not shown.
Binary file added kernels/riscv32.bin
Binary file not shown.
112 changes: 112 additions & 0 deletions kernels/riscv_exceptions.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# RISC-V exception handler
# Author Eric Konks
# Copyright 2020 MIPT-V
pavelkryukov marked this conversation as resolved.
Show resolved Hide resolved

.data
__m1_: .string " Exception "
__m2_: .string " Interrupt "
__m3_: .string " occurred\n"

__i0_: .string " [User software interrupt] "
__i1_: .string " [Supervisor software interrupt]"
__i2_: .string " [Reserved for future standard use]"
__i3_: .string " [Machine software interrupt]"
__i4_: .string " [User timer interrupt]"
__i5_: .string " [Supervisor timer interrupt]"
__i6_: .string " [Reserved for future standard use]"
__i7_: .string " [Machine timer interrupt]"
__i8_: .string " [User external interrupt]"
__i9_: .string " [Supervisor external interrupt]"
__i10_: .string " [Reserved for future standard use] "
__i11_: .string " [Machine external interrupt]"

__e0_: .string " [Instruction address misaligned]"
__e1_: .string " [Instruction access fault]"
__e2_: .string " [Illegal instruction]"
__e3_: .string " [Breakpoint]"
__e4_: .string " [Load address misaligned]"
__e5_: .string " [Load access fault]"
__e6_: .string " [Store/AMO address misaligned]"
__e7_: .string " [Store/AMO access fault]"
__e8_: .string " [Environment call from U-mode]"
__e9_: .string " [Environment call from S-mode]"
__e10_: .string " [Reserved]"
__e11_: .string " [Environment call from M-mode]"
__e12_: .string " [Instruction page fault]"
__e13_: .string " [Load page fault]"
__e14_: .string " [Reserved for future standard use]"
__e15_: .string " [Store/AMO page fault]"

__excp: .word __e0_, __e1_, __e2_, __e3_, __e4_, __e5_, __e6_, __e7_, __e8_, __e9_
.word __e10_, __e11_, __e12_, __e13_, __e14_

__intr: .word __i0_, __i1_, __i2_, __i3_, __i4_, __i5_, __i6_, __i7_, __i8_, __i9_
.word __i10_, __i10_, __i11_

.section .text
.globl _start
_start:
csrr t0, scause # Save cause register
not t1, x0
srli t1, t1, 0x1
and t0, t0, t1 # Extract exception code
not t1, t1 # Extract interrupt bit
beqz t1, _not_intr # Branch if not interrupt

# Interrupt-specific code

# Print information about interrupt
li x2, 4 # Syscall 4 (print string)
la x4, __m2_
ecall
li x2, 1 # Syscall 1 (print int)
mv x4, t0
ecall
li x2, 4 # Syscall 4 (print string)
lw x4, %lo(__intr)(t0)
ecall
li x2, 4 # Syscall 4 (print string)
la x4, __m3_
ecall

_not_intr:

# Exception-specific code

# Print information about exception
li x2, 4 # Syscall 4 (print str)
la x4, __m1_
ecall
li x2, 1 # Syscall 1 (print int)
mv x4, t0
ecall
li x2, 4 # Syscall 4 (print string)
lw x4, %lo(__excp)(t0)
ecall
li x2, 4 # Syscall 4 (print string)
la x4, __m3_
ecall

# 0x2 Illegal insruction
li t1, 2
beq t0, t1, _terminate

# 0x0 Instruction Address misaligned
bnez t0, _ok_pc # Branch if exception code != 0
csrr t0, sepc
andi t0, t0, 3 # Word-aligning check
beqz t0, _ok_pc # Branch if EPC word-aligned
j _terminate

_terminate:
li x2, 0xA # Syscall 10 (exit)
ecall

_ok_pc:

_return:
csrwi scause, 0 # Clear cause register
csrr t0, sepc
addi t0, t0, 4 # Skip instruction to avoid infinite loop
csrw sepc, t0
sret # Return from exception
2 changes: 2 additions & 0 deletions simulator/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ set(TESTS_CPPS
risc_v/riscv_register/t/unit_test.cpp
risc_v/t/unit_test.cpp
risc_v/t/riscv64_test.cpp
risc_v/t/riscv32_driver_test.cpp
func_sim/rf/t/unit_test.cpp
func_sim/traps/t/unit_test.cpp
func_sim/driver/t/unit_test.cpp
Expand Down Expand Up @@ -171,6 +172,7 @@ add_library(mipt-mips-src OBJECT
mips/mips_driver.cpp
risc_v/riscv_register/riscv_register.cpp
risc_v/riscv_instr.cpp
risc_v/riscv_driver.cpp
export/gdb/gdb_wrapper.cpp
export/cen64/cen64_wrapper.cpp
export/cache/runner.cpp
Expand Down
1 change: 1 addition & 0 deletions simulator/export/gdb/gdb_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ GDBSim::GDBSim( const std::string& isa)
cpu->set_kernel( kernel);
kernel->set_simulator( cpu);
kernel->connect_memory( memory);
kernel->connect_exception_handler();
}

bool GDBSim::load( const std::string& filename) const try
Expand Down
3 changes: 2 additions & 1 deletion simulator/export/standalone/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ int Main::impl( int argc, const char* argv[]) const {
sim->write_csr_register( "mscratch", 0x400'0000);

auto kernel = Kernel::create_configured_kernel();
kernel->connect_memory( memory);
kernel->set_simulator( sim);
kernel->connect_memory( memory);
kernel->connect_exception_handler();
kernel->load_file( config::binary_filename);
sim->set_kernel( kernel);

Expand Down
3 changes: 2 additions & 1 deletion simulator/func_sim/func_sim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@
#include <stdexcept>

template <typename ISA>
FuncSim<ISA>::FuncSim( Endian endian, bool log)
FuncSim<ISA>::FuncSim( Endian endian, bool log, std::string_view isa)
: BasicFuncSim()
, imem( endian)
, driver( ISA::create_driver( this))
{
set_isa( isa);
if ( log)
sout.enable();
}
Expand Down
2 changes: 1 addition & 1 deletion simulator/func_sim/func_sim.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class FuncSim : public BasicFuncSim
void write_register( Register index, uint64 value) { rf.write( index, narrow_cast<RegisterUInt>( value)); }

public:
FuncSim( Endian endian, bool log);
FuncSim( Endian endian, bool log, std::string_view isa = "");
pavelkryukov marked this conversation as resolved.
Show resolved Hide resolved

void set_memory( std::shared_ptr<FuncMemory> memory) final;
void set_kernel( std::shared_ptr<Kernel> k) final { kernel = std::move( k); }
Expand Down
10 changes: 9 additions & 1 deletion simulator/func_sim/t/unit_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ static auto run_over_empty_memory( const std::string& isa)
auto kernel = Kernel::create_dummy_kernel();
kernel->set_simulator( sim);
kernel->connect_memory( m);
kernel->connect_exception_handler();
kernel->load_file( TEST_PATH "/mips-tt-no-delayed-branches.bin");
sim->set_kernel( kernel);
return sim->run( 30);
Expand All @@ -48,6 +49,7 @@ TEST_CASE( "FuncSim: get lost without pc")
auto kernel = Kernel::create_dummy_kernel();
kernel->set_simulator( sim);
kernel->connect_memory( m);
kernel->connect_exception_handler();
kernel->load_file( TEST_PATH "/mips-tt-no-delayed-branches.bin");
sim->set_kernel( kernel);
CHECK_THROWS_AS( sim->run_no_limit(), BearingLost);
Expand All @@ -63,6 +65,7 @@ TEST_CASE( "Process_Wrong_Args_Of_Constr: Func_Sim_init_and_load")
auto kernel = Kernel::create_dummy_kernel();
kernel->set_simulator( sim);
kernel->connect_memory( mem);
kernel->connect_exception_handler();
kernel->load_file( TEST_PATH "/mips-tt-no-delayed-branches.bin");
sim->set_kernel( kernel);
CHECK_NOTHROW( sim->set_pc( kernel->get_start_pc()) );
Expand All @@ -77,6 +80,7 @@ TEST_CASE( "Make_A_Step: Func_Sim")
auto kernel = Kernel::create_dummy_kernel();
kernel->set_simulator( sim);
kernel->connect_memory( mem);
kernel->connect_exception_handler();
kernel->load_file( TEST_PATH "/mips-tt-no-delayed-branches.bin");
sim->set_kernel( kernel);

Expand All @@ -98,6 +102,7 @@ TEST_CASE( "Run one instruction: Func_Sim")
auto kernel = Kernel::create_dummy_kernel();
kernel->set_simulator( sim);
kernel->connect_memory( mem);
kernel->connect_exception_handler();
kernel->load_file( TEST_PATH "/mips-tt-no-delayed-branches.bin");
sim->set_kernel( kernel);

Expand Down Expand Up @@ -147,6 +152,7 @@ TEST_CASE( "Run_SMC_trace: Func_Sim")
auto kernel = Kernel::create_mars_kernel();
kernel->set_simulator( sim);
kernel->connect_memory( mem);
kernel->connect_exception_handler();
kernel->load_file( TEST_PATH "/mips-tt-no-delayed-branches.bin");
sim->set_kernel( kernel);

Expand All @@ -165,6 +171,7 @@ TEST_CASE( "Torture_Test: MIPS32 calls without kernel")
auto kernel = Kernel::create_dummy_kernel();
kernel->set_simulator( sim);
kernel->connect_memory( mem);
kernel->connect_exception_handler();
kernel->load_file( TEST_PATH "/mips-tt-no-delayed-branches.bin");
sim->set_kernel( kernel);

Expand All @@ -188,8 +195,9 @@ static auto get_simulator_with_test( const std::string& isa, const std::string&
sim->enable_driver_hooks();

auto kernel = Kernel::create_mars_kernel();
kernel->connect_memory( mem);
kernel->set_simulator( sim);
kernel->connect_memory( mem);
kernel->connect_exception_handler();
sim->set_kernel( kernel);
kernel->load_file( test);

Expand Down
6 changes: 6 additions & 0 deletions simulator/infra/macro.h
Original file line number Diff line number Diff line change
Expand Up @@ -358,4 +358,10 @@ static inline T gen_or_combine( T value, size_t shamt)
return value;
}

template<typename T>
static inline T trap_vector_address( T value, T aligning)
{
return value >> 2U & ~(bitmask<T>( aligning));
pavelkryukov marked this conversation as resolved.
Show resolved Hide resolved
}

#endif
1 change: 1 addition & 0 deletions simulator/kernel/base_kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class BaseKernel : public Kernel
public:
void set_simulator( const std::shared_ptr<CPUModel>& s) override { sim = std::make_unique<CPUReplicant>( s); }
void connect_memory( std::shared_ptr<FuncMemory> m) override { mem = std::make_unique<FuncMemoryReplicant>( m); }
void connect_exception_handler() override { }
void add_replica_simulator( const std::shared_ptr<CPUModel>& s) override { sim->add_replica( s); }
void add_replica_memory( const std::shared_ptr<FuncMemory>& s) override { mem->add_replica( s); }
void load_file( const std::string& name) override;
Expand Down
1 change: 1 addition & 0 deletions simulator/kernel/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class Kernel {

virtual void set_simulator( const std::shared_ptr<CPUModel>& s) = 0;
virtual void connect_memory( std::shared_ptr<FuncMemory> m) = 0;
virtual void connect_exception_handler() = 0;
virtual void add_replica_simulator( const std::shared_ptr<CPUModel>& s) = 0;
virtual void add_replica_memory( const std::shared_ptr<FuncMemory>& s) = 0;
virtual void load_file( const std::string& name) = 0;
Expand Down
27 changes: 24 additions & 3 deletions simulator/kernel/mars/mars_kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <kernel/base_kernel.h>
#include <memory/elf/elf_loader.h>
#include <infra/macro.h>
pavelkryukov marked this conversation as resolved.
Show resolved Hide resolved

#include <fstream>
#include <string>
Expand Down Expand Up @@ -39,9 +40,12 @@ class MARSKernel : public BaseKernel {
static const constexpr uint64 first_user_descriptor = 3;
uint64 next_descriptor = first_user_descriptor;

void connect_riscv_handler();
void connect_mars_handler();

public:
Trap execute() final;
void connect_memory( std::shared_ptr<FuncMemory> m) final;
void connect_exception_handler() final;

MARSKernel( std::istream& instream, std::ostream& outstream, std::ostream& errstream)
: instream( instream), outstream( outstream), errstream( errstream) {}
Expand Down Expand Up @@ -228,9 +232,26 @@ void MARSKernel::read_from_file() {
mem->memcpy_host_to_guest( buffer_ptr, byte_cast( buffer.data()), chars_to_read);
}

void MARSKernel::connect_memory( std::shared_ptr<FuncMemory> m)
void MARSKernel::connect_riscv_handler()
{
constexpr Addr TRAP_VECTOR = 0x8'000'0000;
sim->write_csr_register( "stvec", TRAP_VECTOR);
auto pc = trap_vector_address<Addr>(TRAP_VECTOR, 3);
ElfLoader elf_loader( KERNEL_IMAGES "riscv32.bin");
elf_loader.load_to( mem.get(), pc - elf_loader.get_text_section_addr());
}

void MARSKernel::connect_mars_handler()
{
BaseKernel::connect_memory( m);
ElfLoader elf_loader( KERNEL_IMAGES "mars32_le.bin");
elf_loader.load_to( mem.get(), 0x8'0000'0180 - elf_loader.get_text_section_addr());
}

void MARSKernel::connect_exception_handler()
pavelkryukov marked this conversation as resolved.
Show resolved Hide resolved
{
auto isa = sim->get_isa();
if ( isa == "riscv32")
connect_riscv_handler();
if ( isa == "mars" || isa == "mips32le" || isa == "mips32")
pavelkryukov marked this conversation as resolved.
Show resolved Hide resolved
connect_mars_handler();
pavelkryukov marked this conversation as resolved.
Show resolved Hide resolved
}
1 change: 1 addition & 0 deletions simulator/kernel/mars/t/unit_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ struct System
mars_kernel->set_simulator( sim);
sim->set_memory( mem);
mars_kernel->connect_memory( mem);
mars_kernel->connect_exception_handler();
}
};

Expand Down
1 change: 1 addition & 0 deletions simulator/kernel/replicant.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class CPUReplicant : public CPUModel
}

Addr get_pc() const final { return primary.lock()->get_pc(); }
std::string_view get_isa() const final { return primary.lock()->get_isa(); }
size_t sizeof_register() const final { return primary.lock()->sizeof_register(); }
uint64 read_cpu_register( size_t regno) const final { return primary.lock()->read_cpu_register( regno); }
uint64 read_gdb_register( size_t regno) const final { return primary.lock()->read_gdb_register( regno); }
Expand Down
3 changes: 2 additions & 1 deletion simulator/modules/core/perf_sim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ namespace config {
} // namespace config

template <typename ISA>
PerfSim<ISA>::PerfSim( Endian endian)
PerfSim<ISA>::PerfSim( Endian endian, std::string_view isa)
: endian( endian)
, fetch( this), decode( this), execute( this), mem( this), branch( this), writeback( this, endian)
{
set_isa( isa);
rp_halt = make_read_port<Trap>("WRITEBACK_2_CORE_HALT", PORT_LATENCY);

decode.set_RF( &rf);
Expand Down
2 changes: 1 addition & 1 deletion simulator/modules/core/perf_sim.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class PerfSim : public CycleAccurateSimulator
using Register = typename ISA::Register;
using RegisterUInt = typename ISA::RegisterUInt;

explicit PerfSim( Endian endian);
explicit PerfSim( Endian endian, std::string_view isa = "");
pavelkryukov marked this conversation as resolved.
Show resolved Hide resolved
Trap run( uint64 instrs_to_run) final;
void set_target( const Target& target) final;
void set_memory( std::shared_ptr<FuncMemory> memory) final;
Expand Down
Loading