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.
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:
target sim -p load c40.out break start_proc cont sim z break end_proc cont sim p cim50 profile.out
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:
<clocknr> <memory actions> E <pipeline conflict> <disassembled instruction> R <pipeline conflict> <disassembled instruction> D <pipeline conflict> <disassembled instruction> F <pipeline conflict> <disassembled instruction>
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:
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
Memory actions are:
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 |
The actions are followed by the source of the actions:
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 |
For the local and global bus action a counter is printed for the number of waitstates.
The pipeline conflicts can be:
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 |
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:
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
Copyright ©1998 Michael Hayes (m.hayes@elec.canterbury.ac.nz)
Last modified: Wed Oct 21 23:05:54 NZDT 1998