diff options
-rwxr-xr-x | build_simulators.sh | 8 | ||||
-rw-r--r-- | c_emulator/riscv_platform.c | 5 | ||||
-rw-r--r-- | c_emulator/riscv_platform.h | 3 | ||||
-rw-r--r-- | c_emulator/riscv_platform_impl.c | 2 | ||||
-rw-r--r-- | c_emulator/riscv_platform_impl.h | 2 | ||||
-rw-r--r-- | c_emulator/riscv_sim.c | 12 | ||||
-rw-r--r-- | handwritten_support/riscv_extras.lem | 11 | ||||
-rw-r--r-- | handwritten_support/riscv_extras.v | 50 | ||||
-rw-r--r-- | handwritten_support/riscv_extras_sequential.lem | 11 | ||||
-rw-r--r-- | model/prelude.sail | 14 | ||||
-rw-r--r-- | model/prelude_mem.sail | 24 | ||||
-rw-r--r-- | model/riscv_insts_cext.sail | 9 | ||||
-rw-r--r-- | model/riscv_sys_control.sail | 13 | ||||
-rw-r--r-- | model/riscv_sys_regs.sail | 31 | ||||
-rw-r--r-- | ocaml_emulator/platform.ml | 29 | ||||
-rw-r--r-- | ocaml_emulator/riscv_ocaml_sim.ml | 6 | ||||
-rw-r--r-- | os-boot/README.md | 3 |
17 files changed, 154 insertions, 79 deletions
diff --git a/build_simulators.sh b/build_simulators.sh new file mode 100755 index 0000000..bf32e15 --- /dev/null +++ b/build_simulators.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +make ARCH=RV32 ocaml_emulator/riscv_ocaml_sim_RV32 +make ARCH=RV64 ocaml_emulator/riscv_ocaml_sim_RV64 + +make ARCH=RV32 c_emulator/riscv_sim_RV32 +make ARCH=RV64 c_emulator/riscv_sim_RV64 + diff --git a/c_emulator/riscv_platform.c b/c_emulator/riscv_platform.c index d1b1f6e..dcc5766 100644 --- a/c_emulator/riscv_platform.c +++ b/c_emulator/riscv_platform.c @@ -9,6 +9,11 @@ static mach_bits reservation = 0; static bool reservation_valid = false; +bool sys_enable_rvc(unit u) +{ return rv_enable_rvc; } +bool sys_enable_writable_misa(unit u) +{ return rv_enable_writable_misa; } + bool plat_enable_dirty_update(unit u) { return rv_enable_dirty_update; } diff --git a/c_emulator/riscv_platform.h b/c_emulator/riscv_platform.h index 728555e..31f2807 100644 --- a/c_emulator/riscv_platform.h +++ b/c_emulator/riscv_platform.h @@ -1,6 +1,9 @@ #pragma once #include "sail.h" +bool sys_enable_rvc(unit); +bool sys_enable_writable_misa(unit); + bool plat_enable_dirty_update(unit); bool plat_enable_misaligned_access(unit); bool plat_mtval_has_illegal_inst_bits(unit); diff --git a/c_emulator/riscv_platform_impl.c b/c_emulator/riscv_platform_impl.c index ed32979..5894fc9 100644 --- a/c_emulator/riscv_platform_impl.c +++ b/c_emulator/riscv_platform_impl.c @@ -3,6 +3,8 @@ #include <stdio.h> /* Settings of the platform implementation, with common defaults. */ +bool rv_enable_rvc = true; +bool rv_enable_writable_misa = true; bool rv_enable_dirty_update = false; bool rv_enable_misaligned = false; diff --git a/c_emulator/riscv_platform_impl.h b/c_emulator/riscv_platform_impl.h index 2e59fd8..cf3bc30 100644 --- a/c_emulator/riscv_platform_impl.h +++ b/c_emulator/riscv_platform_impl.h @@ -7,6 +7,8 @@ #define DEFAULT_RSTVEC 0x00001000 +extern bool rv_enable_rvc; +extern bool rv_enable_writable_misa; extern bool rv_enable_dirty_update; extern bool rv_enable_misaligned; extern bool rv_mtval_has_illegal_inst_bits; diff --git a/c_emulator/riscv_sim.c b/c_emulator/riscv_sim.c index 7be7fce..1176400 100644 --- a/c_emulator/riscv_sim.c +++ b/c_emulator/riscv_sim.c @@ -45,7 +45,6 @@ const char *RV32ISA = "RV32IMAC"; #define CSR_MIP 0x344 static bool do_dump_dts = false; -static bool disable_compressed = false; static bool do_show_times = false; struct tv_spike_t *s = NULL; char *term_log = NULL; @@ -78,6 +77,7 @@ static struct option options[] = { {"enable-misaligned", no_argument, 0, 'm'}, {"ram-size", required_argument, 0, 'z'}, {"disable-compressed", no_argument, 0, 'C'}, + {"disable-writable-misa", no_argument, 0, 'I'}, {"mtval-has-illegal-inst-bits", no_argument, 0, 'i'}, {"dump-dts", no_argument, 0, 's'}, {"device-tree-blob", required_argument, 0, 'b'}, @@ -187,7 +187,10 @@ char *process_args(int argc, char **argv) rv_enable_misaligned = true; break; case 'C': - disable_compressed = true; + rv_enable_rvc = false; + break; + case 'I': + rv_enable_writable_misa = false; break; case 'i': rv_mtval_has_illegal_inst_bits = true; @@ -424,8 +427,9 @@ void init_sail(uint64_t elf_entry) } else #endif init_sail_reset_vector(elf_entry); - if (disable_compressed) - z_set_Misa_C(&zmisa, 0); + + // this is probably unnecessary now; remove + if (!rv_enable_rvc) z_set_Misa_C(&zmisa, 0); } int init_check(struct tv_spike_t *s) diff --git a/handwritten_support/riscv_extras.lem b/handwritten_support/riscv_extras.lem index ed572be..d2cd03b 100644 --- a/handwritten_support/riscv_extras.lem +++ b/handwritten_support/riscv_extras.lem @@ -71,6 +71,14 @@ let speculate_conditional_success () = excl_result () let match_reservation _ = true let cancel_reservation () = () +val sys_enable_writable_misa : unit -> bool +let sys_enable_writable_misa () = true +declare ocaml target_rep function sys_enable_writable_misa = `Platform.enable_writable_misa` + +val sys_enable_rvc : unit -> bool +let sys_enable_rvc () = true +declare ocaml target_rep function sys_enable_rvc = `Platform.enable_rvc` + val plat_ram_base : forall 'a. Size 'a => unit -> bitvector 'a let plat_ram_base () = wordFromInteger 0 declare ocaml target_rep function plat_ram_base = `Platform.dram_base` @@ -139,3 +147,6 @@ let prerr_bits msg bs = prerr_endline (msg ^ (show_bitlist (bits_of bs))) val print_bits : forall 'a. Size 'a => string -> bitvector 'a -> unit let print_bits msg bs = () (* print_endline (msg ^ (show_bitlist (bits_of bs))) *) + +val print_dbg : string -> unit +let print_dbg msg = () diff --git a/handwritten_support/riscv_extras.v b/handwritten_support/riscv_extras.v index ff235a9..33bc9ec 100644 --- a/handwritten_support/riscv_extras.v +++ b/handwritten_support/riscv_extras.v @@ -36,31 +36,38 @@ Definition MEMea_conditional_release {rv a e} (addr : mword a) size : monad rv u Definition MEMea_conditional_strong_release {rv a e} (addr : mword a) size : monad rv unit e := write_mem_ea Write_RISCV_conditional_strong_release addr size. - -(* Some wrappers copied from aarch64_extras *) -(* TODO: Harmonise into a common library *) (* -Definition get_slice_int_bl len n lo := - (* TODO: Is this the intended behaviour? *) - let hi := lo + len - 1 in - let bs := bools_of_int (hi + 1) n in - subrange_list false bs hi lo - -val get_slice_int : forall 'a. Bitvector 'a => integer -> integer -> integer -> 'a -Definition get_slice_int len n lo := of_bools (get_slice_int_bl len n lo) +val MEMr : forall 'rv 'a 'b 'e. Size 'a, Size 'b => integer -> integer -> bitvector 'a -> bitvector 'a -> monad 'rv (bitvector 'b) 'e +val MEMr_acquire : forall 'rv 'a 'b 'e. Size 'a, Size 'b => integer -> integer -> bitvector 'a -> bitvector 'a -> monad 'rv (bitvector 'b) 'e +val MEMr_strong_acquire : forall 'rv 'a 'b 'e. Size 'a, Size 'b => integer -> integer -> bitvector 'a -> bitvector 'a -> monad 'rv (bitvector 'b) 'e +val MEMr_reserved : forall 'rv 'a 'b 'e. Size 'a, Size 'b => integer -> integer -> bitvector 'a -> bitvector 'a -> monad 'rv (bitvector 'b) 'e +val MEMr_reserved_acquire : forall 'rv 'a 'b 'e. Size 'a, Size 'b => integer -> integer -> bitvector 'a -> bitvector 'a -> monad 'rv (bitvector 'b) 'e +val MEMr_reserved_strong_acquire : forall 'rv 'a 'b 'e. Size 'a, Size 'b => integer -> integer -> bitvector 'a -> bitvector 'a -> monad 'rv (bitvector 'b) 'e *) -Definition write_ram {rv e} m size (hexRAM : mword m) (addr : mword m) (data : mword (8 * size)) : monad rv bool e := - write_mem_val data. -Definition read_ram {rv e} m size `{ArithFact (size >= 0)} (_ : mword m) (addr : mword m) : monad rv (mword (8 * size)) e := - read_mem Read_plain addr size. -(* -Definition string_of_bits bs := string_of_bv (bits_of bs). -Definition string_of_int := show +Definition MEMr {rv e} addrsize size (hexRAM addr : mword addrsize) `{ArithFact (size >= 0)} : monad rv (mword (8 * size)) e := read_mem Read_plain addr size. +Definition MEMr_acquire {rv e} addrsize size (hexRAM addr : mword addrsize) `{ArithFact (size >= 0)} : monad rv (mword (8 * size)) e := read_mem Read_RISCV_acquire addr size. +Definition MEMr_strong_acquire {rv e} addrsize size (hexRAM addr : mword addrsize) `{ArithFact (size >= 0)} : monad rv (mword (8 * size)) e := read_mem Read_RISCV_strong_acquire addr size. +Definition MEMr_reserved {rv e} addrsize size (hexRAM addr : mword addrsize) `{ArithFact (size >= 0)} : monad rv (mword (8 * size)) e := read_mem Read_RISCV_reserved addr size. +Definition MEMr_reserved_acquire {rv e} addrsize size (hexRAM addr : mword addrsize) `{ArithFact (size >= 0)} : monad rv (mword (8 * size)) e := read_mem Read_RISCV_reserved_acquire addr size. +Definition MEMr_reserved_strong_acquire {rv e} addrsize size (hexRAM addr : mword addrsize) `{ArithFact (size >= 0)} : monad rv (mword (8 * size)) e := read_mem Read_RISCV_reserved_strong_acquire addr size. -Definition _sign_extend bits len := maybe_failwith (of_bits (exts_bv len bits)) -Definition _zero_extend bits len := maybe_failwith (of_bits (extz_bv len bits)) +(* +val MEMw : forall 'rv 'a 'b 'e. Size 'a, Size 'b => integer -> integer -> bitvector 'a -> bitvector 'a -> bitvector 'b -> monad 'rv bool 'e +val MEMw_release : forall 'rv 'a 'b 'e. Size 'a, Size 'b => integer -> integer -> bitvector 'a -> bitvector 'a -> bitvector 'b -> monad 'rv bool 'e +val MEMw_strong_release : forall 'rv 'a 'b 'e. Size 'a, Size 'b => integer -> integer -> bitvector 'a -> bitvector 'a -> bitvector 'b -> monad 'rv bool 'e +val MEMw_conditional : forall 'rv 'a 'b 'e. Size 'a, Size 'b => integer -> integer -> bitvector 'a -> bitvector 'a -> bitvector 'b -> monad 'rv bool 'e +val MEMw_conditional_release : forall 'rv 'a 'b 'e. Size 'a, Size 'b => integer -> integer -> bitvector 'a -> bitvector 'a -> bitvector 'b -> monad 'rv bool 'e +val MEMw_conditional_strong_release : forall 'rv 'a 'b 'e. Size 'a, Size 'b => integer -> integer -> bitvector 'a -> bitvector 'a -> bitvector 'b -> monad 'rv bool 'e *) + +Definition MEMw {rv e} addrsize size (hexRAM addr : mword addrsize) (v : mword (8 * size)) : monad rv bool e := write_mem Write_plain addr size v. +Definition MEMw_release {rv e} addrsize size (hexRAM addr : mword addrsize) (v : mword (8 * size)) : monad rv bool e := write_mem Write_RISCV_release addr size v. +Definition MEMw_strong_release {rv e} addrsize size (hexRAM addr : mword addrsize) (v : mword (8 * size)) : monad rv bool e := write_mem Write_RISCV_strong_release addr size v. +Definition MEMw_conditional {rv e} addrsize size (hexRAM addr : mword addrsize) (v : mword (8 * size)) : monad rv bool e := write_mem Write_RISCV_conditional addr size v. +Definition MEMw_conditional_release {rv e} addrsize size (hexRAM addr : mword addrsize) (v : mword (8 * size)) : monad rv bool e := write_mem Write_RISCV_conditional_release addr size v. +Definition MEMw_conditional_strong_release {rv e} addrsize size (hexRAM addr : mword addrsize) (v : mword (8 * size)) : monad rv bool e := write_mem Write_RISCV_conditional_strong_release addr size v. + Definition shift_bits_left {a b} (v : mword a) (n : mword b) : mword a := shiftl v (int_of_mword false n). @@ -134,6 +141,9 @@ Definition putchar {T} (_:T) : unit := tt. Require DecimalString. Definition string_of_int z := DecimalString.NilZero.string_of_int (Z.to_int z). +Axiom sys_enable_writable_misa : unit -> bool. +Axiom sys_enable_rvc : unit -> bool. + (* The constraint solver can do this itself, but a Coq bug puts anonymous_subproof into the term instead of an actual subproof. *) Lemma n_leading_spaces_fact {w__0} : diff --git a/handwritten_support/riscv_extras_sequential.lem b/handwritten_support/riscv_extras_sequential.lem index 2919d77..604911a 100644 --- a/handwritten_support/riscv_extras_sequential.lem +++ b/handwritten_support/riscv_extras_sequential.lem @@ -67,6 +67,14 @@ let speculate_conditional_success () = excl_result () let match_reservation _ = true let cancel_reservation () = () +val sys_enable_writable_misa : unit -> bool +let sys_enable_writable_misa () = true +declare ocaml target_rep function sys_enable_writable_misa = `Platform.enable_writable_misa` + +val sys_enable_rvc : unit -> bool +let sys_enable_rvc () = true +declare ocaml target_rep function sys_enable_rvc = `Platform.enable_rvc` + val plat_ram_base : forall 'a. Size 'a => unit -> bitvector 'a let plat_ram_base () = wordFromInteger 0 declare ocaml target_rep function plat_ram_base = `Platform.dram_base` @@ -135,3 +143,6 @@ let prerr_bits msg bs = prerr_endline (msg ^ (show_bitlist (bits_of bs))) val print_bits : forall 'a. Size 'a => string -> bitvector 'a -> unit let print_bits msg bs = () (* print_endline (msg ^ (show_bitlist (bits_of bs))) *) + +val print_dbg : string -> unit +let print_dbg msg = () diff --git a/model/prelude.sail b/model/prelude.sail index 73f96b0..457c4d4 100644 --- a/model/prelude.sail +++ b/model/prelude.sail @@ -1,5 +1,6 @@ default Order dec +$include <smt.sail> $include <option.sail> $include <arith.sail> $include <string.sail> @@ -84,9 +85,8 @@ overload operator - = {sub_vec, sub_vec_int} val quot_round_zero = {ocaml: "quot_round_zero", interpreter: "quot_round_zero", lem: "hardware_quot", c: "tdiv_int"} : (int, int) -> int val rem_round_zero = {ocaml: "rem_round_zero", interpreter: "rem_round_zero", lem: "hardware_mod", c: "tmod_int"} : (int, int) -> int -val modulus = {lem: "hardware_mod"} : (int, int) -> int - -overload operator % = {modulus} +/* The following should get us euclidean modulus, and is compatible with pre and post 0.9 versions of sail */ +overload operator % = {emod_int, mod} val min_nat = {ocaml: "min_int", lem: "min", coq: "min_nat", c: "min_int"} : (nat, nat) -> nat @@ -105,10 +105,10 @@ val pow2 = "pow2" : forall 'n. atom('n) -> atom(2 ^ 'n) val print = "print_endline" : string -> unit val print_string = "print_string" : (string, string) -> unit -val print_instr = {ocaml: "Platform.print_instr", interpreter: "print_endline", c: "print_instr", _: "print_endline"} : string -> unit -val print_reg = {ocaml: "Platform.print_reg", interpreter: "print_endline", c: "print_reg", _: "print_endline"} : string -> unit -val print_mem = {ocaml: "Platform.print_mem_access", interpreter: "print_endline", c: "print_mem_access", _: "print_endline"} : string -> unit -val print_platform = {ocaml: "Platform.print_platform", interpreter: "print_endline", c: "print_platform", _: "print_endline"} : string -> unit +val print_instr = {ocaml: "Platform.print_instr", interpreter: "print_endline", c: "print_instr", lem: "print_dbg", _: "print_endline"} : string -> unit +val print_reg = {ocaml: "Platform.print_reg", interpreter: "print_endline", c: "print_reg", lem: "print_dbg", _: "print_endline"} : string -> unit +val print_mem = {ocaml: "Platform.print_mem_access", interpreter: "print_endline", c: "print_mem_access", lem: "print_dbg", _: "print_endline"} : string -> unit +val print_platform = {ocaml: "Platform.print_platform", interpreter: "print_endline", c: "print_platform", lem: "print_dbg", _: "print_endline"} : string -> unit $ifndef FEATURE_IMPLICITS val EXTS : forall 'n 'm , 'm >= 'n . bits('n) -> bits('m) diff --git a/model/prelude_mem.sail b/model/prelude_mem.sail index 8e483f8..b6fa0bc 100644 --- a/model/prelude_mem.sail +++ b/model/prelude_mem.sail @@ -2,22 +2,22 @@ * They depend on the XLEN of the architecture. */ -val __WriteRAM = {lem: "MEMw", _: "write_ram"} : forall 'n 'm. +val __WriteRAM = {lem: "MEMw", coq: "MEMw", _: "write_ram"} : forall 'n 'm. (atom('m), atom('n), bits('m), bits('m), bits(8 * 'n)) -> bool effect {wmv} -val __WriteRAM_release = {lem: "MEMw_release", _: "write_ram"} : forall 'n 'm. +val __WriteRAM_release = {lem: "MEMw_release", coq: "MEMw_release", _: "write_ram"} : forall 'n 'm. (atom('m), atom('n), bits('m), bits('m), bits(8 * 'n)) -> bool effect {wmv} -val __WriteRAM_strong_release = {lem: "MEMw_strong_release", _: "write_ram"} : forall 'n 'm. +val __WriteRAM_strong_release = {lem: "MEMw_strong_release", coq: "MEMw_strong_release", _: "write_ram"} : forall 'n 'm. (atom('m), atom('n), bits('m), bits('m), bits(8 * 'n)) -> bool effect {wmv} -val __WriteRAM_conditional = {lem: "MEMw_conditional", _: "write_ram"} : forall 'n 'm. +val __WriteRAM_conditional = {lem: "MEMw_conditional", coq: "MEMw_conditional", _: "write_ram"} : forall 'n 'm. (atom('m), atom('n), bits('m), bits('m), bits(8 * 'n)) -> bool effect {wmv} -val __WriteRAM_conditional_release = {lem: "MEMw_conditional_release", _: "write_ram"} : forall 'n 'm. +val __WriteRAM_conditional_release = {lem: "MEMw_conditional_release", coq: "MEMw_conditional_release", _: "write_ram"} : forall 'n 'm. (atom('m), atom('n), bits('m), bits('m), bits(8 * 'n)) -> bool effect {wmv} -val __WriteRAM_conditional_strong_release = {lem: "MEMw_conditional_strong_release", _: "write_ram"} : forall 'n 'm. +val __WriteRAM_conditional_strong_release = {lem: "MEMw_conditional_strong_release", coq: "MEMw_conditional_strong_release", _: "write_ram"} : forall 'n 'm. (atom('m), atom('n), bits('m), bits('m), bits(8 * 'n)) -> bool effect {wmv} val __RISCV_write : forall 'n. (xlenbits, atom('n), bits(8 * 'n), bool, bool, bool) -> bool effect {wmv} @@ -36,22 +36,22 @@ function __RISCV_write (addr, width, data, aq, rl, con) = val __TraceMemoryWrite : forall 'n 'm. (atom('n), bits('m), bits(8 * 'n)) -> unit -val __ReadRAM = { lem: "MEMr", _ : "read_ram" } : forall 'n 'm, 'n >= 0. +val __ReadRAM = { lem: "MEMr", coq: "MEMr", _ : "read_ram" } : forall 'n 'm, 'n >= 0. (atom('m), atom('n), bits('m), bits('m)) -> bits(8 * 'n) effect {rmem} -val __ReadRAM_acquire = { lem: "MEMr_acquire", _ : "read_ram" } : forall 'n 'm, 'n >= 0. +val __ReadRAM_acquire = { lem: "MEMr_acquire", coq: "MEMr_acquire", _ : "read_ram" } : forall 'n 'm, 'n >= 0. (atom('m), atom('n), bits('m), bits('m)) -> bits(8 * 'n) effect {rmem} -val __ReadRAM_strong_acquire = { lem: "MEMr_strong_acquire", _ : "read_ram" } : forall 'n 'm, 'n >= 0. +val __ReadRAM_strong_acquire = { lem: "MEMr_strong_acquire", coq: "MEMr_strong_acquire", _ : "read_ram" } : forall 'n 'm, 'n >= 0. (atom('m), atom('n), bits('m), bits('m)) -> bits(8 * 'n) effect {rmem} -val __ReadRAM_reserved = { lem: "MEMr_reserved", _ : "read_ram" } : forall 'n 'm, 'n >= 0. +val __ReadRAM_reserved = { lem: "MEMr_reserved", coq: "MEMr_reserved", _ : "read_ram" } : forall 'n 'm, 'n >= 0. (atom('m), atom('n), bits('m), bits('m)) -> bits(8 * 'n) effect {rmem} -val __ReadRAM_reserved_acquire = { lem: "MEMr_reserved_acquire", _ : "read_ram" } : forall 'n 'm, 'n >= 0. +val __ReadRAM_reserved_acquire = { lem: "MEMr_reserved_acquire", coq: "MEMr_reserved_acquire", _ : "read_ram" } : forall 'n 'm, 'n >= 0. (atom('m), atom('n), bits('m), bits('m)) -> bits(8 * 'n) effect {rmem} -val __ReadRAM_reserved_strong_acquire = { lem: "MEMr_reserved_strong_acquire", _ : "read_ram" } : forall 'n 'm, 'n >= 0. +val __ReadRAM_reserved_strong_acquire = { lem: "MEMr_reserved_strong_acquire", coq: "MEMr_reserved_strong_acquire", _ : "read_ram" } : forall 'n 'm, 'n >= 0. (atom('m), atom('n), bits('m), bits('m)) -> bits(8 * 'n) effect {rmem} val __RISCV_read : forall 'n, 'n >= 0. (xlenbits, atom('n), bool, bool, bool) -> option(bits(8 * 'n)) effect {rmem} diff --git a/model/riscv_insts_cext.sail b/model/riscv_insts_cext.sail index 70d4978..4986278 100644 --- a/model/riscv_insts_cext.sail +++ b/model/riscv_insts_cext.sail @@ -150,13 +150,8 @@ mapping clause encdec_compressed = C_ADDIW(imm5 @ imm40, rsd) <-> 0b001 @ imm5 : bits(1) @ rsd : regbits @ imm40 : bits(5) @ 0b01 if rsd != zreg & sizeof(xlen) == 64 -function clause execute (C_ADDIW(imm, rsd)) = { - let imm : bits(32) = EXTS(imm); - let rs_val = X(rsd); - let res : bits(32) = rs_val[31..0] + imm; - X(rsd) = EXTS(res); - true -} +function clause execute (C_ADDIW(imm, rsd)) = + execute(ADDIW(EXTS(imm), rsd, rsd)) mapping clause assembly = C_ADDIW(imm, rsd) if sizeof(xlen) == 64 diff --git a/model/riscv_sys_control.sail b/model/riscv_sys_control.sail index 2f02839..4155d66 100644 --- a/model/riscv_sys_control.sail +++ b/model/riscv_sys_control.sail @@ -415,18 +415,19 @@ function handle_interrupt(i : InterruptType, del_priv : Privilege) -> unit = /* state state initialization */ +val sys_enable_rvc = {c: "sys_enable_rvc", ocaml: "Platform.enable_rvc", _: "sys_enable_rvc"} : unit -> bool function init_sys() -> unit = { cur_privilege = Machine; mhartid = EXTZ(0b0); misa->MXL() = arch_to_bits(if sizeof(xlen) == 32 then RV32 else RV64); - misa->A() = true; /* atomics */ - misa->C() = true; /* RVC */ - misa->I() = true; /* base integer ISA */ - misa->M() = true; /* integer multiply/divide */ - misa->U() = true; /* user-mode */ - misa->S() = true; /* supervisor-mode */ + misa->A() = true; /* atomics */ + misa->C() = sys_enable_rvc (); /* RVC */ + misa->I() = true; /* base integer ISA */ + misa->M() = true; /* integer multiply/divide */ + misa->U() = true; /* user-mode */ + misa->S() = true; /* supervisor-mode */ mstatus = set_mstatus_SXL(mstatus, misa.MXL()); mstatus = set_mstatus_UXL(mstatus, misa.MXL()); diff --git a/model/riscv_sys_regs.sail b/model/riscv_sys_regs.sail index 439d12d..fb8a994 100644 --- a/model/riscv_sys_regs.sail +++ b/model/riscv_sys_regs.sail @@ -70,13 +70,19 @@ bitfield Misa : xlenbits = { } register misa : Misa +val sys_enable_writable_misa = {c: "sys_enable_writable_misa", ocaml: "Platform.enable_writable_misa", _: "sys_enable_writable_misa"} : unit -> bool + +/* We currently only support dynamic changes for the C extension. */ function legalize_misa(m : Misa, v : xlenbits) -> Misa = { - /* Allow modifications to C. */ - let v = Mk_Misa(v); - // Suppress changing C if nextPC would become misaligned. - if v.C() == false & nextPC[1] == true - then m - else update_C(m, v.C()) + if sys_enable_writable_misa () + then { /* Allow modifications to C only for now. */ + let v = Mk_Misa(v); + /* Suppress changing C if nextPC would become misaligned. */ + if v.C() == false & nextPC[1] == true + then m + else update_C(m, v.C()) + } + else m } /* helpers to check support for various extensions. */ @@ -319,12 +325,15 @@ function tvec_addr(m : Mtvec, c : Mcause) -> option(xlenbits) = { register mepc : xlenbits -// legalizing writes to xepc -function legalize_xepc(v : xlenbits) -> xlenbits = { - v & EXTS(if haveRVC() then 0b110 else 0b100) -} +/* The xepc legalization zeroes xepc[1:0] when misa.C is hardwired to 0. + * When misa.C is writable, it zeroes only xepc[0]. + */ +function legalize_xepc(v : xlenbits) -> xlenbits = + if sys_enable_writable_misa () | misa.C() == true + then [v with 0 = bitzero] + else v & EXTS(0b100) -// masking for reads to xepc +/* masking for reads to xepc */ function pc_alignment_mask() -> xlenbits = ~(EXTZ(if misa.C() == true then 0b00 else 0b10)) diff --git a/ocaml_emulator/platform.ml b/ocaml_emulator/platform.ml index 45e3d43..95e7c57 100644 --- a/ocaml_emulator/platform.ml +++ b/ocaml_emulator/platform.ml @@ -4,8 +4,10 @@ module Elf = Elf_loader;; (* Platform configuration *) -let config_enable_dirty_update = ref false -let config_enable_misaligned_access = ref false +let config_enable_rvc = ref true +let config_enable_writable_misa = ref true +let config_enable_dirty_update = ref false +let config_enable_misaligned_access = ref false let config_mtval_has_illegal_inst_bits = ref false let platform_arch = ref P.RV64 @@ -65,24 +67,27 @@ let make_rom arch start_pc = *) rom ) -let enable_dirty_update () = !config_enable_dirty_update -let enable_misaligned_access () = !config_enable_misaligned_access -let mtval_has_illegal_inst_bits () = !config_mtval_has_illegal_inst_bits +let enable_writable_misa () = !config_enable_writable_misa +let enable_rvc () = !config_enable_rvc +let enable_dirty_update () = !config_enable_dirty_update +let enable_misaligned_access () = !config_enable_misaligned_access +let mtval_has_illegal_inst_bits () = !config_mtval_has_illegal_inst_bits -let rom_base () = arch_bits_of_int64 P.rom_base -let rom_size () = arch_bits_of_int !rom_size_ref +let rom_base () = arch_bits_of_int64 P.rom_base +let rom_size () = arch_bits_of_int !rom_size_ref -let dram_base () = arch_bits_of_int64 P.dram_base -let dram_size () = arch_bits_of_int64 !P.dram_size_ref - -let htif_tohost () = - arch_bits_of_int64 (Big_int.to_int64 (Elf.elf_tohost ())) +let dram_base () = arch_bits_of_int64 P.dram_base +let dram_size () = arch_bits_of_int64 !P.dram_size_ref let clint_base () = arch_bits_of_int64 P.clint_base let clint_size () = arch_bits_of_int64 P.clint_size let insns_per_tick () = Big_int.of_int P.insns_per_tick +let htif_tohost () = + arch_bits_of_int64 (Big_int.to_int64 (Elf.elf_tohost ())) + + (* load reservation *) let speculate_conditional () = true diff --git a/ocaml_emulator/riscv_ocaml_sim.ml b/ocaml_emulator/riscv_ocaml_sim.ml index 9046a2f..5f5c716 100644 --- a/ocaml_emulator/riscv_ocaml_sim.ml +++ b/ocaml_emulator/riscv_ocaml_sim.ml @@ -40,6 +40,12 @@ let options = Arg.align ([("-dump-dts", ("-mtval-has-illegal-inst-bits", Arg.Set P.config_mtval_has_illegal_inst_bits, " mtval stores instruction bits on an illegal instruction exception"); + ("-disable-rvc", + Arg.Clear P.config_enable_rvc, + " disable the RVC extension on boot"); + ("-disable-writable-misa-c", + Arg.Clear P.config_enable_writable_misa, + " leave misa hardwired to its initial value"); ("-ram-size", Arg.Int PI.set_dram_size, " size of physical ram memory to use (in MB)"); diff --git a/os-boot/README.md b/os-boot/README.md index 7077b4a..4d80d39 100644 --- a/os-boot/README.md +++ b/os-boot/README.md @@ -7,6 +7,9 @@ output port similar to Spike's HTIF (host-target interface) mechanism, and an interrupt controller based on Spike's CLINT (core-local interrupt controller). Console input is not currently supported. +32-bit OS boots require a workaround for the 64-bit HTIF interface, +which is currently not supported. + Booting Linux with the C backend -------------------------------- |