Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementing callbacks in sail-riscv for state-changing events #494

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ c_preserve_fns=-c_preserve _set_Misa_C

generated_definitions/c/riscv_model_$(ARCH).c: $(SAIL_SRCS) model/main.sail Makefile
mkdir -p generated_definitions/c
$(SAIL) $(SAIL_FLAGS) $(c_preserve_fns) -O -Oconstant_fold -memo_z3 -c -c_include riscv_prelude.h -c_include riscv_platform.h -c_no_main $(SAIL_SRCS) model/main.sail -o $(basename $@)
$(SAIL) $(SAIL_FLAGS) $(c_preserve_fns) -O -Oconstant_fold -memo_z3 -c -c_include riscv_prelude.h -c_include riscv_platform.h -c_no_main $(SAIL_SRCS) -c_include riscv_default_callbacks.c model/main.sail -o $(basename $@)

generated_definitions/c2/riscv_model_$(ARCH).c: $(SAIL_SRCS) model/main.sail Makefile
mkdir -p generated_definitions/c2
Expand Down Expand Up @@ -255,13 +255,17 @@ rvfi_preserve_fns=-c_preserve rvfi_set_instr_packet \
-c_preserve rvfi_get_int_data \
-c_preserve rvfi_zero_exec_packet \
-c_preserve rvfi_halt_exec_packet \
-c_preserve rvfi_write \
-c_preserve rvfi_read \
-c_preserve rvfi_mem_exception \
-c_preserve rvfi_wX \
-c_preserve print_instr_packet \
-c_preserve print_rvfi_exec

# sed -i isn't posix compliant, unfortunately
generated_definitions/c/riscv_rvfi_model_$(ARCH).c: $(SAIL_RVFI_SRCS) model/main.sail Makefile
mkdir -p generated_definitions/c
$(SAIL) $(c_preserve_fns) $(rvfi_preserve_fns) $(SAIL_FLAGS) -O -Oconstant_fold -memo_z3 -c -c_include riscv_prelude.h -c_include riscv_platform.h -c_no_main $(SAIL_RVFI_SRCS) model/main.sail -o $(basename $@)
$(SAIL) $(c_preserve_fns) $(rvfi_preserve_fns) $(SAIL_FLAGS) -O -Oconstant_fold -memo_z3 -c -c_include riscv_prelude.h -c_include riscv_platform.h -c_no_main $(SAIL_RVFI_SRCS) -c_include riscv_rvfi_callbacks.c model/main.sail -o $(basename $@)
sed -e '/^[[:space:]]*$$/d' $@ > [email protected]
mv [email protected] $@

Expand Down
1 change: 1 addition & 0 deletions c_emulator/riscv_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ extern bool config_print_step;
extern bool config_print_reg;
extern bool config_print_mem_access;
extern bool config_print_platform;
extern bool rv_enable_callbacks;
91 changes: 91 additions & 0 deletions c_emulator/riscv_default_callbacks.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#include "riscv_config.h"
#include <stdlib.h>

void zcsr_name_map_forwards(sail_string *rop, uint64_t);

static uint8_t *get_lbits_data(lbits val)
{
uint8_t *data = (uint8_t *)calloc(val.len, sizeof(uint8_t));
mpz_export(data, NULL, -1, 1, 0, 0, val.bits);
return data;
}

/* Implementations of default callbacks for trace printing.
*
* The model assumes that these functions do not change the state of the model.
*/
int mem_write_callback(uint64_t addr, uint64_t width, lbits value)
{
if (config_print_mem_access) {
char *lbits_data = get_lbits_data(value);
printf("mem[0x%.16lX] <- 0x", addr);
for (int i = width - 1; i >= 0; --i)
printf("%02hhX", lbits_data[i]);
printf("\n");
free(lbits_data);
}
}

int mem_read_callback(const char *type, uint64_t addr, uint64_t width,
lbits value)
{
if (config_print_mem_access) {
char *lbits_data = get_lbits_data(value);
printf("mem[%s,0x%.16lX] -> 0x", type, addr);
for (int i = width - 1; i >= 0; --i)
printf("%02hhX", lbits_data[i]);
printf("\n");
free(lbits_data);
}
}

