Skip to content

Commit

Permalink
forgot to add cfunc.c and cfunc.h to repo. bah. things compile and st…
Browse files Browse the repository at this point in the history
…art to run, but the loading of ROM doesn't work.
  • Loading branch information
billmcspadden-riscv committed Aug 3, 2022
1 parent 0ab4b85 commit 84ea6fb
Show file tree
Hide file tree
Showing 5 changed files with 309 additions and 38 deletions.
212 changes: 212 additions & 0 deletions c_emulator/cfunc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
// vim: set tabstop=4 shiftwidth=4 expandtab
// ============================================================================
// Filename: cfunc.c
//
// Description: Functions to be called by Sail to get values from a yaml file.
//
// Author(s): Bill McSpadden ([email protected])
//
// Revision: See git log
// ============================================================================

#include <sail.h>
#include "cfunc.h"
#include "string.h"

/* RISC-V Config YAML configuration support */
static char *rv_config_platform_file = NULL;
static int rv_config_platform_fd = 0;
static struct fy_document *rv_config_fyd_platform = NULL;

static char *rv_config_isa_file = NULL;
static int rv_config_isa_fd = 0;
static struct fy_document *rv_config_fyd_isa = NULL;

// rv_cfg_enum2string_a is built (in rv_cfg_init()) so that the
// array index is the enum value. A poor man's associative array.
static rv_cfg_enum2string_t rv_cfg_enum2string_a[RV_CFG_LAST];

#define EXPAND(__ENUM2STR__) { __ENUM2STR__, #__ENUM2STR__ }
static rv_cfg_enum2string_t rv_cfg_enum2string_init_a[] =
{
EXPAND(RV_CFG_ISA),
EXPAND(RV_CFG_PLATFORM),
EXPAND(RV_CFG_DEBUG),
};

static rv_cfg_enum2doc_t rv_cfg_enum2doc_a[RV_CFG_LAST];

// ============================================================================
int
rv_cfg_init()
{
for (int i = 0; i < RV_CFG_LAST; i++)
{
rv_cfg_enum2string_a[rv_cfg_enum2string_init_a[i].e].e = rv_cfg_enum2string_init_a[i].e;
rv_cfg_enum2string_a[rv_cfg_enum2string_init_a[i].e].s = rv_cfg_enum2string_init_a[i].s;
}

}

// ============================================================================
char *
rv_cfg_get_string(rv_cfg_e e)
{
return(rv_cfg_enum2string_a[e].s);
}

// ============================================================================
rv_cfg_e
rv_cfg_get_enum(char * s)
{
for (int i = 0; i < (sizeof(rv_cfg_enum2string_a)/sizeof(rv_cfg_enum2string_t)); i++)
{
if ( strcmp(rv_cfg_enum2string_a[i].s, s) == 0 )
{
return(rv_cfg_enum2string_a[i].e);
}
}
fprintf(stderr, "%s, %d: error: internal error. bad lookup of '%s'\n", __FILE__, __LINE__, s);
exit(1);
}


// ============================================================================
int
rv_cfg_build_from_file(rv_cfg_e rv_cfg_type, char * filename )
{
struct stat buffer;
struct fy_document *fyd = NULL;

printf("%s file: %s\n", rv_cfg_get_string(rv_cfg_type), filename);
if ( (stat(filename, &buffer) == -1) )
{
fprintf(stderr, "%s, %d: error: file, %s, does not exist.\n", __FILE__, __LINE__, filename);
return(0);
}

rv_cfg_enum2doc_a[rv_cfg_type].fyd = fy_document_build_from_file(NULL, filename);
if (! rv_cfg_enum2doc_a[rv_cfg_type].fyd)
{
fprintf(stderr, "unable to build document from %s\n", filename);
return(0);
}
rv_cfg_enum2doc_a[rv_cfg_type].filename = filename;

return (1);
}


