riscv-software-src / riscv-isa-sim

Spike, a RISC-V ISA Simulator
Other
2.4k stars 849 forks source link

Canonical way of setting data memory #60

Open zwabbit opened 8 years ago

zwabbit commented 8 years ago

I have the need to load some data into the RISCV memory space in spike before I start the simulation, but looking at the code there doesn't seem to be functionality to do this. The closest way I can see seems to be to use the addr_to_mem function in the sim_t class to get access to the memory mapped offset, but those methods are private. Is there an alternative, or should I just hack my local copy and make those public so that I can do what I need to do?

aswaterman commented 8 years ago

Initial program loading etc. is driven by the HTIF in libfesvr (https://github.com/riscv/riscv-fesvr/blob/master/fesvr/htif.cc).

zwabbit commented 8 years ago

It's not instructions I'm trying to load, it's data.

aswaterman commented 8 years ago

Instructions are data

zwabbit commented 8 years ago

Err, no, not in this context. I have data that is not part of the ELF file that I need to load. Which actually raises another problem.

Currently the simulator requires that you specify the executable you want to load at instantiation time. The load_program in the HTIF class pulls the path to the ELF file from the targs member, which is private and as far as I can tell only accessible when the class is created. As far as I can tell, I can't load in another elf file with the same simulator instance, I have to create a new one.

aswaterman commented 8 years ago

I see. Indeed, there's no ready-made mechanism for what you're trying to do, aside from getting the data into your ELF. (It's not the worst solution, just very inconvenient.)

timsifive commented 8 years ago

You could connect to spike with gdb, which supports some commands to load binary data from files to memory. It'll be slowish, though.

Tim

On Thu, Aug 11, 2016 at 3:28 PM, Andrew Waterman notifications@github.com wrote:

I see. Indeed, there's no ready-made mechanism for what you're trying to do, aside from getting the data into your ELF. (It's not the worst solution, just very inconvenient.)

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/riscv/riscv-isa-sim/issues/60#issuecomment-239312828, or mute the thread https://github.com/notifications/unsubscribe-auth/APYH7TSqgXGfQ2MHSe45XGHXIAElpUXrks5qe6IbgaJpZM4Jiivk .

zwabbit commented 8 years ago

Looking at the source code there are two functions, read_chunk and write_chunk, that seem to be used for accessing the simulated core's memory. They're defined as public in the HTIF parent class, but are set as private in the sim_t child class. Is there a reason for this?

Also, any plans to allow for dynamically loading programs after the sim_t class has been instantiated?

zwabbit commented 8 years ago

Or for that matter are you guys open to patches to expose those abilities.

aswaterman commented 8 years ago

dynamically loading programs after the simulator starts is best handled at a higher level (e.g., by statically loading an OS, which can then dynamically load programs and libraries)

read_chunk and write_chunk are low-level routines; you are better off using sim.memif().read()/write(), which are public

zwabbit commented 8 years ago

Compiler did not like that, when I tried to call memif's write function it generated the error:

error: ‘simulatedCore->htif_t::memif’ does not have class type

aswaterman commented 8 years ago

I added the following nonsense line to spike.cc and verified it does compile:

s.memif().write(0, 0, 0);

so I have no idea what's up

zwabbit commented 8 years ago

It was me being an idiot...I kept thinking that was a member variable and not a member method.

zwabbit commented 8 years ago

Are the data and instruction memories in the same space? In theory could I use the memif functions to also load program instructions after the fact?

aswaterman commented 8 years ago

There is a unified address space. But the instruction stream is incoherent with the data stream, so you need to execute a FENCE.I instruction before executing dynamically loaded code.

aswaterman commented 8 years ago

(see Section 2.7 of https://riscv.org/specifications/)

zwabbit commented 8 years ago

So just a clarification on what address I'm actually permitted to write to. Based off of the base addresses in the encoding, if I wanted to write to what is effectively "memory" in the simulator, I should be writing only to addresses past 0x80000000 as indicated by DRAM_BASE in the encoding.h file?

Also side question, unless it got changed in the 1.9 rev, I thought the reset vector was addressed at 0x200? The header file seems to have it at 0x1000.

aswaterman commented 8 years ago

Right.

The reset vector did move (it's now a platform property, rather than being nailed down in the privileged ISA).

zwabbit commented 8 years ago

1) And the question about writing to memory?

2) Followup on reset, by platform property, are you saying that that literally can change for any RISCV processor depending on who implements it? That would seem to imply that anyone seeking to write a bare-metal program would potentially need to recompile to accommodate differences in the reset vector in order to properly locate the program start. Is there going to be a "standard" platform property set down somewhere to use as a baseline?

aswaterman commented 8 years ago

1) Yes.

2) Yes. It's kind of unavoidable, as different platforms demand different memory maps (consider, for example, replacing another vendor's core with a RISC-V core, but trying to keep the rest of the system the same).

That said, Spike follows the SiFive platform memory map, which we expect to be a de facto standard once it is finalized.

zwabbit commented 8 years ago

That promises a degree of complication with the compiler as well. At present the current version of the compiler linked in by riscv-tools sets the entrypoint for the program at address 0x200. Granted the version of spike in that repo is also from February, so I presume at the very least that set of programs will be kept synchronized with each other?

zwabbit commented 8 years ago

I've had to revert back to the version of spike that's linked in as a submodule in the riscv-tools repository to make sure I have everything in sync, from compilers and etc. That version (and the associated riscv-fesvr) still has the memif interface for read and write, though getting to it was a bit more cumbersome. The problem when I tried to use the two however was an assert got fired in at fesvr/context.cc:69 in the switch_to method. I'm not clear on what this assert is trying to guard against so any pointers would be helpful. I'm calling the memif write method before the sim_t::run method is called if that matters.