Skip to content

Commit

Permalink
intermediate checkin
Browse files Browse the repository at this point in the history
  • Loading branch information
billmcspadden-riscv committed Aug 15, 2022
1 parent c320615 commit d1afe6d
Show file tree
Hide file tree
Showing 11 changed files with 171 additions and 51 deletions.
29 changes: 27 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -345,9 +345,33 @@ Some useful options are: configuring whether misaligned accesses trap
whether page-table walks update PTE bits (`--enable-dirty-update` for C
and `-enable-dirty-update` for OCaml).
### Experimental integration with riscv-config
### Integration with RISCV-Config
RISCV-Config ( https://github.com/riscv-software-src/riscv-config ) is the
configuration standard used by the RISC-V Architectural Compatability Tests
to specify how a RISC-V core is configured. The RISC-V architecture allows
for many implementation specific configurations such as:
- Supported (implemented) ISA extensions
- Misaligned address support (ie - HW support or trap)
- Configuration of WARL fields in CSRs
- Memory map
RISCV-Config utilizes YAML and YAML schemas to describe the configuration.
There are two YAML files that get examined: 1) an ISA YAML file that
describes the configuration of a RISC-V core (ie - supported ISA extensions,
CSR configurations, etc), and 2) a platform YAML file that describes
the platform configurations (ie - reset address, CLIC support, etc).
Configuration is done at run-time not at compile time. (Note: there
was an earlier PR (PR #43) that integrated RISCV-Config as a compile-time
capability. See: [integration with riscv-config](https://github.com/rems-project/sail-riscv/pull/43)
It was determined that a run-time solution was needed rather than a compile-time solution.)
Command line switches specify the YAML files that are to be used.
When adding new extensions to the model, corresponding configuration parameters
need to be added to RISCV-Config.
There is also (as yet unmerged) support for [integration with riscv-config](https://github.com/rems-project/sail-riscv/pull/43) to allow configuring the compiled model according to a riscv-config yaml specification.
### Booting OS images
Expand Down Expand Up @@ -383,6 +407,7 @@ Authors
Nathaniel Wesley Filardo, Microsoft;
Peter Rugg, University of Cambridge;
Scott Johnson, Aril Computer Corp.
William C. McSpadden, RISC-V, International;
Funding
-------
Expand Down
2 changes: 2 additions & 0 deletions c_emulator/riscv_platform_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ bool rv_enable_dirty_update = false;
bool rv_enable_misaligned = false;
bool rv_mtval_has_illegal_inst_bits = false;

uint64_t rv_reset_address = UINT64_C(0x0);

uint64_t rv_ram_base = UINT64_C(0x80000000);
uint64_t rv_ram_size = UINT64_C(0x4000000);

Expand Down
2 changes: 2 additions & 0 deletions c_emulator/riscv_platform_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ extern bool rv_enable_dirty_update;
extern bool rv_enable_misaligned;
extern bool rv_mtval_has_illegal_inst_bits;

extern uint64_t rv_reset_address;

extern uint64_t rv_ram_base;
extern uint64_t rv_ram_size;

Expand Down
63 changes: 32 additions & 31 deletions c_emulator/riscv_sim.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,13 @@ char *sailcov_file = NULL;
#endif

static struct option options[] = {
{"enable-dirty-update", no_argument, 0, 'd'},
// {"enable-dirty-update", no_argument, 0, 'd'},
// {"enable-misaligned", no_argument, 0, 'm'},
{"enable-pmp", no_argument, 0, 'P'},
// {"enable-pmp", no_argument, 0, 'P'},
// {"enable-next", no_argument, 0, 'N'},
{"ram-size", required_argument, 0, 'z'},
// {"ram-size", required_argument, 0, 'z'},
// {"disable-compressed", no_argument, 0, 'C'},
{"disable-writable-misa", no_argument, 0, 'I'},
// {"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'},
Expand Down Expand Up @@ -227,17 +227,17 @@ char *process_args(int argc, char **argv)
while(true) {
c = getopt_long(argc, argv,
"a"
"d"
// "d"
// "m"
"P"
// "P"
// "C"
// "N"
"I"
// "F"
"i"
"s"
"p"
"z:"
// "z:"
"b:"
"t:"
"T:"
Expand Down Expand Up @@ -274,18 +274,18 @@ char *process_args(int argc, char **argv)
case 'a':
report_arch();
break;
case 'd':
fprintf(stderr, "enabling dirty update.\n");
rv_enable_dirty_update = true;
break;
// case 'd':
// fprintf(stderr, "enabling dirty update.\n");
// rv_enable_dirty_update = true;
// break;
// case 'm':
// fprintf(stderr, "enabling misaligned access.\n");
// rv_enable_misaligned = true;
// break;
case 'P':
fprintf(stderr, "enabling PMP support.\n");
rv_enable_pmp = true;
break;
// case 'P':
// fprintf(stderr, "enabling PMP support.\n");
// rv_enable_pmp = true;
// break;
// case 'C':
// fprintf(stderr, "disabling RVC compressed instructions.\n");
// rv_enable_rvc = false;
Expand All @@ -294,10 +294,10 @@ char *process_args(int argc, char **argv)
// fprintf(stderr, "enabling N extension.\n");
// rv_enable_next = true;
// break;
case 'I':
fprintf(stderr, "disabling writable misa CSR.\n");
rv_enable_writable_misa = false;
break;
// case 'I':
// fprintf(stderr, "disabling writable misa CSR.\n");
// rv_enable_writable_misa = false;
// break;
// case 'F':
// fprintf(stderr, "disabling floating point (F and D extensions).\n");
// rv_enable_fdext = false;
Expand All @@ -313,16 +313,16 @@ char *process_args(int argc, char **argv)
fprintf(stderr, "will show execution times on completion.\n");
do_show_times = true;
break;
case 'z':
ram_size = atol(optarg);
if (ram_size) {
fprintf(stderr, "setting ram-size to %" PRIu64 " MB\n", ram_size);
rv_ram_size = ram_size << 20;
} else {
fprintf(stderr, "invalid ram-size '%s' provided.\n", optarg);
exit(1);
}
break;
// case 'z':
// ram_size = atol(optarg);
// if (ram_size) {
// fprintf(stderr, "setting ram-size to %" PRIu64 " MB\n", ram_size);
// rv_ram_size = ram_size << 20;
// } else {
// fprintf(stderr, "invalid ram-size '%s' provided.\n", optarg);
// exit(1);
// }
// break;
case 'b':
dtb_file = strdup(optarg);
fprintf(stderr, "using %s as DTB file.\n", dtb_file);
Expand Down Expand Up @@ -556,8 +556,9 @@ void init_sail_reset_vector(uint64_t entry)
rv_rom_size = rom_end - rv_rom_base;
/* boot at reset vector */
// zPC = rv_rom_base;
zPC = rv_cfg_int_c("/reset/address");
printf("%s, %d: reset address: 0x%lx\n", __FILE__, __LINE__, zPC);
// zPC = rv_cfg_int_c("/reset/address");
zPC = rv_reset_address;
// printf("%s, %d: reset address: 0x%lx\n", __FILE__, __LINE__, zPC);
}

void preinit_sail()
Expand Down
107 changes: 91 additions & 16 deletions c_emulator/rv_cfg_func.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,76 @@ rv_cfg_configure_c()
{
char * RV_ISA;


// ====================================================================
// Get the ISA string. Much of the configuration is derived from this
// string.
RV_ISA = rv_cfg_string_c("/hart0/ISA");
printf("%s, %d: RV_ISA: '%s'\n", __FILE__, __LINE__, RV_ISA);

rv_enable_rvc = rv_cfg_ext_enable_c(RV_ISA, "C");
rv_enable_fdext = rv_cfg_ext_enable_c(RV_ISA, "F");
rv_enable_next = rv_cfg_ext_enable_c(RV_ISA, "N");
rv_enable_zfinx = rv_cfg_ext_enable_c(RV_ISA, "Zfinx");
// ====================================================================
// Do the configuration.
rv_enable_rvc = rv_cfg_ext_enable_c(RV_ISA, "C");
rv_enable_fdext = rv_cfg_ext_enable_c(RV_ISA, "F");
rv_enable_next = rv_cfg_ext_enable_c(RV_ISA, "N");
rv_enable_zfinx = rv_cfg_ext_enable_c(RV_ISA, "Zfinx");
rv_enable_dirty_update = rv_cfg_ext_enable_c(RV_ISA, "Ssptead"); //TODO: Use this, ....
//rv_enable_dirty_update = rv_cfg_bool_c("/hart0/pte_dirty_update_enable"); // .... not this

rv_enable_misaligned = rv_cfg_bool_c("/hart0/hw_data_misaligned_support");

rv_enable_pmp = (
(rv_cfg_bool_c("/hart0/pmpaddr0/rv32/accessible") ) ||
(rv_cfg_bool_c("/hart0/pmpaddr0/rv64/accessible") )
) ;

rv_ram_size = rv_cfg_int_c("/ram_size") << 20; // Convert to MBs
rv_reset_address = rv_cfg_int_c("/reset/address");

// TODO: make a rv_cfg method that returns true if key exists; false otherwise
//rv_enable_writable_misa = (fy_node_mapping_lookup_by_string( rv_cfg_enum2doc_a[RV_CFG_ISA].fyd, "/hart0/misa/rv32/extensions/type/warl", -1) == NULL) ? false : true;
//rv_enable_writable_misa = (fy_document_tag_directive_lookup(rv_cfg_enum2doc_a[RV_CFG_ISA].fyd, "/hart0/misa/rv32/extensions/type/warl") == NULL) ? false : true;
//rv_enable_writable_misa = (fy_document_tag_directive_lookup(rv_cfg_enum2doc_a[RV_CFG_ISA].fyd, "/hart0/misa/rv32/extensions/type/warl/") == NULL) ? false : true;
//rv_enable_writable_misa = (fy_document_tag_directive_lookup(rv_cfg_enum2doc_a[RV_CFG_ISA].fyd, "/hart0") == NULL) ? false : true;

rv_enable_writable_misa = rv_cfg_path_exists_c("/hart0/misa/rv32/extensions/type/warl");




// ====================================================================
// Print out the configuration that you just pulled out from the
// RISCV-Config files. Print it out in terms of the Golden Model
// variables that are used in Sail.
//#define CFG_STRING_FMT "%-32s"
#define CFG_STRING_FMT "%-48s"
// printf("%s: '%s'\n", "RV_ISA: ", RV_ISA);
// printf("%-48s '%s'\n", "RV_ISA: ", RV_ISA);
printf(CFG_STRING_FMT "'%s'\n", "RV_ISA: ", RV_ISA);
printf(CFG_STRING_FMT "%s\n", "C ext support (rv_enable_rvc): " , rv_enable_rvc ? "true" : "false");
printf(CFG_STRING_FMT "%s\n", "F/D ext support (rv_enable_fdext):", rv_enable_fdext ? "true" : "false");
printf(CFG_STRING_FMT "%s\n", "N ext support (rv_enable_next): ", rv_enable_next ? "true" : "false");
printf(CFG_STRING_FMT "%s\n", "Zfinx ext support (rv_enable_zfinx): ", rv_enable_zfinx ? "true" : "false");
printf(CFG_STRING_FMT "%s\n", "enable misaligned support (rv_enable_misaligned): ", rv_enable_misaligned ? "true" : "false");
printf(CFG_STRING_FMT "%s\n", "enable pmp support (rv_enable_pmp): ", rv_enable_pmp ? "true" : "false");
printf(CFG_STRING_FMT "%ld MB\n", "ram size (rv_ram_size): ", rv_ram_size >> 20);
printf(CFG_STRING_FMT "0x%lx\n", "reset address (rv_reset_address, zPC): ", rv_reset_address);
printf(CFG_STRING_FMT "%s\n", "PTE dirty update enable (rv_enable_dirty_update): ", rv_enable_dirty_update ? "true" : "false");
printf(CFG_STRING_FMT "%s\n", "writable misa (rv_enable_writable_misa): ", rv_enable_writable_misa ? "true" : "false");


// ====================================
// Error checking of configuration.
// Most error checking of allowed configurations is done
// by the RISCV-Config validator script. It is assumed
// that the user has validated his implementation-specific
// config file using the validator script.
//
// TODO: Would it make sense to run the validator script
// here in order to ensure that legal configurations
// are being run? I believe RISCOF already does this
// when running the arch-tests.

// TODO: Need a method for getting XLEN from the Sail model so
// that we can compare it against the ISA string.
// // ====================================
// // Error checking of configuration. XLEN
// printf("%s, %d: zxlen_val: %ld\n", __FILE__, __LINE__, zxlen_val);
Expand Down Expand Up @@ -108,18 +166,35 @@ rv_cfg_configure_c()
// }

// ====================================
// Check extension settings
// Check extension settings for mutual exclusivity
// TODO: should I introduce 'assert' as an error reporting mechanism
// instead of this ad hoc mechanism?
if ((rv_enable_fdext == true) && (rv_enable_zfinx == true))
{
fprintf(stderr, "%s, %d: incompatable settings for [fd]ext and Zfinx. both cannot be enabled.",
__FILE__, __LINE__);
exit(1);
}

// ====================================
// Print out the configuration settings
}

// ============================================================================
bool
rv_cfg_path_exists_c(char * path)
{
struct fy_path_parse_cfg cfg;
struct fy_path_parser *fypp;
bool ret;

cfg.flags = FYPPCF_QUIET;
cfg.userdata = NULL;
cfg.diag = NULL;

fypp = fy_path_parser_create(&cfg);
ret = (fy_path_parse_expr_from_string(fypp, "/hart0/misa/rv32/extensions/type/warl", -1) == NULL) ? false : true;
fy_path_parser_destroy(fypp);

return(ret);
}

// ============================================================================
Expand Down Expand Up @@ -183,7 +258,7 @@ rv_cfg_ext_enable_c(char * isa_str, char * ext_pattern)
match_data, /* block for storing the result */
NULL); /* use default match context */

printf("%s, %d: rc: %d\n", __FILE__, __LINE__, rc);
// printf("%s, %d: rc: %d\n", __FILE__, __LINE__, rc);

if ((rc == 0) || (rc == -1))
{
Expand Down Expand Up @@ -266,7 +341,7 @@ rv_cfg_int_c(char * key_str)
int yaml_val_int;
int count;
char *tmp_str;
// TODO: concersion strings: also need hex, octal (perhaps binary???)
// TODO: conversion strings: also need hex, octal (perhaps binary???)


for (int i = 0; i < RV_CFG_LAST; i++)
Expand All @@ -287,7 +362,7 @@ rv_cfg_int_c(char * key_str)
if (count == 1)
{
free(tmp_str);
//printf("%s, %d: value found, 0x%x, in %s\n", __FILE__, __LINE__, yaml_val_int, rv_cfg_enum2doc_a[i].filename);
printf("%s, %d: value found, 0x%x, in %s\n", __FILE__, __LINE__, yaml_val_int, rv_cfg_enum2doc_a[i].filename);
//fy_emit_document_to_fp(fyd, FYECF_DEFAULT | FYECF_SORT_KEYS, stdout);
return(yaml_val_int);
}
Expand All @@ -309,12 +384,11 @@ char *
rv_cfg_string_c(char * key_str)
{
struct fy_document *fyd = NULL;
//char * yaml_val_string;
// char *yaml_val_string;
char yaml_val_string[1024];
int count;
char *tmp_str;
char * ret_str_ptr;

char *ret_str_ptr;

for (int i = 0; i < RV_CFG_LAST; i++)
{
Expand All @@ -338,6 +412,7 @@ rv_cfg_string_c(char * key_str)
printf("%s, %d: value found, '%s', in %s\n", __FILE__, __LINE__, yaml_val_string, rv_cfg_enum2doc_a[i].filename);
ret_str_ptr = malloc(strlen(yaml_val_string)); // TODO: where should this be freed?
strcpy(ret_str_ptr, yaml_val_string);
// ret_str_ptr = yaml_val_string;
//fy_emit_document_to_fp(fyd, FYECF_DEFAULT | FYECF_SORT_KEYS, stdout);
return(ret_str_ptr);
}
Expand Down Expand Up @@ -379,7 +454,7 @@ int
//rv_cfg_string(sail_string **s, char * yaml_key_str)
rv_cfg_string(sail_string s, char * yaml_key_str)
{
printf("%s, %d: entering rv_cfg_string()\n", __FILE__, __LINE__);
// printf("%s, %d: entering rv_cfg_string()\n", __FILE__, __LINE__);
s = rv_cfg_string_c(yaml_key_str);
return(1);
}
Expand Down
1 change: 1 addition & 0 deletions c_emulator/rv_cfg_func.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ int rv_cfg_configure_c(void);
void rv_cfg_dump_yaml_c(char *);
int rv_cfg_ext_enable_c(char * isa_str, char * ext_pattern);
bool rv_cfg_bool_c(char * key_str);
bool rv_cfg_path_exists_c(char * path);



Expand Down
1 change: 1 addition & 0 deletions cookbook/doc/TheRISCVSailCookbook_Main.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
The RISCV Sail Golden Model: A Cookbook for the RISCV ISA
==============================================
William C. McSpadden <bill@riscv.org>; Martin Berger <contact@martinfriedrichberger.net>

:toc:
:toc-placement: preamble
:toclevels: 2
Expand Down
Loading

0 comments on commit d1afe6d

Please sign in to comment.