int mem_exception_callback(uint64_t addr, uint64_t num_of_exception) { }

int xreg_write_callback(unsigned reg, uint64_t value)
{
if (config_print_reg)
printf("x%d <- 0x%.16lX\n", reg, value);
}

int freg_write_callback(unsigned reg, uint64_t value)
{
/* TODO: will only print bits; should we print in floating point format? */
if (config_print_reg)
printf("f%d <- 0x%.16lX\n", reg, value);
}

int csr_write_callback(unsigned reg, uint64_t value)
{
if (config_print_reg) {
sail_string csr_name;
CREATE(sail_string)(&csr_name);
zcsr_name_map_forwards(&csr_name, reg);
printf("CSR %s <- 0x%.16lX (input: 0x%.16lX)\n", csr_name, value, value);
KILL(sail_string)(&csr_name);
}
}

int csr_read_callback(unsigned reg, uint64_t value)
{
if (config_print_reg) {
sail_string csr_name;
CREATE(sail_string)(&csr_name);
zcsr_name_map_forwards(&csr_name, reg);
printf("CSR %s -> 0x%.16lX\n", csr_name, value);
KILL(sail_string)(&csr_name);
}
}

int vreg_write_callback(unsigned reg, lbits value)
{
if (config_print_reg) {
char *lbits_data = get_lbits_data(value);
printf("v%d <- ", reg);
for (int i = value.len - 1; i >= 0; --i)
printf("%02hhX", lbits_data[i]);
printf("\n");
free(lbits_data);
}
}

int pc_write_callback(uint64_t value) { }
2 changes: 0 additions & 2 deletions c_emulator/riscv_prelude.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,4 @@ unit print_mem_access(sail_string s);
unit print_platform(sail_string s);

bool get_config_print_instr(unit u);
bool get_config_print_reg(unit u);
bool get_config_print_mem(unit u);
bool get_config_print_platform(unit u);
38 changes: 38 additions & 0 deletions c_emulator/riscv_rvfi_callbacks.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include "riscv_config.h"

int zrvfi_write(uint64_t addr, int64_t width, lbits value);
int zrvfi_read(uint64_t addr, sail_int width, lbits value);
int zrvfi_mem_exception(uint64_t addr);
int zrvfi_wX(int64_t reg, uint64_t value);

int mem_write_callback(uint64_t addr, uint64_t width, lbits value)
{
if (rv_enable_callbacks)
zrvfi_write(addr, width, value);
}
int mem_read_callback(const char *type, uint64_t addr, uint64_t width,
lbits value)
{
if (rv_enable_callbacks) {
sail_int len;
CREATE(sail_int)(&len);
CONVERT_OF(sail_int, mach_int)(&len, width);
zrvfi_read(addr, len, value);
KILL(sail_int)(&len);
}
}
int mem_exception_callback(uint64_t addr, uint64_t num_of_exception)
{
if (rv_enable_callbacks)
zrvfi_mem_exception(addr);
}
int xreg_write_callback(unsigned reg, uint64_t value)
{
if (rv_enable_callbacks)
zrvfi_wX(reg, value);
}
int freg_write_callback(unsigned reg, uint64_t value) { }
int csr_write_callback(unsigned reg, uint64_t value) { }
int csr_read_callback(unsigned reg, uint64_t value) { }
int vreg_write_callback(unsigned reg, lbits value) { }
int pc_write_callback(uint64_t value) { }
14 changes: 14 additions & 0 deletions c_emulator/riscv_sail.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,20 @@ extern bool zhtif_done;
extern mach_bits zhtif_exit_code;
extern bool have_exception;

/* Callbacks for state-changing events */

