From 1735e3e978c8982321715b9245211c8b06fad3d2 Mon Sep 17 00:00:00 2001 From: William McSpaddden Date: Sun, 20 Oct 2024 12:02:29 -0500 Subject: [PATCH] intemediate checkin. priv 1.13 features added. --- c_emulator/riscv_sim.c | 77 +++++++++++++++++++++++++++++++++++++++ model/riscv_platform.sail | 4 ++ model/riscv_types.sail | 43 ++++++++++++++++++++++ 3 files changed, 124 insertions(+) diff --git a/c_emulator/riscv_sim.c b/c_emulator/riscv_sim.c index b5b7b08d4..790b0bee3 100644 --- a/c_emulator/riscv_sim.c +++ b/c_emulator/riscv_sim.c @@ -59,8 +59,32 @@ enum { OPT_ENABLE_ZICBOM, OPT_ENABLE_ZICBOZ, OPT_CACHE_BLOCK_SIZE, + OPT_PRIV_SPEC, + OPT_UNPRIV_SPEC, }; +enum priv_spec_enum { + OPT_PRIV_SPEC_UNSPECIFIED, + OPT_PRIV_SPEC_1_11, + OPT_PRIV_SPEC_1_12, + OPT_PRIV_SPEC_1_13, +} ; + +struct priv_spec_enum_str { + const enum priv_spec_enum e; + const char * str; +}; + +static struct priv_spec_enum_str priv_spec_enum_str_lookup [] = { + { OPT_PRIV_SPEC_UNSPECIFIED, "unspecified"}, + { OPT_PRIV_SPEC_1_11, "1.11" }, + { OPT_PRIV_SPEC_1_12, "1.12" }, + { OPT_PRIV_SPEC_1_13, "1.13" }, +}; + +enum priv_spec_enum priv_spec = OPT_PRIV_SPEC_UNSPECIFIED; +char * _priv_spec_str = "unspecified"; + static bool do_dump_dts = false; static bool do_show_times = false; struct tv_spike_t *s = NULL; @@ -160,6 +184,8 @@ static struct option options[] = { {"enable-zicbom", no_argument, 0, OPT_ENABLE_ZICBOM }, {"enable-zicboz", no_argument, 0, OPT_ENABLE_ZICBOZ }, {"cache-block-size", required_argument, 0, OPT_CACHE_BLOCK_SIZE }, + {"priv-spec", required_argument, 0, OPT_PRIV_SPEC }, + {"unpriv-spec", required_argument, 0, OPT_UNPRIV_SPEC }, #ifdef SAILCOV {"sailcov-file", required_argument, 0, 'c' }, #endif @@ -459,6 +485,25 @@ static int process_args(int argc, char **argv) case '?': print_usage(argv[0], 1); break; + case OPT_PRIV_SPEC: + int found = 0; + for (int i = 0; i < sizeof(priv_spec_enum_str_lookup)/sizeof(struct priv_spec_enum_str); i++) { + if (strcmp(priv_spec_enum_str_lookup[i].str, optarg) == 0) { + priv_spec = priv_spec_enum_str_lookup[i].e; + _priv_spec_str = priv_spec_enum_str_lookup[i].str; + found = 1; + break; + } + } + if (found == 0) { + fprintf(stderr, "Invalid setting for option, priv-spec: %s\n", optarg); + fprintf(stderr, " Must be one of: \n"); + for (int i = 0; i < sizeof(priv_spec_enum_str_lookup)/sizeof(struct priv_spec_enum_str); i++) { + fprintf(stderr, " %s\n", priv_spec_enum_str_lookup[i].str); + } + exit(1); + } + break; } } if (do_dump_dts) @@ -1248,3 +1293,35 @@ int main(int argc, char **argv) flush_logs(); close_logs(); } + +void priv_spec_vers(sail_string * zret_str, unit u) + { + //========================= + // The following code ...... + // + // *zret_str = "i'm baaaack...\n"; + // + // return; + // + // ... yields a segmentation fault when killing + // the sail_string variable (pointed to by zret_str) + // in the calling code. The calling code assumes that + // memory has been malloc'd for the string, and when + // it's free'd, you get a seg fault. So, I re-wrote + // the code to do the actual malloc. But note the + // assymetry of the memory management: the space is + // allocated here, but free'd at the calling level. + // This is, at least, ugly code. And, at worst, + // prone to error. + //========================= + char * s; + + // TODO: Fix this. this will cause a memory leak. + s = malloc(strlen(_priv_spec_str)); + strcpy(s, _priv_spec_str); + *zret_str = s; + return; + + } + + diff --git a/model/riscv_platform.sail b/model/riscv_platform.sail index b7a498c59..27aaaa99a 100644 --- a/model/riscv_platform.sail +++ b/model/riscv_platform.sail @@ -447,6 +447,10 @@ function init_platform() -> unit = { htif_exit_code = zero_extend(0b0); htif_cmd_write = bitzero; htif_payload_writes = zero_extend(0b0); + + priv_spec = priv_spec_lookup(); + print_platform("priv spec version: " ^ priv_spec_lookup_str(priv_spec)); + } function tick_platform() -> unit = { diff --git a/model/riscv_types.sail b/model/riscv_types.sail index 94c57a34e..1e23a31ed 100644 --- a/model/riscv_types.sail +++ b/model/riscv_types.sail @@ -79,6 +79,7 @@ function arch_to_bits(a : Architecture) -> arch_xlen = } + /* model-internal exceptions */ union exception = { @@ -95,6 +96,48 @@ function internal_error(file, line, s) = { throw Error_internal_error() } +/* spec version enumerations, functions and data */ +val priv_spec_str = { c: "priv_spec_vers" } : unit -> string + +enum priv_spec_enum = {Priv_unspecified, Priv_1_11, Priv_1_12, Priv_1_13} +struct priv_spec_enum_str = { + e : priv_spec_enum , + str : string +} + +//let priv_spec_enum_str_lookup : vector(4, dec, priv_spec_enum_str) = [ +// { Priv_unspecified, "unspecified" }, +// { Priv_1_11, "1.11" }, +// { Priv_1_12, "1.12" }, +// { Priv_1_13, "1.13" }, +//] + +register priv_spec : priv_spec_enum + +val priv_spec_lookup : unit -> priv_spec_enum +function priv_spec_lookup(unit) = { + let str : string = priv_spec_str(); + match (str) { + "unspecified" => Priv_unspecified, + "1.11" => Priv_1_11, + "1.12" => Priv_1_12, + "1.13" => Priv_1_13, + _ => { internal_error(__FILE__, __LINE__, "Invalid priv spec version: " ^ str); Priv_unspecified; } + } +} + +val priv_spec_lookup_str : priv_spec_enum -> string +function priv_spec_lookup_str(e) = { + match (e) { + Priv_unspecified => "unspecified" , + Priv_1_11 => "1.11" , + Priv_1_12 => "1.12" , + Priv_1_13 => "1.13" , + _ => { internal_error(__FILE__, __LINE__, "Invalid priv spec version enum") ; ""} + } +} + + /* privilege levels */ type priv_level = bits(2)