Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
//-----------------------------------------------------------------
// RISC-V ISA Simulator
// V1.0
// Ultra-Embedded.com
// Copyright 2014-2017
//
// admin@ultra-embedded.com
//
// License: BSD
//-----------------------------------------------------------------
//
// Copyright (c) 2014, Ultra-Embedded.com
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// - Neither the name of the author nor the names of its contributors
// may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
//-----------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include "riscv.h"
#include "elf_load.h"
#include "cosim_api.h"
#include "riscv_main.h"
//-----------------------------------------------------------------
// mem_create: Create memory region
//-----------------------------------------------------------------
static int mem_create(void *arg, uint32_t base, uint32_t size)
{
return cosim::instance()->create_memory(base, size);
}
//-----------------------------------------------------------------
// mem_load: Load byte into memory
//-----------------------------------------------------------------
static int mem_load(void *arg, uint32_t addr, uint8_t data)
{
cosim::instance()->write(addr, data);
return cosim::instance()->valid_addr(addr);
}
//-----------------------------------------------------------------
// riscv_main
//-----------------------------------------------------------------
int riscv_main(cosim_cpu_api *sim, int argc, char *argv[])
{
unsigned _cycles = 0;
int max_cycles = -1;
char *filename = NULL;
int help = 0;
int trace = 0;
uint32_t trace_mask = 1;
uint32_t stop_pc = 0xFFFFFFFF;
uint32_t trace_pc = 0xFFFFFFFF;
uint32_t mem_base = 0x00000000;
uint32_t mem_size = (32 * 1024 * 1024);
bool explicit_mem = false;
char * dump_file = NULL;
char * dump_sym_start = NULL;
char * dump_sym_end = NULL;
int c;
while ((c = getopt (argc, argv, "t:v:f:c:r:d:b:s:e:p:j:k:")) != -1)
{
switch(c)
{
case 't':
trace = strtoul(optarg, NULL, 0);
break;
case 'v':
trace_mask = strtoul(optarg, NULL, 0);
break;
case 'r':
stop_pc = strtoul(optarg, NULL, 0);
break;
case 'f':
filename = optarg;
break;
case 'c':
max_cycles = (int)strtoul(optarg, NULL, 0);
break;
case 'b':
mem_base = strtoul(optarg, NULL, 0);
explicit_mem = true;
break;
case 's':
mem_size = strtoul(optarg, NULL, 0);
explicit_mem = true;
break;
case 'e':
trace_pc = strtoul(optarg, NULL, 0);
break;
case 'p':
dump_file = optarg;
break;
case 'j':
dump_sym_start = optarg;
break;
case 'k':
dump_sym_end = optarg;
break;
case '?':
default:
help = 1;
break;
}
}
if (help || filename == NULL)
{
fprintf (stderr,"Usage:\n");
fprintf (stderr,"-f filename.elf = Executable to load (ELF)\n");
fprintf (stderr,"-t [0/1] = Enable program trace\n");
fprintf (stderr,"-v 0xX = Trace Mask\n");
fprintf (stderr,"-c nnnn = Max instructions to execute\n");
fprintf (stderr,"-r 0xnnnn = Stop at PC address\n");
fprintf (stderr,"-e 0xnnnn = Trace from PC address\n");
fprintf (stderr,"-b 0xnnnn = Memory base address (for binary loads)\n");
fprintf (stderr,"-s nnnn = Memory size (for binary loads)\n");
fprintf (stderr,"-p dumpfile.bin = Post simulation memory dump file\n");
fprintf (stderr,"-j sym_name = Symbol for memory dump start\n");
fprintf (stderr,"-k sym_name = Symbol for memory dump end\n");
exit(-1);
}
if (explicit_mem)
{
printf("MEM: Create memory 0x%08x-%08x\n", mem_base, mem_base + mem_size-1);
mem_create(NULL, mem_base, mem_size);
}
uint32_t start_addr = 0;
// Load ELF file
if (elf_load(filename, mem_create, mem_load, sim, &start_addr))
{
printf("Starting from 0x%08x\n", start_addr);
// Register dump handler
if (dump_file)
{
cosim::instance()->dump_on_exit(dump_file,
(uint32_t)elf_get_symbol(filename, dump_sym_start),
(uint32_t)elf_get_symbol(filename, dump_sym_end));
}
// Reset CPU to given start PC
sim->reset(start_addr);
// Enable trace?
if (trace)
sim->enable_trace(trace_mask);
_cycles = 0;
uint32_t current_pc = 0;
while (!sim->get_fault() && !sim->get_stopped() && current_pc != stop_pc)
{
current_pc = sim->get_pc();
sim->step();
_cycles++;
if (max_cycles != -1 && max_cycles == _cycles)
break;
// Turn trace on
if (trace_pc == current_pc)
sim->enable_trace(trace_mask);
}
cosim::instance()->at_exit(sim->get_fault());
}
else
fprintf (stderr,"Error: Could not open %s\n", filename);
// Fault occurred?
if (sim->get_fault())
return 1;
else
return 0;
}
7ae6f803eThis file is pinned to the selected release. Download the original to open it in your design tool.