/* The model assumes that these functions do not change the state of the model.
*/
int mem_write_callback(uint64_t addr, uint64_t width, lbits value);
int mem_read_callback(uint64_t addr, uint64_t width, lbits value);
int mem_exception_callback(uint64_t addr, uint64_t num_of_exception);
int xreg_write_callback(unsigned reg, uint64_t value);
int freg_write_callback(unsigned reg, uint64_t value);
int csr_write_callback(unsigned reg, uint64_t value);
int csr_read_callback(unsigned reg, uint64_t value);
int vreg_write_callback(unsigned reg, lbits value);
int pc_write_callback(uint64_t value);

/* machine state */

extern uint32_t zcur_privilege;
Expand Down
2 changes: 2 additions & 0 deletions c_emulator/riscv_sim.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ bool config_print_mem_access = true;
bool config_print_platform = true;
bool config_print_rvfi = false;
bool config_print_step = false;
bool rv_enable_callbacks = true;

void set_config_print(char *var, bool val)
{
Expand All @@ -102,6 +103,7 @@ void set_config_print(char *var, bool val)
config_print_reg = val;
config_print_platform = val;
config_print_rvfi = val;
rv_enable_callbacks = val;
} else if (strcmp("instr", var) == 0) {
config_print_instr = val;
} else if (strcmp("reg", var) == 0) {
Expand Down
2 changes: 0 additions & 2 deletions model/prelude.sail
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,6 @@ val get_config_print_mem = pure {c:"get_config_print_mem"} : unit -> bool
val get_config_print_platform = pure {c:"get_config_print_platform"} : unit -> bool
// defaults for other backends
function get_config_print_instr () = false
function get_config_print_reg () = false
function get_config_print_mem () = false
function get_config_print_platform () = false

val sign_extend : forall 'n 'm, 'm >= 'n. (implicit('m), bits('n)) -> bits('m)
Expand Down
1 change: 1 addition & 0 deletions model/riscv_csr_begin.sail
Original file line number Diff line number Diff line change
Expand Up @@ -338,3 +338,4 @@ scattered function read_CSR
/* returns new value (after legalisation) if the CSR is defined */
val write_CSR : (csreg, xlenbits) -> xlenbits
scattered function write_CSR

7 changes: 2 additions & 5 deletions model/riscv_fdext_regs.sail
Original file line number Diff line number Diff line change
Expand Up @@ -193,11 +193,8 @@ function wF (r : regno, in_v : flenbits) -> unit = {
};

dirty_fd_context();

if get_config_print_reg()
then
/* TODO: will only print bits; should we print in floating point format? */
print_reg("f" ^ dec_str(r) ^ " <- " ^ FRegStr(v));

freg_write_callback(regno_to_regidx(r), in_v);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default callback needs to print the register otherwise this removes tracing capabilities from the model.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added an implementation of the callbacks for trace printing to the riscv_types.sail, riscv_csr_begin.sail, riscv_vreg_type.sail and call them from the default callbacks in the riscv_default_callbacks.c.

}

function rF_bits(i: regidx) -> flenbits = rF(unsigned(i))
Expand Down
8 changes: 4 additions & 4 deletions model/riscv_insts_vext_mem.sail
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ function process_vlsegff (nf, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)
if i == 0 then { ext_handle_data_check_error(e); return RETIRE_FAIL }
else {
vl = to_bits(xlen, i);
print_reg("CSR vl <- " ^ BitStr(vl));
csr_write_callback(csr_name_map("vl"), vl);
trimmed = true
}
},
Expand All @@ -163,15 +163,15 @@ function process_vlsegff (nf, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)
if i == 0 then { handle_mem_exception(vaddr, E_Load_Addr_Align()); return RETIRE_FAIL }
else {
vl = to_bits(xlen, i);
print_reg("CSR vl <- " ^ BitStr(vl));
csr_write_callback(csr_name_map("vl"), vl);
trimmed = true
}
} else match translateAddr(vaddr, Read(Data)) {
TR_Failure(e, _) => {
if i == 0 then { handle_mem_exception(vaddr, e); return RETIRE_FAIL }
else {
vl = to_bits(xlen, i);
print_reg("CSR vl <- " ^ BitStr(vl));
csr_write_callback(csr_name_map("vl"), vl);
trimmed = true
}
},
Expand All @@ -182,7 +182,7 @@ function process_vlsegff (nf, vm, vd, load_width_bytes, rs1, EMUL_pow, num_elem)
if i == 0 then { handle_mem_exception(vaddr, e); return RETIRE_FAIL }
else {
vl = to_bits(xlen, i);
print_reg("CSR vl <- " ^ BitStr(vl));
csr_write_callback(csr_name_map("vl"), vl);
trimmed = true
}
}
Expand Down
22 changes: 11 additions & 11 deletions model/riscv_insts_vext_vset.sail
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ function handle_illegal_vtype() = {
*/
vtype.bits = 0b1 @ zeros(xlen - 1); /* set vtype.vill */
vl = zeros();
print_reg("CSR vtype <- " ^ BitStr(vtype.bits));
print_reg("CSR vl <- " ^ BitStr(vl))
csr_write_callback(csr_name_map("vtype"), vtype.bits);
csr_write_callback(csr_name_map("vl"), vl);
}

