The C4x port of the GNU debugger (c4x-gdb) is designed to attach to a C3x or C4x target system via a serial port or a TCP/IP socket connection. Currently only a few target systems are supported although it is a relatively straightforward to add additional target systems.
GDB-C4x now includes Herman's (haj.ten.brugge@net.hcc.nl) C30/C40 simulator. You can now debug your programs without having to a connect to a real C[34]x target system. In addition, the simulator allows you to profile your code and to see where pipeline conflicts are occuring. You can connect i/o ports to files (or TCP/IP sockets), trigger interrupts, examine the cache etc. It will detect different threads of control running and generate a profile summary for each thread.
c4x-gdb talks to the target system either directly via a serial port or indirectly using TCP/IP and a debug server program. I've used the latter approach and have written a program c4x-dbg which acts like a simple monitor program (see utils-c4x ). c4x-gdb sends commands to this program to interrogate register/memory contents of the target, set breakpoints, single-step, and the like.
To connect to the target from gdb, fire up gdb (c4x-gdb) and at the prompt (gdb) type target c4x hostname:port-number, where hostname is the name of the host that the target system is connected to and port-number is the port number of the c4x-dbg service.
To communicate with the debug server (c4x-dbg), inetd.conf needs to be configured to fire up c4x-dbg whenever gdb tries accessing the c4x-dbg service.
Here's the entry from my /etc/inetd.conf:
c4x-dbg stream tcp nowait c4x /usr/sbin/tcpd /usr/local/bin/c4x-dbg
where c4x-dbg is the service defined in /etc/services:
c4x-dbg 7772/tcp # c4x debug server (MPH)
Note that my chosen port number 7772 is arbitrary---it must be greater
than 1024 and must not conflict with another service.
Simulator Introduction
To connect to the simulator fire up gdb and type Profiling can be turned on when connecting to the siumlator
target sim -p. You can display the result of the
executing code by sim p cim50 profile.out. This will
create a big file with all profiling counters in c-source,
instructions. At the end is a list for each text symbol with an
_ in it. The percentage of time spent, the total time
spent and the total number of calls is printed. You can clear the
profile counters in the simulator with sim z. The
resulting sourceble command for c4x-gdb could be:
It is also possible to use the history command to show where
the pipeline conflicts are. You can enable history by target
sim -h. It is possible to enable profiling and history at
the same time. When you run a part of the code you can show the
history with sim h 100 file. The number 100 is the
number of cycles you want to see.
The layout of this file is:
The symbols E, R, D and F are:
E execution pipeline stage
R read pipeline stage
D decode pipeline stage
F fetch pipeline stage
The Lines are only printed if a pipeline stage is used.
Example:
Memory actions are:
The actions are followed by the source of the actions:
For the local and global bus action a counter is printed for
the number of waitstates.
The pipeline conflicts can be:
Not all pipeline conflicts are generated for all pipeline
stages. FL for example can only be generated by the Fetch pipeline
stage. The conflicts are described in the manual of the C40 and
the C30.
With the command sim n a overview of all internal
counters for memory access, dma access, .... can be printed. This
list also includes the counters for the pipeline conflicts.
Here's an example .gdbinit file which tells the simulator what
memory is present, where to find the source files, and defines
a new command steph that will single step the processor, displaying
the pipeline operation:
Copyright ©1998
Michael Hayes (m.hayes@elec.canterbury.ac.nz)
Last modified: Wed Oct 21 23:05:54 NZDT 1998
Simulator Profiling
target sim -p
load c40.out
break start_proc
cont
sim z
break end_proc
cont
sim p cim50 profile.out
Simulator Cycle History
<clocknr> <memory actions>
E <pipeline conflict> <disassembled instruction>
R <pipeline conflict> <disassembled instruction>
D <pipeline conflict> <disassembled instruction>
F <pipeline conflict> <disassembled instruction>
49437 L=FETCH_RD,0
E 0x301d45 <delay+20>: bud 0x301a6f <start_test>
R 0x301d46 <delay+21>: sti ar2,*+ar0(2)
D 0x301d47 <delay+22>: lda @0x6f18 <data+26392>,ar3
F 0x301d48 <delay+23>: ldpk 48
49438 I00=EXECUTE1_WR L=DMA0_RD,0
E 0x301d46 <delay+21>: sti ar2,*+ar0(2)
R RD 0x301d47 <delay+22>: lda @0x306f18 <label+3>,ar3
D HE 0x301d48 <delay+23>: ldpk 48
F PW
49439 P=DMA0_WR L=READ1_RD,0
R 0x301d47 <delay+22>: lda @0x306f18 <label+3>,ar3
D 0x301d48 <delay+23>: ldpk 48
F PW
P peripheral (internal bus) C cache I00 Internal memory bank 0 access 0 I01 Internal memory bank 0 access 1 I10 Internal memory bank 1 access 0 I11 Internal memory bank 1 access 1 R0 Internal rom access 0 R1 Internal rom access 1 L local bus access G global bus access
DMA0_RD Dma 0 read action DMA1_RD Dma 1 read action DMA2_RD Dma 2 read action DMA3_RD Dma 3 read action DMA4_RD Dma 4 read action DMA5_RD Dma 5 read action DMA0_WR Dma 0 write action DMA1_WR Dma 1 write action DMA2_WR Dma 2 write action DMA3_WR Dma 3 write action DMA4_WR Dma 4 write action DMA5_WR Dma 5 write action FETCH_RD rogram fetch action READ1_RD ata read 1 action from Read stage READ2_RD ata read 2 action from Read stage EXECUTE1_WR ata write 1 action from Execute stage EXECUTE2_WR ata write 2 action from Execute stage
FL Pipeline flush (due to branch instruction) BR Branch conflict RE Register conflict RD Read stage incomplete EX Execute only PF Program fetch PW Program wait HE Hold everything HI Hold because of IDLE instruction
target sim -3 -p -h
sim m a 0 0x100000
sim m a 0x804000 0x1000
dir /usr/local/mphos/kern
dir /usr/local/mphos/drivers
dir /usr/local/mphos/libc
define steph
stepc
sim h
end