From be0962c1bdca50ae55ee20ed445c9686956ef5df Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Fri, 26 May 2023 07:17:39 -0700 Subject: [PATCH] csim: Allow redirecting trace output to a file using command line flag This is useful when booting an operating system with tracing enabled as it allows showing the printed messages on the terminal and storing the trace log to a separate file. All categorized trace messages are now redirected to the --trace-output file when passed. If this option is not gived, the current behaviour of using stdout is retained. Example usage: `./c_emulator/riscv_sim_RV64 -b os-boot/rv64-64mb.dtb --trace-output /dev/stderr os-boot/linux-rv64-64mb.bbl --trace-output /tmp/linux.log` --- c_emulator/riscv_platform_impl.h | 2 + c_emulator/riscv_prelude.c | 9 ++-- c_emulator/riscv_sim.c | 70 ++++++++++++++++++++------------ 3 files changed, 52 insertions(+), 29 deletions(-) diff --git a/c_emulator/riscv_platform_impl.h b/c_emulator/riscv_platform_impl.h index d24ecc8fb..aa8d391de 100644 --- a/c_emulator/riscv_platform_impl.h +++ b/c_emulator/riscv_platform_impl.h @@ -2,6 +2,7 @@ #include #include +#include /* Settings of the platform implementation. */ @@ -32,5 +33,6 @@ extern uint64_t rv_clint_size; extern uint64_t rv_htif_tohost; extern uint64_t rv_insns_per_tick; +extern FILE *trace_log; extern int term_fd; void plat_term_write_impl(char c); diff --git a/c_emulator/riscv_prelude.c b/c_emulator/riscv_prelude.c index cd2ab70cd..143a1521b 100644 --- a/c_emulator/riscv_prelude.c +++ b/c_emulator/riscv_prelude.c @@ -1,5 +1,6 @@ #include "riscv_prelude.h" #include "riscv_config.h" +#include "riscv_platform_impl.h" unit print_string(sail_string prefix, sail_string msg) { @@ -10,28 +11,28 @@ unit print_string(sail_string prefix, sail_string msg) unit print_instr(sail_string s) { if (config_print_instr) - printf("%s\n", s); + fprintf(trace_log, "%s\n", s); return UNIT; } unit print_reg(sail_string s) { if (config_print_reg) - printf("%s\n", s); + fprintf(trace_log, "%s\n", s); return UNIT; } unit print_mem_access(sail_string s) { if (config_print_mem_access) - printf("%s\n", s); + fprintf(trace_log, "%s\n", s); return UNIT; } unit print_platform(sail_string s) { if (config_print_platform) - printf("%s\n", s); + fprintf(trace_log, "%s\n", s); return UNIT; } diff --git a/c_emulator/riscv_sim.c b/c_emulator/riscv_sim.c index fdb9ce01d..5a73896ba 100644 --- a/c_emulator/riscv_sim.c +++ b/c_emulator/riscv_sim.c @@ -48,10 +48,14 @@ const char *RV32ISA = "RV32IMAC"; #define CSR_MTVAL 0x343 #define CSR_MIP 0x344 +#define OPT_TRACE_OUTPUT 1000 + static bool do_dump_dts = false; static bool do_show_times = false; struct tv_spike_t *s = NULL; char *term_log = NULL; +static const char *trace_log_path = NULL; +FILE *trace_log = NULL; char *dtb_file = NULL; unsigned char *dtb = NULL; size_t dtb_len = 0; @@ -111,33 +115,34 @@ char *sailcov_file = NULL; #endif static struct option options[] = { - {"enable-dirty-update", no_argument, 0, 'd'}, - {"enable-misaligned", no_argument, 0, 'm'}, - {"enable-pmp", no_argument, 0, 'P'}, - {"enable-next", no_argument, 0, 'N'}, - {"ram-size", required_argument, 0, 'z'}, - {"disable-compressed", no_argument, 0, 'C'}, - {"disable-writable-misa", no_argument, 0, 'I'}, - {"disable-fdext", no_argument, 0, 'F'}, - {"mtval-has-illegal-inst-bits", no_argument, 0, 'i'}, - {"device-tree-blob", required_argument, 0, 'b'}, - {"terminal-log", required_argument, 0, 't'}, - {"show-times", required_argument, 0, 'p'}, - {"report-arch", no_argument, 0, 'a'}, - {"test-signature", required_argument, 0, 'T'}, - {"signature-granularity", required_argument, 0, 'g'}, + {"enable-dirty-update", no_argument, 0, 'd' }, + {"enable-misaligned", no_argument, 0, 'm' }, + {"enable-pmp", no_argument, 0, 'P' }, + {"enable-next", no_argument, 0, 'N' }, + {"ram-size", required_argument, 0, 'z' }, + {"disable-compressed", no_argument, 0, 'C' }, + {"disable-writable-misa", no_argument, 0, 'I' }, + {"disable-fdext", no_argument, 0, 'F' }, + {"mtval-has-illegal-inst-bits", no_argument, 0, 'i' }, + {"device-tree-blob", required_argument, 0, 'b' }, + {"terminal-log", required_argument, 0, 't' }, + {"show-times", required_argument, 0, 'p' }, + {"report-arch", no_argument, 0, 'a' }, + {"test-signature", required_argument, 0, 'T' }, + {"signature-granularity", required_argument, 0, 'g' }, #ifdef RVFI_DII - {"rvfi-dii", required_argument, 0, 'r'}, + {"rvfi-dii", required_argument, 0, 'r' }, #endif - {"help", no_argument, 0, 'h'}, - {"trace", optional_argument, 0, 'v'}, - {"no-trace", optional_argument, 0, 'V'}, - {"inst-limit", required_argument, 0, 'l'}, - {"enable-zfinx", no_argument, 0, 'x'}, + {"help", no_argument, 0, 'h' }, + {"trace", optional_argument, 0, 'v' }, + {"no-trace", optional_argument, 0, 'V' }, + {"trace-output", required_argument, 0, OPT_TRACE_OUTPUT}, + {"inst-limit", required_argument, 0, 'l' }, + {"enable-zfinx", no_argument, 0, 'x' }, #ifdef SAILCOV - {"sailcov-file", required_argument, 0, 'c'}, + {"sailcov-file", required_argument, 0, 'c' }, #endif - {0, 0, 0, 0 } + {0, 0, 0, 0 } }; static void print_usage(const char *argv0, int ec) @@ -352,6 +357,10 @@ char *process_args(int argc, char **argv) sailcov_file = strdup(optarg); break; #endif + case OPT_TRACE_OUTPUT: + trace_log_path = optarg; + fprintf(stderr, "using %s for trace output.\n", trace_log_path); + break; case '?': print_usage(argv[0], 1); break; @@ -626,6 +635,9 @@ void close_logs(void) exit(EXIT_FAILURE); } #endif + if (trace_log != stdout) { + fclose(trace_log); + } } void finish(int ec) @@ -726,8 +738,8 @@ void flush_logs(void) if (config_print_instr) { fprintf(stderr, "\n"); fflush(stderr); - fprintf(stdout, "\n"); - fflush(stdout); + fprintf(trace_log, "\n"); + fflush(trace_log); } } @@ -1010,6 +1022,14 @@ void init_logs() exit(1); } + if (trace_log_path == NULL) { + trace_log = stdout; + } else if ((trace_log = fopen(trace_log_path, "w+")) < 0) { + fprintf(stderr, "Cannot create trace log '%s': %s\n", trace_log, + strerror(errno)); + exit(1); + } + #ifdef SAILCOV if (sailcov_file != NULL) { sail_set_coverage_file(sailcov_file);