val calculate_new_vl : (int, int) -> xlenbits
Expand Down Expand Up @@ -106,9 +106,9 @@ function clause execute VSETVLI(ma, ta, sew, lmul, rs1, rd) = {
/* reset vstart to 0 */
vstart = zeros();

print_reg("CSR vtype <- " ^ BitStr(vtype.bits));
print_reg("CSR vl <- " ^ BitStr(vl));
print_reg("CSR vstart <- " ^ BitStr(vstart));
csr_write_callback(csr_name_map("vtype"), vtype.bits);
csr_write_callback(csr_name_map("vl"), vl);
csr_write_callback(csr_name_map("vstart"), zero_extend(vstart));

RETIRE_SUCCESS
}
Expand Down Expand Up @@ -157,9 +157,9 @@ function clause execute VSETVL(rs2, rs1, rd) = {
/* reset vstart to 0 */
vstart = zeros();

print_reg("CSR vtype <- " ^ BitStr(vtype.bits));
print_reg("CSR vl <- " ^ BitStr(vl));
print_reg("CSR vstart <- " ^ BitStr(vstart));
csr_write_callback(csr_name_map("vtype"), vtype.bits);
csr_write_callback(csr_name_map("vl"), vl);
csr_write_callback(csr_name_map("vstart"), zero_extend(vstart));

RETIRE_SUCCESS
}
Expand Down Expand Up @@ -193,9 +193,9 @@ function clause execute VSETIVLI(ma, ta, sew, lmul, uimm, rd) = {
/* reset vstart to 0 */
vstart = zeros();

print_reg("CSR vtype <- " ^ BitStr(vtype.bits));
print_reg("CSR vl <- " ^ BitStr(vl));
print_reg("CSR vstart <- " ^ BitStr(vstart));
csr_write_callback(csr_name_map("vtype"), vtype.bits);
csr_write_callback(csr_name_map("vl"), vl);
csr_write_callback(csr_name_map("vstart"), zero_extend(vstart));

RETIRE_SUCCESS
}
Expand Down
6 changes: 2 additions & 4 deletions model/riscv_insts_zicsr.sail
Original file line number Diff line number Diff line change
Expand Up @@ -193,11 +193,9 @@ function clause execute CSR(csr, rs1, rd, is_imm, op) = {
CSRRC => csr_val & ~(rs1_val)
};
let final_val = write_CSR(csr, new_val);
if get_config_print_reg()
then print_reg("CSR " ^ to_str(csr) ^ " <- " ^ bits_str(final_val) ^ " (input: " ^ bits_str(new_val) ^ ")")
csr_write_callback(csr, final_val);
} else {
if get_config_print_reg()
then print_reg("CSR " ^ to_str(csr) ^ " -> " ^ bits_str(csr_val));
csr_read_callback(csr, csr_val);
};
X(rd) = csr_val;
RETIRE_SUCCESS
Expand Down
Loading