riscv-software-src / riscv-isa-sim

Spike, a RISC-V ISA Simulator
Other
2.45k stars 858 forks source link

Spike ignores `--pc` argument #1290

Open xobs opened 1 year ago

xobs commented 1 year ago

Spike appears to ignore the --pc argument, regardless of where it is placed on the command line:

user@Ondo:/opt/Xous/renode-ebreak-test$ /opt/Xous/spike/bin/spike -d --pc=0x80000000 -l -m1 --disable-dtb  --isa=RV32IMAC target/riscv32imac-unknown-none-elf/debug/renode-ebreak-test  --pc=0x80000000
warning: tohost and fromhost symbols not in ELF; can't communicate with target
(spike) pc 0
0x00001000
(spike)
xobs commented 1 year ago

I was able to get the simulator to work by patching riscv/platform.h:

diff --git a/riscv/platform.h b/riscv/platform.h
index 2bafa68d..3bc7ff18 100644
--- a/riscv/platform.h
+++ b/riscv/platform.h
@@ -2,7 +2,7 @@
 #ifndef _RISCV_PLATFORM_H
 #define _RISCV_PLATFORM_H

-#define DEFAULT_RSTVEC     0x00001000
+#define DEFAULT_RSTVEC     0x80000000
 #define CLINT_BASE         0x02000000
 #define CLINT_SIZE         0x000c0000
 #define PLIC_BASE          0x0c000000

There were a few other patches I had to make to get things working for my purposes -- mostly due to the fact that HTIF seems to not work well on 32-bit platforms due to the split writes -- and I'm very glad this project existed to validate my design

aswaterman commented 1 year ago

It works by patching the boot ROM; you'll see its effect if you run for a few instructions:

$ spike -d --pc=0x87654320 pk
(spike) r 6
core   0: 0x0000000000001000 (0x00000297) auipc   t0, 0x0
core   0: 0x0000000000001004 (0x02028593) addi    a1, t0, 32
core   0: 0x0000000000001008 (0xf1402573) csrr    a0, mhartid
core   0: 0x000000000000100c (0x0182b283) ld      t0, 24(t0)
core   0: 0x0000000000001010 (0x00028067) jr      t0
core   0: 0x0000000087654320 (0x00000000) c.unimp
core   0: exception trap_illegal_instruction, epc 0x0000000087654320
core   0:           tval 0x0000000000000000
(spike) q
TommyMurphyTM1234 commented 1 year ago

So, is it the case that this issue is invalid or maybe that the usage help for --pc should clarify that the specified PC does not take immediate effect?

but only after this code has processed it:

xobs commented 1 year ago

The issue, I think, is that I'm not sure how to use the ISA sim.

I was trying to validate the behaviour of an emulator, so I wrote a small RISC-V program that demonstrates the issue. I linked it at 0x80000000. I ran Spike by passing it my ELF file:

spike \
    -l \
    --pc=0x80000000 \
    -m0x80000000:1048576,0x40008000:4096 \
    --disable-dtb  \
    --isa=RV32IMAC \
    target/riscv32imac-unknown-none-elf/debug/renode-ebreak-test

Since I'm testing the behaviour of the emulator itself, and I want it to be cycle-accurate, and I'm modeling exception handling, I don't want it running under a kernel. I just want something that parses RISC-V instructions and works according to the spec.

I'm able to get that by simply setting the PC to the start of my program, which is what I assumed --pc did. It did not, but patching DEFAULT_RSTVEC and recompiling did allow it to work.

I'm not able to get your example working, but perhaps that's because I'm not using the same kernel you are:

$ spike -d --pc=0x80000000 -m0x80000000:1048576,0x40008000:4096 --disable-dtb  --isa=RV32IMAC ebreak-test
(spike) r 6
core   0: exception trap_instruction_access_fault, epc 0x00001000
core   0:           tval 0x00001000
core   0: exception trap_instruction_access_fault, epc 0x00000000
core   0:           tval 0x00000000
core   0: exception trap_instruction_access_fault, epc 0x00000000
core   0:           tval 0x00000000
core   0: exception trap_instruction_access_fault, epc 0x00000000
core   0:           tval 0x00000000
core   0: exception trap_instruction_access_fault, epc 0x00000000
core   0:           tval 0x00000000
core   0: exception trap_instruction_access_fault, epc 0x00000000
core   0:           tval 0x00000000
(spike)
TommyMurphyTM1234 commented 1 year ago

Since I'm testing the behaviour of the emulator itself, and I want it to be cycle-accurate, and I'm modeling exception handling, I don't want it running under a kernel.

Can't you run self-contained bare metal programs on Spike by simply doing:

spike my-bare-metal-program.elf

Even if you use the Proxy Kernel (pk) I don't think that it adds any overhead unless your program causes calls into it?

xobs commented 1 year ago

Can't you run self-contained bare metal programs on Spike by simply doing:

That doesn't seem to work:

$ spike -d ebreak-test
Error: cannot execute 32-bit program on RV64 hart
$

However, it does work if I add --isa=RV32IMAC:

$ spike -d --isa=RV32IMAC ebreak-test
warning: tohost and fromhost symbols not in ELF; can't communicate with target
(spike) r 6
core   0: 0x00001000 (0x00000297) auipc   t0, 0x0
core   0: 0x00001004 (0x02028593) addi    a1, t0, 32
core   0: 0x00001008 (0xf1402573) csrr    a0, mhartid
core   0: 0x0000100c (0x0182a283) lw      t0, 24(t0)
core   0: 0x00001010 (0x00028067) jr      t0
core   0: 0x80000000 (0x800000b7) lui     ra, 0x80000
(spike)

Though I did just discover something very interesting: Apparently there is a ROM that gets inserted at address 0x00001000 (as pointed out by @TommyMurphyTM1234), but this ROM is omitted when spike is passed the --disable-dtb flag. I was building with --disable-dtb since I didn't see any documentation on where the DTB is placed, and I know I've seen some emulators that happen to place it at 0x80000000.

I didn't expect the machine behaviour to change by disabling the DTB, but apparently that happens.

It would be helpful to have the following:

  1. A note that the machine will unconditionally start execution at 0x00001000
  2. There is a ROM at this address that will jump to the program counter specified by --pc, or to 0x80000000 if unspecified
  3. A note that saying --disable-dtb also disables the boot ROM, and users will need to provide their own ROM at address 0x00001000