// ============================================================================
unsigned int
cfunc_int_c(char * key_str)
{
struct fy_document *fyd = NULL;
unsigned int yaml_val_int;
int count;
char *tmp_str;
// TODO: concersion strings: also need hex, octal (perhaps binary???)


for (int i = 0; i < RV_CFG_LAST; i++)
{
char *conversion_str;
if ( (fyd = rv_cfg_enum2doc_a[i].fyd) == NULL)
{
continue;
}

// TODO: How to iterate through all of the conversion strings
// effeciently?
conversion_str = " %d";
tmp_str = malloc(strlen(key_str) + strlen(conversion_str) + 1);
strcpy(tmp_str, key_str);
strcat(tmp_str, conversion_str);

count = fy_document_scanf(fyd, tmp_str, &yaml_val_int);
if (count == 1)
{
free(tmp_str);
return(yaml_val_int);
}
free(tmp_str);

conversion_str = " 0x%x";
tmp_str = malloc(strlen(key_str) + strlen(conversion_str) + 1);
strcpy(tmp_str, key_str);
strcat(tmp_str, conversion_str);

count = fy_document_scanf(fyd, tmp_str, &yaml_val_int);
if (count == 1)
{
free(tmp_str);
return(yaml_val_int);
}
free(tmp_str);
}

// If we've gotten to this point, we've gone through each of the
// rv_cfg files and didn't find the pattern OR the pattern
// didn't match the conversion string. In either case, there is
// something wrong.

exit(1);
return(0); // Never taken.
}




// ============================================================================
int
cfunc_int(sail_int *zret_int, char * yaml_key_str)
{
mpz_set_ui(*zret_int, cfunc_int_c(yaml_key_str));
return(1);

// struct fy_document *fyd = NULL;
// unsigned int yaml_val_int;
// int count;
// char *tmp_str;
// char *conversion_str = " %d";
//
// tmp_str = malloc(strlen(yaml_key_str) + strlen(conversion_str));
// strcpy(tmp_str, yaml_key_str);
// strcat(tmp_str, conversion_str);
//
// fyd = fy_document_build_from_file(NULL, yaml_filename);
// if ( !fyd )
// {
// fprintf(stderr, "%s, %d: error: failed to build document from yaml file, %s\n", __FILE__, __LINE__, yaml_filename);
// exit(1);
// }
//
// count = fy_document_scanf(fyd, tmp_str, &yaml_val_int);
// if (count == 1)
// {
// mpz_set_ui(*zret_int, yaml_val_int);
// }
// else
// {
// fprintf(stderr, "%s, %d: error: value for key, %s, not found in yaml file, %s\n", __FILE__, __LINE__, yaml_key_str, yaml_filename);
// // TODO: figure out a return mechanism and let caller decide on action.
// exit(1);
// }
//
// // TODO: need to de-allocate memory from fy_document_build_from_file()
// free(fyd);
// free(tmp_str);
//
// return(1);
}

unit
cfunc_dump_yaml(char *yaml_filename)
{
struct fy_document *fyd = NULL;

fyd = fy_document_build_from_file(NULL, yaml_filename);
fy_emit_document_to_fp(fyd, FYECF_DEFAULT | FYECF_SORT_KEYS, stdout);
free(fyd);
}

72 changes: 72 additions & 0 deletions c_emulator/cfunc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// vim: set tabstop=4 shiftwidth=4 expandtab
// ============================================================================
// Filename: cfunc.h
//
// Description: Functions prototype support for cfunc
//
// Author(s): Bill McSpadden ([email protected])
//
// Revision: See git log
// ============================================================================
//#ifndef __CFUNC_H__
//#define __CFUNC_H__
//

#pragma once

#include "sail.h"
#include <libfyaml.h>
#include <sys/stat.h>

// ==================================================
// Function prototypes just for the C side of things.
// The items in this section should only be used on
// the C side of the simulator.

// Keep these in linear order as they are used as indices
// into an array where the index is the enum.
typedef enum
{
RV_CFG_ISA = 0,
RV_CFG_PLATFORM = 1,
RV_CFG_DEBUG = 2,
RV_CFG_LAST = 3
} rv_cfg_e;

typedef struct rv_cfg_enum2string_tt
{
rv_cfg_e e;
char * s;
} rv_cfg_enum2string_t;

typedef struct rv_cfg_enum2doc_tt
{
rv_cfg_e e;
struct fy_document * fyd;
char * filename;
} rv_cfg_enum2doc_t;

int rv_cfg_init(void);
char * rv_cfg_get_string(rv_cfg_e e);
rv_cfg_e rv_cfg_get_enum(char * s);
int rv_cfg_build_from_file(rv_cfg_e rv_cfg_type, char * filename );
unsigned int cfunc_int_c(char *);



// ==================================================
// Function prototypes for the Sail interface

// It doesn't appear that Sail does anything with the
// function's return value. "return values" are done
// by passing a pointer to a return value struct, which
// is the first element in the function's argument list.
//
// TODO: make the return value of type void.

//INT_RET_TYPE cfunc_int(sail_int *, char *, unit); // TODO: find out why unit is sometimes required, sometimes not INT_RET_TYPE cfunc_int(sail_int *, char *);

