The Wayback Machine - https://web.archive.org/web/20040628215849/http://www.elec.canterbury.ac.nz:80/c4x/c4x-gdb.html

C4x GDB

Introduction

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.

GDB Operation

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 target sim. Use target sim ? to get a list of options---for example, to specify the processor type (-3 for the C30, -4 for C40), to enable profiling, etc. To send commands to the simulator use the prefix sim. sim ? gives a list of the simulator commands---for example, to examine the history counters, to generate an interrupt, to add a block of memory etc. You need to tell the simulator if you have external memory and how much of the stuff you have---sim m a start-addr size. You can then load your program, and away you go....using gdb as if you were interacting with a running target system.

Simulator Profiling

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
    

Simulator Cycle History

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:
FLPipeline 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