From be0962c1bdca50ae55ee20ed445c9686956ef5df Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Fri, 26 May 2023 07:17:39 -0700 Subject: [PATCH 1/3] 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); From ffa591d5e09389b01c50dd98333fce6b994a11a9 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Fri, 28 Apr 2023 12:28:06 -0700 Subject: [PATCH 2/3] Fix --help output for options without a short flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously --help printed the following: ``` -V --no-trace -� --trace-output -l --inst-limit ``` With the new change it is: ``` -V --no-trace --trace-output -l --inst-limit ``` --- c_emulator/riscv_sim.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/c_emulator/riscv_sim.c b/c_emulator/riscv_sim.c index 5a73896ba..84ee04d3f 100644 --- a/c_emulator/riscv_sim.c +++ b/c_emulator/riscv_sim.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -156,7 +157,10 @@ static void print_usage(const char *argv0, int ec) #endif struct option *opt = options; while (opt->name) { - fprintf(stdout, "\t -%c\t --%s\n", (char)opt->val, opt->name); + if (isprint(opt->val)) + fprintf(stdout, "\t -%c\t --%s\n", (char)opt->val, opt->name); + else + fprintf(stdout, "\t \t --%s\n", opt->name); opt++; } exit(ec); From 4f3fd5121d5b1ecbc4e67e24a0d64549374876cf Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Thu, 3 Aug 2023 09:18:35 -0700 Subject: [PATCH 3/3] Avoid unnecessary empty lines when instruction tracing is on These empty lines don't add to the readability of the trace and in fact when trace redirection is enabled they result in lots of empty lines being printed to stderr which makes it impossible to read the OS boot messages. --- c_emulator/riscv_sim.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/c_emulator/riscv_sim.c b/c_emulator/riscv_sim.c index 84ee04d3f..93609b433 100644 --- a/c_emulator/riscv_sim.c +++ b/c_emulator/riscv_sim.c @@ -740,9 +740,7 @@ int compare_states(struct tv_spike_t *s) void flush_logs(void) { if (config_print_instr) { - fprintf(stderr, "\n"); fflush(stderr); - fprintf(trace_log, "\n"); fflush(trace_log); } }