1 |
147 |
chris |
Originally by Chris Ziomkowski
|
2 |
1242 |
hpanther |
Some Additions by Heiko Panther
|
3 |
|
|
|
4 |
147 |
chris |
Brief introduction to using GDB based debugging with or1ksim
|
5 |
|
|
|
6 |
|
|
GDB uses the JTAG proxy server included in or1ksim to communicate
|
7 |
|
|
directly with the simulator. Only 1 connection is allowed to the
|
8 |
|
|
proxy server at a time. Attempting a second connection will terminate
|
9 |
|
|
the previous connection. This is very useful when the gdb or1k
|
10 |
|
|
process terminates abnormally (such as when you are debugging the
|
11 |
|
|
debugger.) In this case it is impossible to notify the JTAG server
|
12 |
|
|
that the socket has shut down, and therefore it will assume that a
|
13 |
|
|
new connection implies the termination of the previous process.
|
14 |
|
|
|
15 |
|
|
The or1ksim will start the JTAG proxy server on the port specified
|
16 |
|
|
for service "jtag". If such a service is not specified, the server
|
17 |
|
|
will choose a random port number. This behavior can be overridden by
|
18 |
|
|
specifying the port number to the simulator using the -srv option.
|
19 |
|
|
As an example, "sim -srv 9999" starts up the simulator with the
|
20 |
|
|
JTAG proxy server on port 9999. This behavior is useful for those
|
21 |
|
|
people who do not have root access and can not add services to
|
22 |
|
|
the config files (such as university students operating in a shared
|
23 |
|
|
environment.)
|
24 |
|
|
|
25 |
|
|
As the JTAG proxy server runs only if there is data available for
|
26 |
|
|
reading, there is very little resource usage consumed by this
|
27 |
|
|
capability. However, in certain instances where gdb is not being
|
28 |
|
|
utilized, it is possible to disable the JTAG proxy server
|
29 |
|
|
entirely. This will recover the few cycles necessary for the
|
30 |
|
|
poll() system call. (Tests indicate this has a negligible to
|
31 |
|
|
non existant impact on speed, however your mileage may vary.)
|
32 |
|
|
This behavior can be achieved by starting the simulator with
|
33 |
|
|
the command "sim -nosrv."
|
34 |
|
|
|
35 |
|
|
At startup, the simulator will execute random commands, just as
|
36 |
|
|
a real chip would do performing in this environment if the memory
|
37 |
|
|
was not initialized. If it is desired to simulate a ROM or FLASH
|
38 |
|
|
environment, these can be approximated by using the -loadmem option
|
39 |
|
|
to the simulator. For example, to simulate a 32k flash at location
|
40 |
|
|
0x8000, the command "sim -loadmem@0x8000 " could be
|
41 |
|
|
used, where represents the name of the initialization
|
42 |
|
|
file. If the optional '@0x8000' flag is left off of the loadmem
|
43 |
|
|
statement, then the load will occur at location 0. Several loadmem
|
44 |
|
|
flags can appear on the command line to simulate different
|
45 |
|
|
memory blocks.
|
46 |
|
|
|
47 |
|
|
It is also possible to initialize all RAM to a predefined value,
|
48 |
|
|
which is usually 0x00000000 or 0xFFFFFFFF. This would be equivalent
|
49 |
|
|
to what is normally observed in a real world environment. However,
|
50 |
|
|
specific sequences are possible in case this is necessary. Alternatively,
|
51 |
|
|
random values can be assigned to memory, to check the behavior of a
|
52 |
|
|
process under different conditions. All of these options can be
|
53 |
|
|
handled by the "-initmem" option of the simulator. The following
|
54 |
|
|
command would startup the simulator with all memory initialized to
|
55 |
|
|
"1":
|
56 |
|
|
|
57 |
|
|
sim -initmem 0xFFFFFFFF
|
58 |
|
|
|
59 |
|
|
while this command would generate random values:
|
60 |
|
|
|
61 |
|
|
sim -initmem random
|
62 |
|
|
|
63 |
|
|
Once the simulator is started, it will print out something like
|
64 |
|
|
the following:
|
65 |
|
|
|
66 |
|
|
> bash-2.03$ sim
|
67 |
|
|
> JTAG Proxy server started on port 42240
|
68 |
|
|
> Machine initialization...
|
69 |
|
|
> Data cache tag: physical
|
70 |
|
|
> Insn cache tag: physical
|
71 |
|
|
> BPB simulation on.
|
72 |
|
|
> BTIC simulation on.
|
73 |
|
|
> Clock cycle: 4 ns
|
74 |
|
|
> RAM: 0x0 to 0x7aa80 (490 KB)
|
75 |
|
|
>
|
76 |
|
|
> simdebug off, interactive prompt off
|
77 |
|
|
> Building automata... done, num uncovered: 0/216.
|
78 |
|
|
> Parsing operands data... done.
|
79 |
|
|
> Resetting 4 UART(s).
|
80 |
|
|
> UART0 has problems with RX file stream.
|
81 |
|
|
> Resetting Tick Timer.
|
82 |
|
|
> Resetting Power Management.
|
83 |
|
|
> Resetting PIC.
|
84 |
|
|
> Exception 0x100 (Reset): Iqueue[0].insn_addr: 0x0 Eff ADDR: 0x0
|
85 |
|
|
> pc: 0x0 pcnext: 0x4
|
86 |
|
|
>
|
87 |
|
|
|
88 |
|
|
Note that because we did not specify a server port, a random
|
89 |
|
|
port (42240) was selected for us (The "jtag" service does not
|
90 |
|
|
exist on this machine). We will need this value to create the
|
91 |
|
|
connection URL for the target command. It is now possible to
|
92 |
|
|
debug a program with gdb as follows:
|
93 |
|
|
|
94 |
|
|
> bash-2.03$ gdb
|
95 |
|
|
> GNU gdb 5.0
|
96 |
|
|
> Copyright 2000 Free Software Foundation, Inc.
|
97 |
|
|
> GDB is free software, covered by the GNU General Public License, and you are
|
98 |
|
|
> welcome to change it and/or distribute copies of it under certain conditions.
|
99 |
|
|
> Type "show copying" to see the conditions.
|
100 |
|
|
> There is absolutely no warranty for GDB. Type "show warranty" for details.
|
101 |
|
|
> This GDB was configured as "--host=sparc-sun-solaris2.7 --target=or32-rtems".
|
102 |
|
|
> (or1k) file "dhry.or32"
|
103 |
|
|
> Reading symbols from dhry.or32...done.
|
104 |
|
|
> (or1k) target jtag jtag://localhost:42240
|
105 |
|
|
> Remote or1k debugging using jtag://localhost:42240
|
106 |
|
|
> 0x0 in ?? ()
|
107 |
|
|
> (or1k) load dhry.or32
|
108 |
|
|
> Loading section .text, size 0x14fc lma 0x100
|
109 |
|
|
> Loading section .data, size 0x2804 lma 0x15fc
|
110 |
|
|
> Start address 0x100 , load size 15616
|
111 |
|
|
> Transfer rate: 124928 bits/sec, 488 bytes/write.
|
112 |
|
|
> (or1k) b main
|
113 |
|
|
> Breakpoint 1 at 0x51c: file dhry.c, line 176.
|
114 |
|
|
> (or1k) run
|
115 |
|
|
> Starting program: /usr3/home/chris/opencores/or1k/gdb-build/gdb/dhry.or32
|
116 |
|
|
>
|
117 |
|
|
> Breakpoint 1, main () at dhry.c:176
|
118 |
|
|
> 176 Next_Ptr_Glob = (Rec_Pointer) &x;
|
119 |
|
|
> (or1k)
|
120 |
|
|
|
121 |
|
|
The simulator window will have printed out the following, showing that
|
122 |
|
|
a breakpoint exception was asserted.
|
123 |
|
|
|
124 |
|
|
> Exception 0xd00 (Break): Iqueue[0].insn_addr: 0x51c Eff ADDR: 0x0
|
125 |
|
|
> pc: 0x51c pcnext: 0x520
|
126 |
|
|
|
127 |
|
|
Note that when the "run" command is given, the simulator will start
|
128 |
|
|
by jumping to the reset vector at location 0x100. You must start off
|
129 |
|
|
by placing a small bootloader at this location. A simple environment
|
130 |
|
|
capable of running C programs can be established by placing the
|
131 |
|
|
following code in a file called "start.s" and linking it to your
|
132 |
|
|
executable. As an example, the following will work. The file start.s
|
133 |
|
|
was derived from the output of a file start.c compiled by gcc:
|
134 |
|
|
|
135 |
|
|
or32-rtems-gcc -g -c -o start.o start.s
|
136 |
|
|
or32-rtems-gcc -g -c -DOR1K -o dhry.o dhry.c
|
137 |
154 |
chris |
or32-rtems-ld -Ttext 0x0 -o dhry.or32 start.o dhry.o
|
138 |
147 |
chris |
|
139 |
|
|
---------------------- CUT HERE -------------------------
|
140 |
|
|
|
141 |
|
|
# file start.s
|
142 |
|
|
.file "start.s"
|
143 |
|
|
|
144 |
|
|
# This is the general purpose start routine. It
|
145 |
|
|
# sets up the stack register, and jumps to the
|
146 |
|
|
# _main program location. It should be linked at
|
147 |
|
|
# the start of all programs.
|
148 |
|
|
|
149 |
|
|
.text
|
150 |
154 |
chris |
.align 4
|
151 |
|
|
.org 0x100 # The reset routine goes at 0x100
|
152 |
147 |
chris |
.proc _rst
|
153 |
|
|
.def _rst
|
154 |
|
|
.val _rst
|
155 |
|
|
.scl 2
|
156 |
|
|
.type 041
|
157 |
|
|
.endef
|
158 |
|
|
.global _rst
|
159 |
|
|
_rst:
|
160 |
|
|
.def .bf
|
161 |
|
|
.val .
|
162 |
|
|
.scl 101
|
163 |
|
|
.endef
|
164 |
154 |
chris |
l.addi r1,r0,0x7f00 # Set STACK to value 0x7f00
|
165 |
|
|
l.addi r2,r1,0x0 # FRAME and STACK are the same
|
166 |
|
|
l.mfspr r3,r0,17 # Get SR value
|
167 |
|
|
l.ori r3,r3,2 # Set exception enable bit
|
168 |
|
|
l.jal _main # Jump to main routine
|
169 |
|
|
l.mtspr r0,r3,17 # Enable exceptions (DELAY SLOT)
|
170 |
147 |
chris |
|
171 |
|
|
.endproc _rst
|
172 |
|
|
.def _rst
|
173 |
|
|
.val .
|
174 |
|
|
.scl -1
|
175 |
|
|
.endef
|
176 |
|
|
|
177 |
154 |
chris |
.org 0xFFC
|
178 |
|
|
l.nop # Guarantee the exception vector space
|
179 |
|
|
# does not have general purpose code
|
180 |
|
|
|
181 |
|
|
# C code starts at 0x1000
|
182 |
|
|
|
183 |
1242 |
hpanther |
---------------------- CUT HERE -------------------------
|
184 |
|
|
|
185 |
|
|
|
186 |
|
|
Setting registers
|
187 |
|
|
|
188 |
|
|
"info spr" commands give info about special purpose registers, "spr" commands set them.
|
189 |
|
|
"info spr" - display the SPR groups
|
190 |
|
|
"info spr " - display SPRs in
|
191 |
|
|
"info spr " - display value in
|
192 |
|
|
"spr " - set to
|
193 |
|
|
|
194 |
|
|
Breaking for exceptions
|
195 |
|
|
|
196 |
|
|
You have to set a bit in the Debug Stop Register "dsr" for each exception you want
|
197 |
|
|
to stop on. Use "spr dsr ".
|