Services - tools - models - for embedded software development
Embecosm divider strip
Prev  Next

4.4.1.  GdbServerSC class

The public interface to the GdbServerSC class is its constructor and destructor. The constructor arguments include the start and end address of Flash memory, the port on which RSP TCP/IP connections will be accepted and a pointer to the JTAG FIFO for TAP actions.

The constructor instantiates a new instance of RspConnection to handle the RSP TCP/IP interface (see Section 4.2) and a new instance of DebugUnitSC to model the interface to the OpenRISC 1000 Debug Unit and drive the JTAG interface (see Section 4.3). It creates an instance of RspPacket to hold the data associated with the packet currently in use.

The GDB server needs to keep track of breakpoints and watchpoints (collectively known as matchpoints) which have been inserted. These use OpenRISC 1000 l.trap instructions. Class MpHash holds details of each matchpoint: its type, address and the instruction that was replaced by l.trap. The GdbServerSC constructor creates an instance of this class.

Finally the constructor declares the private function rspServer as a new SystemC THREAD.

The SystemC Thread, rspServer

On start up, the OpenRISC 1000 model loads an image from Flash memory which initializes the exception vectors in RAM, sets up any caches and then jumps to the reset vector (location 0x100). GDB debugging should not start until this initialization has occurred.

This is achieved by detecting when the processor first tries to access a location outside Flash memory (hence the need for this addresses to be passed to the constructor). At start up, the thread resets the JTAG interface of the Debug Unit, then waits until the next program counter has a value outside the flash memory address range.

This is followed by the main loop. The first part of the loop checks if a connection to a GDB client has been established, and if not loops trying to listen. When a new connection is established it immediately stalls the processor, pending instructions from the client.

The second part of the loop waits until the processor has stalled (it will already be stalled on first connection). Once it has stalled it notifies the GDB client, then processes the next RSP packet from the client using the function rspClientRequest. The majority of packets will leave the CPU unstalled, so subsequent moves round the loop will immediately come back to the same point and call rspClientRequest again.

The exceptions are continue, step and restart packets which unstall the processor. There will be no further RSP packets processed until the processor stalls again. This will either be due to hitting a breakpoint or the connection being dropped and reconnected.

[Note]Note

This loop relies on detecting a stalled processor (using the variable targetStopped) being a fast operation. It would not be efficient if the target had to be interrogated via JTAG between processing each GDB packet.

The processing of individual packets by rspClientRequest follows the same approach described in Embecosm Application Note 4 Howto: GDB Remote Serial Protocol: Writing a RSP Server [8]. The only difference is the code is in C++ rather than C. The details of individual packet actions are not described further in this application note. All the actions use reading and writing of SPRs and memory in the same way. However for this application they use the functions provided by the Debug Unit class, DebugUnitSC.

Embecosm divider strip