Merge pull request #113 from riscv/debug_readme
[riscv-isa-sim.git] / README.md
1 RISC-V ISA Simulator
2 ======================
3
4 Author : Andrew Waterman, Yunsup Lee
5
6 Date : June 19, 2011
7
8 Version : (under version control)
9
10 About
11 -------------
12
13 The RISC-V ISA Simulator implements a functional model of one or more
14 RISC-V processors.
15
16 Build Steps
17 ---------------
18
19 We assume that the RISCV environment variable is set to the RISC-V tools
20 install path, and that the riscv-fesvr package is installed there.
21
22 $ apt-get install device-tree-compiler
23 $ mkdir build
24 $ cd build
25 $ ../configure --prefix=$RISCV --with-fesvr=$RISCV
26 $ make
27 $ [sudo] make install
28
29 Compiling and Running a Simple C Program
30 -------------------------------------------
31
32 Install spike (see Build Steps), riscv-gnu-toolchain, and riscv-pk.
33
34 Write a short C program and name it hello.c. Then, compile it into a RISC-V
35 ELF binary named hello:
36
37 $ riscv64-unknown-elf-gcc -o hello hello.c
38
39 Now you can simulate the program atop the proxy kernel:
40
41 $ spike pk hello
42
43 Simulating a New Instruction
44 ------------------------------------
45
46 Adding an instruction to the simulator requires two steps:
47
48 1. Describe the instruction's functional behavior in the file
49 riscv/insns/<new_instruction_name>.h. Examine other instructions
50 in that directory as a starting point.
51
52 2. Add the opcode and opcode mask to riscv/opcodes.h. Alternatively,
53 add it to the riscv-opcodes package, and it will do so for you:
54
55 $ cd ../riscv-opcodes
56 $ vi opcodes // add a line for the new instruction
57 $ make install
58
59 3. Rebuild the simulator.
60
61 Interactive Debug Mode
62 ---------------------------
63
64 To invoke interactive debug mode, launch spike with -d:
65
66 $ spike -d pk hello
67
68 To see the contents of an integer register (0 is for core 0):
69
70 : reg 0 a0
71
72 To see the contents of a floating point register:
73
74 : fregs 0 ft0
75
76 or:
77
78 : fregd 0 ft0
79
80 depending upon whether you wish to print the register as single- or double-precision.
81
82 To see the contents of a memory location (physical address in hex):
83
84 : mem 2020
85
86 To see the contents of memory with a virtual address (0 for core 0):
87
88 : mem 0 2020
89
90 You can advance by one instruction by pressing <enter>. You can also
91 execute until a desired equality is reached:
92
93 : until pc 0 2020 (stop when pc=2020)
94 : until mem 2020 50a9907311096993 (stop when mem[2020]=50a9907311096993)
95
96 Alternatively, you can execute as long as an equality is true:
97
98 : while mem 2020 50a9907311096993
99
100 You can continue execution indefinitely by:
101
102 : r
103
104 At any point during execution (even without -d), you can enter the
105 interactive debug mode with `<control>-<c>`.
106
107 To end the simulation from the debug prompt, press `<control>-<c>` or:
108
109 : q
110
111 Debugging With Gdb
112 ------------------
113
114 An alternative to interactive debug mode is to attach using gdb. Because spike
115 tries to be like real hardware, you also need OpenOCD to do that. OpenOCD
116 doesn't currently know about address translation, so it's not possible to
117 easily debug programs that are run under `pk`. We'll use the following test
118 program:
119 ```
120 $ cat rot13.c
121 char text[] = "Vafgehpgvba frgf jnag gb or serr!";
122
123 // Don't use the stack, because sp isn't set up.
124 volatile int wait = 1;
125
126 int main()
127 {
128 while (wait)
129 ;
130
131 // Doesn't actually go on the stack, because there are lots of GPRs.
132 int i = 0;
133 while (text[i]) {
134 char lower = text[i] | 32;
135 if (lower >= 'a' && lower <= 'm')
136 text[i] += 13;
137 else if (lower > 'm' && lower <= 'z')
138 text[i] -= 13;
139 i++;
140 }
141
142 while (!wait)
143 ;
144 }
145 $ cat spike.lds
146 OUTPUT_ARCH( "riscv" )
147
148 SECTIONS
149 {
150 . = 0x10010000;
151 .text : { *(.text) }
152 .data : { *(.data) }
153 }
154 $ riscv64-unknown-elf-gcc -g -Og -o rot13-64.o -c rot13.c
155 $ riscv64-unknown-elf-gcc -g -Og -T spike.lds -nostartfiles -o rot13-64 rot13-64.o
156 ```
157
158 To debug this program, first run spike telling it to listen for OpenOCD:
159 ```
160 $ spike --rbb-port=9824 -m0x10000000:0x20000 rot13-64
161 Listening for remote bitbang connection on port 9824.
162 ```
163
164 In a separate shell run OpenOCD with the appropriate configuration file:
165 ```
166 $ cat spike.cfg
167 interface remote_bitbang
168 remote_bitbang_host localhost
169 remote_bitbang_port 9824
170
171 set _CHIPNAME riscv
172 jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913
173
174 set _TARGETNAME $_CHIPNAME.cpu
175 target create $_TARGETNAME riscv -chain-position $_TARGETNAME
176
177 gdb_report_data_abort enable
178
179 init
180 halt
181 $ openocd -f spike.cfg
182 Open On-Chip Debugger 0.10.0-dev-00002-gc3b344d (2017-06-08-12:14)
183 ...
184 riscv.cpu: target state: halted
185 ```
186
187 In yet another shell, start your gdb debug session:
188 ```
189 tnewsome@compy-vm:~/SiFive/spike-test$ riscv64-unknown-elf-gdb rot13-64
190 GNU gdb (GDB) 7.12.50.20170505-git
191 Copyright (C) 2016 Free Software Foundation, Inc.
192 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
193 This is free software: you are free to change and redistribute it.
194 There is NO WARRANTY, to the extent permitted by law. Type "show copying"
195 and "show warranty" for details.
196 This GDB was configured as "--host=x86_64-pc-linux-gnu --target=riscv64-unknown-elf".
197 Type "show configuration" for configuration details.
198 For bug reporting instructions, please see:
199 <http://www.gnu.org/software/gdb/bugs/>.
200 Find the GDB manual and other documentation resources online at:
201 <http://www.gnu.org/software/gdb/documentation/>.
202 For help, type "help".
203 Type "apropos word" to search for commands related to "word"...
204 Reading symbols from rot13-64...done.
205 (gdb) target remote localhost:3333
206 Remote debugging using localhost:3333
207 0x000000001001000a in main () at rot13.c:8
208 8 while (wait)
209 (gdb) print wait
210 $1 = 1
211 (gdb) print wait=0
212 $2 = 0
213 (gdb) print text
214 $3 = "Vafgehpgvba frgf jnag gb or serr!"
215 (gdb) b 23
216 Breakpoint 1 at 0x10010064: file rot13.c, line 23.
217 (gdb) c
218 Continuing.
219
220 Breakpoint 1, main () at rot13.c:23
221 23 while (!wait)
222 (gdb) print wait
223 $4 = 0
224 (gdb) print text
225 ...
226 ```