--- /dev/null
+How to implement a stub or server using RDA (Red Hat Debug Agent and library).
+==================================================
+Andrew Cagney <cagney@cygnus.com>
+Fernando Nasser <fnasser@cygnus.com>
+Frank Eigler <fche@cygnus.com>
+
+Introduction
+------------
+
+This is the implementation of a server for the gdb remote protocol.
+It is available as a host library that provides most of the common code
+required. By adding a relatively small amount of target dependent code,
+one can build a server that allows gdb to connect to that target using
+the gdb "target remote" command.
+
+Gdb connects to this server through a TCP/IP connection. The server
+waits for a connection from GDB by listening to a non-restricted TCP port.
+Anyone with GDB (or even telnet) network connectivity to the machine
+running the server can initiate a connection to it.
+
+Note: The user of this software is advised to ensure
+that access to the TCP port being used is restricted to
+secure siblings. For instance, the user may need to take
+action that ensures that `The Internet' is not able to access
+the TCP port being used.
+
+Architecture
+------------
+
+The following diagram shows the components of RDA.
+
+ (GDB) <---"remote"---> CLIENT <--> SERVER <--> TARGET
+ ------- ------------------------------
+ The client. The server.
+
+Where:
+
+ CLIENT Provides the raw interface between
+ GDB and the internal SERVER
+ mechanism.
+
+ The client passes on any data relevant
+ to the server. The SERVER presents
+ CLIENT with raw output to be returned
+ to GDB.
+
+ SERVER Implements the state-machine that
+ is capable of decoding / processing
+ various GDB remote protocol requests.
+
+ TARGET The embedded system proper. SERVER
+ passes decoded requests onto the TARGET
+ while TARGET notifies the SERVER of any
+ target state changes.
+
+
+Looking at SERVER in more detail, that component consists of three sub
+components INPUT, OUTPUT and STATE. Visually:
+
+ .------------ fromtarget_*
+ \|/
+ fromclient_* -> INPUT -> STATE (M/C) -> target->*
+ /|\ |
+ |
+ \|/ |
+ client->write <- OUTPUT <----'
+
+Where:
+
+ INPUT Filters the raw input stream from the client
+ breaking it up into complete packets and
+ passing them onto STATE.
+
+ This component co-operates with OUTPUT for
+ the ACK/NAK of input packets.
+
+ OUTPUT Wraps up and then passes onto the client
+ raw output packets ready for transmission
+ on the output stream.
+
+ This component co-operates with INPUT for
+ the ACK/NAK of output packets.
+
+ STATE The state machine proper.
+
+
+The Appendix provides various scenarios showing in some detail how typical
+operations are handled by these components. It may be convenient to read the
+next section first before turning to the Appendix.
+
+
+Adding the target dependent code
+--------------------------------
+
+In the following discussion, assume your debugger (gdb) is using
+the remote protocol to communicate with the code you are building here.
+The "target" is a simulator, hardware device, board, program or whatever you
+are interfacing to with your stub/server.
+
+The library provides gdbsocket_*() and gdbserv_fromtarget_*() routines that
+must be called and requires you to set a series of callback routines.
+You make these callbacks known/available to the library by filling the entries
+of a "gdbserv_target" object. You must also provide an extra function that
+will be invoked when a new connection is detected on the input port (a socket).
+
+
+Handling the connection:
+
+The server is capable of handling several connections (named, sessions)
+simultaneously. This is possible because each session data is kept on
+an instance of a GDBSERV object. A routine called gdbserv_fromclient_attach()
+is called when a connection request is received by the socket.
+If the connection is accepted, a new instance of a GDBSERV object is returned,
+otherwise NULL is returned indicating that it has been rejected (a EOF will be
+sensed on the other end).
+
+The server will, in turn, pass the request onto the target. The target can
+either reject the connection (returning NULL) or accept the connection
+(returning a target object). That is where you come in.
+
+You must provide a routine like (please see the precise API in the header file
+include/gdbserv-client.h):
+
+typedef struct gdbserv_target *(gdbserv_target_attach) (struct gdbserv *gdbserv, void *attatch_data);
+
+This will be called by the server to notify that the client has initiated a
+connection. You must return a GDBSERV_TARGET struct for the session or null
+if your target has rejected the connection.
+
+The recommended way to create your gdbserv_target object is:
+
+struct gdbserv_target *gdbtarget = malloc (sizeof (struct gdbserv_target));
+memset (gdbtarget, 0, sizeof (*gdbtarget));
+gdbtarget->process_get_gen = process_get_gen;
+(...)
+
+If you initialize it like this, you will not have to change your code even if
+new entries are added to this struct.
+
+
+Handling target events:
+
+The fromtarget_* routines may be called by your target. Before you
+despair, let me tell you that they are only three: reset, break and
+exit. They indicate that some interesting condition happened in your
+target that requires debugger attention. Reset and exit are quite
+obvious and break is for everything else. These routines must *not*
+be called from within a gdbserv_target callback function, so it may be
+necessary for your target to set some flags to signal state change
+calls later.
+
+If your target is a simulator, call those when the corresponding
+condition arises in your simulated target. If it is a board, it will
+probably be called from your ISRs. A special case occurs if your
+target is a device that has to be polled in order to detect state
+changes. If this is the case, you will call these routines from the
+polling code.
+
+
+The main loop:
+
+At some point you must get things going by:
+
+1) looking for connection requests from gdb and
+2) causing remote protocol commands to be read from the input port (socket).
+
+You must (repeatedly) call a function called gdbloop_poll(). This
+will be in your main loop. If it is a server it will be in your
+main() function. If it is a simulator that also accepts input from
+other sources, it will have to be added to the existing main loop. If
+it is a board, it will probably be called from the timer ISR.
+
+Before doing that you must initialize your socket interface. Look in
+the main() routine of the sample program to see what to call. When
+calling gdbsocket_startup() you must give the address of the callback
+that handles connection requests for your target.
+
+If your target has to be polled for state changes, you will have to alternate
+calls to poll() and to check your target status. As I mentioned before,
+your status checking routine must call the appropriate fromtarget_* function.
+
+
+The callbacks:
+
+All that is left now is to implement your callbacks, which are, directly or
+indirectly, called as a result of a remote protocol packet being received and
+processed by some fromclient_* routine. I will assume that the remote
+protocol packets are known. If not, please refer to the "Remote Protocol"
+section of the gdb manual. There you will find how your target should be
+affected by each packet and what the response should be. It is always
+useful to look at what some other remote targets do as well.
+
+The list of all callbacks with the situation in which they are invoked can be
+found in the header file lib/gdbserv-target.h.
+
+Have fun!
+
+
+
+Appendix
+--------
+
+SCENARIOS
+
+
+ATTACH: Creating a connection into the server/target.
+
+Client receives a connect request from the remote GDB. A socket
+interface would see this as an attach. For Cygmon this is the
+``transfer'' command.
+
+The client creates an output object (struct gdbserv_client) and passes
+that and the target side attach function onto GDBSERV. SERVER will
+then initialize itself and call ``to_target_attach'' for final
+approval of the request.
+
+ struct gdbserv_client *client;
+ ...
+ client->write = client_write_to_output_port;
+ client->data = ... local state ...
+ server = gdbserv_fromclient_attach (client, to_target_attach,
+ target_data);
+
+The target_attach() function is expected to either create and return a
+gdbserv_target object or return NULL. The latter indicates that the
+connection request is rejected.
+
+Finally gdbserv_fromclient_attach() returns a SERVER state object that
+should be passed to all client->server calls.
+
+
+DATA-IN: Data being sent to the client from the remote GDB
+
+The client passes the data vis:
+
+ len = read (fd, buf, sizeof (buf));
+ gdbserv_fromclient_data (server, buf, len);
+
+
+BREAK-IN: Request to stop sent to the client from the remote GDB
+
+The client passes the request to SERVER:
+
+ server.c:
+
+ volatile
+ break_handler ()
+ {
+ gdbserv_fromclient_break (server);
+ }
+
+If the target is currently running, the server will in turn pass the
+request onto the TARGET:
+
+ ->target->break_program (server);
+
+and the target will record the break request and then return control
+back to the SERVER. The server returning control to the client.
+
+Later, once the target has halted, the SERVER is notified of the state
+change vis:
+
+ target.c:
+
+ gdbserv_fromtarget_break (server);
+
+
+NB: Often ``break'' is sent across the stream interface as a special
+character sequence.
+
+FIXME: gdbserv-input.c should be able to parse such character
+sequences.
+
+
+DATA-OUT: Data for the remote GDB from SERVER
+
+The ``write'' function specified in the ``struct gdbserv_client''
+object is called.
+
+
+DETACH: Remote GDB disconnects from the SERVER
+
+The CLIENT notifies SERVER via the gdbserv_fromclient_detach() call.
+
+
+HARD-RESET: A hard reset is performed on a serial board.
+
+Assuming a standalone system, the client/target side sequences would
+be performed:
+
+ /* create the server */
+ server = gdbserv_fromclient_attach (...);
+ /* notify the server that the target was just reset */
+ gdbserv_fromtarget_reset (server);
+
+
+WRITE-MEMORY: GDB sends the server a write-memory packet.
+
+Eventually SERVER passes the request onto the TARGET with the call:
+
+ ->target->process_set_mem (server, addr, len);
+
+where ADDR and LEN contain the uninterpreted address/length of the
+data to follow. target_process_set_mem() might be implemented as:
+
+ long long addr;
+ long int;
+ gdbserv_reg_to_ulonglong (server, reg_addr, &addr);
+ gdbserv_reg_to_ulong (server, reg_len, &len);
+ /* just blat local memory */
+ len = gdbserv_input_bytes (server, addr, len);
+
+
+READ-MEMORY: GDB requests memory from the target.
+
+Eventually target_process_get_mem() function is called. An
+implementation may look like:
+
+ gdbserv_reg_to_ulonglong (gdbserv, reg_addr, &addr);
+ gdbserv_reg_to_ulong (gdbserv, reg_len, &len);
+ /* assume we're reading raw memory from the local mc */
+ gdbserv_output_bytes (gdbserv, addr, len);
+
+
+TARGET-RESUME: GDB requests that the target resume execution.
+
+Eventually ->target->continue_program() is called. That function
+should record the request and then wait for SERVER to exit before
+actually continuing the target.
+
+--
+