int cfunc_int(sail_int *, char *);
unit cfunc_dump_yaml(char *);

//#endif
2 changes: 1 addition & 1 deletion c_emulator/riscv_platform_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
/* Settings of the platform implementation. */

// #define DEFAULT_RSTVEC 0x00001000
#define DEFAULT_RSTVEC cfunc_int("./rv32i_platform.yaml", "/reset/address")
#define DEFAULT_RSTVEC cfunc_int_c("/reset/address")

extern bool rv_enable_pmp;
extern bool rv_enable_zfinx;
Expand Down
57 changes: 22 additions & 35 deletions c_emulator/riscv_sim.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include "riscv_platform_impl.h"
#include "riscv_sail.h"

#include "cfunc.h"

#ifdef ENABLE_SPIKE
#include "tv_spike_intf.h"
#else
Expand Down Expand Up @@ -78,14 +80,14 @@ bool config_print_mem_access = true;
bool config_print_platform = true;
bool config_print_rvfi = false;

/* RISC-V Config YAML configuration support */
char *rv_config_platform_file = NULL;
int rv_config_platform_fd = 0;
struct fy_document *rv_config_fyd_platform = NULL;

char *rv_config_isa_file = NULL;
int rv_config_isa_fd = 0;
struct fy_document *rv_config_fyd_isa = NULL;
///* RISC-V Config YAML configuration support */
//char *rv_config_platform_file = NULL;
//int rv_config_platform_fd = 0;
//struct fy_document *rv_config_fyd_platform = NULL;
//
//char *rv_config_isa_file = NULL;
//int rv_config_isa_fd = 0;
//struct fy_document *rv_config_fyd_isa = NULL;


void set_config_print(char *var, bool val) {
Expand Down Expand Up @@ -263,37 +265,19 @@ char *process_args(int argc, char **argv)
, options, NULL);
if (c == -1) break;
switch (c) {
case 'y': {
struct stat buffer;
rv_config_platform_file = optarg;
printf("RISC-V platform YAML file: %s\n", rv_config_platform_file);
if ( (stat(rv_config_platform_file, &buffer) == -1) ) {
fprintf(stderr, "RISC-V Config platform file, %s, does not exist.\n", rv_config_platform_file);
break;
}
rv_config_fyd_platform = fy_document_build_from_file(NULL, rv_config_platform_file);
if (!rv_config_fyd_platform) {
fprintf(stderr, "unable to build fast-yaml document from %s\n", rv_config_platform_file);
break;
case 'y':
if ( rv_cfg_build_from_file(RV_CFG_PLATFORM, optarg) == 0 ) {
fprintf(stderr, "unable to build fast-yaml document from %s\n", optarg);
exit(1);
}

break;

case 'u':
if ( rv_cfg_build_from_file(RV_CFG_ISA, optarg) == 0 ) {
fprintf(stderr, "unable to build fast-yaml document from %s\n", optarg);
exit(1);
}
case 'u': {
struct stat buffer;
rv_config_isa_file = optarg;
printf("RISC-V platform YAML file: %s\n", rv_config_isa_file);
if ( (stat(rv_config_isa_file, &buffer) == -1) ) {
fprintf(stderr, "RISC-V Config ISA file, %s, does not exist.\n", rv_config_isa_file);
}
rv_config_fyd_isa = fy_document_build_from_file(NULL, rv_config_isa_file);
if (!rv_config_fyd_isa) {
fprintf(stderr, "unable to build fast-yaml document from %s\n", rv_config_isa_file);
break;
}

break;
}
case 'a':
report_arch();
break;
Expand Down Expand Up @@ -1027,6 +1011,9 @@ void init_logs()

int main(int argc, char **argv)
{
// Initialize the RISC-V Configuration elements
rv_cfg_init();

// Initialize model so that we can check or report its architecture.
preinit_sail();

Expand Down
4 changes: 2 additions & 2 deletions model/main.sail
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,13 @@
/*=======================================================================================*/

// TODO: put the cfunc interface into a sail file and include it.
val cfunc_int = { c: "cfunc_int" } : (string, string) -> int
val cfunc_int = { c: "cfunc_int" } : (string) -> int

function main () : unit -> unit = {
// initialize extensions
ext_init ();

let reset_address : int = cfunc_int( "./rv32i_platform.sail" , "/reset/address") ;
let reset_address : int = cfunc_int( "/reset/address") ;

// PC = __GetSlice_int(64, elf_entry(), 0);
PC = sail_zero_extend(0x1000, sizeof(xlen));
Expand Down

0 comments on commit 84ea6fb

Please sign in to comment.