This is Info file bspint.info, produced by Makeinfo version 1.68 from
the input file
/tantor/build/intel-xscale/xscale-010413/i686-pc-linux-gnulibc2.1/src/bsp/doc/bspint.texinfo.

START-INFO-DIR-ENTRY
* Cygnus BSP Internals: (bspint). The Cygnus Board Support Package Internals
END-INFO-DIR-ENTRY

   This file documents the internals of the Cygnus board support
package.

   Copyright 1999 Cygnus Solutions.  Written by Mark Salter.

   Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

   Permission is granted to copy or distribute modified versions of this
manual under the terms of the GPL (for which purpose this text may be
regarded as a program in the language TeX).


File: bspint.info,  Node: Data Types,  Next: Packet Buffers,  Prev: Network Stack,  Up: Network Stack

Data Types
==========

   `include/net.h' defines many data types for the network stack. The
basic scalar types are:

`octet'
     An unsigned 8-bit integer.

`word'
     An unsigned 16-bit integer.

`dword'
     An unsigned 32-bit integer.

`enet_addr_t'
-------------

     typedef octet enet_addr_t[6];
   *Description*
Ethernet address type.

`ip_addr_t'
-----------

     typedef octet enet_addr_t[4];
   *Description*
Internet Protocol address type.

`eth_header_t'
--------------

     typedef struct {
         enet_addr_t   destination;
         enet_addr_t   source;
         word          type;
     } eth_header_t;
   *Description*
Ethernet protocol header. The `type' field values that the BSP is
interested in are:
   * ETH_TYPE_IP

   * ETH_TYPE_ARP

   * ETH_TYPE_RARP

`arp_header_t'
--------------

     typedef struct {
         word	hw_type;
         word	protocol;
         octet	hw_len;
         octet	proto_len;
         word	opcode;
         enet_addr_t	sender_enet;
         ip_addr_t	sender_ip;
         enet_addr_t	target_enet;
         ip_addr_t	target_ip;
     } arp_header_t;
   *Description*
The ARP/RARP header. This header immediately follows the ethernet header
when the ethernet `type' is `ETH_TYPE_ARP' or `ETH_TYPE_RARP'.  In the
case of the BSP, the only `hw_type' value is `ARP_HW_ETHER'.  The
opcode field is one of:
   * ARP_REQUEST

   * ARP_REPLY

   * RARP_REQUEST

   * RARP_REPLY

`ip_header_t'
-------------

     typedef struct {
     #ifdef __LITTLE_ENDIAN__
         octet       hdr_len:4,
                     version:4;
     #else
         octet       version:4,
                     hdr_len:4;
     #endif
         octet       tos;
         word        length;
         word        ident;
         word        fragment;
         octet       ttl;
         octet       protocol;
         word        checksum;
         ip_addr_t   source;
         ip_addr_t   destination;
     } ip_header_t;
   *Description*
The IP protocol header. Supported `protocol' fields are:
   * IP_PROTO_ICMP

   * IP_PROTO_TCP

   * IP_PROTO_UDP

`ip_route_t'
------------

     typedef struct {
         ip_addr_t    ip_addr;
         enet_addr_t  enet_addr;
     } ip_route_t;
   *Description*
Structure to bind an IP address to an ethernet address.

`udp_header_t'
--------------

     typedef struct {
         word	src_port;
         word	dest_port;
         word	length;
         word	checksum;
     } udp_header_t;
   *Description*
User Datagram Protocol header. This header follows the IP header when
the IP header `protocol' field is `IP_PROTO_UDP'.

`tcp_header_t'
--------------

     typedef struct {
         word	src_port;
         word	dest_port;
         dword	seqnum;
         dword	acknum;
     #ifdef __LITTLE_ENDIAN__
         octet       reserved:4,
                     hdr_len:4;
     #else
         octet       hdr_len:4,
                     reserved:4;
     #endif
         octet	flags;
         word	window;
         word	checksum;
         word	urgent;
     } tcp_header_t;
   *Description*
Transaction Control Protocol header. This header follows the IP header
when the IP header `protocol' field is `IP_PROTO_TCP'.

`icmp_header_t'
---------------

     typedef struct {
         octet	type;
         octet	code;
         word	checksum;
         word	ident;
         word	seqnum;
     } icmp_header_t;
   *Description*
ICMP protocol header.This header follows the IP header when the IP
header `protocol' field is `IP_PROTO_ICMP'. The BSP uses ICMP to
respond to `ping' packets.

`bootp_header_t'
----------------

     typedef struct {
         octet	opcode;
         octet	hw_type;	/* same as ARP */
         octet	hw_len;
         octet	hop_cnt;
         dword	trans_id;
         word	seconds;
         word	unused;
         ip_addr_t	client_ip;
         ip_addr_t	your_ip;
         ip_addr_t	server_ip;
         ip_addr_t	gateway_ip;
         octet	client_hw[16];
         char        server_name[64];
         char        boot_file[128];
         char        vendor_data[64];
     } bootp_header_t;
   *Description*
BOOTP protocol header. This header follows a UDP protocol header.

`pktbuf_t'
----------

     typedef struct _pktbuf {
         struct _pktbuf *next;
         eth_header_t   *eth_hdr;
         union {
     	ip_header_t  *__iphdr;
     	arp_header_t *__arphdr;
         } u1;
         union {
     	udp_header_t  *__udphdr;
     	tcp_header_t  *__tcphdr;
     	icmp_header_t *__icmphdr;
         } u2;
         word	pkt_bytes;
         word        bufsize;
         word	*buf;
     } pktbuf_t;
   *Description*
The BSP uses a very simplistic packet buffer which minimizes copying of
data.  It is not space efficient, but that is not critical because the
entire stack can run fine with just a couple of these buffers. The
`next' pointer allows the creation of singly linked lists. For
efficiency, the protocol stack maintains pointers to several protocol
specific headers within the overall packet buffer. `pkt_bytes' is a
count of bytes used by the packet.  `bufsize' is the total size of the
packet buffer and `buf' points to the start of actual buffer. Several
convenience macros are provided to access protocol headers:

     #define ip_hdr   u1.__iphdr
     #define arp_hdr  u1.__arphdr
     #define udp_hdr  u2.__udphdr
     #define tcp_hdr  u2.__tcphdr
     #define icmp_hdr u2.__icmphdr

tcp_socket_t
------------

     typedef struct _tcp_socket {
         struct _tcp_socket *next;
     
         /* TCP connection state */
         int		       state;
     
         /* address of other end of connection */
         ip_route_t         his_addr;
     
         /* connection ports */
         word               our_port;
         word               his_port;
     
         word               data_bytes;
         dword              ack;
         dword              seq;
         timer_t            timer;
         /* dedicated transmit packet */
         pktbuf_t           pkt;
         /* list of unread incoming data packets */
         pktbuf_t           *rxlist;
         /* pointer to next byte to read */
         char               *rxptr;
         /* bytes left in current read packet */
         int                rxcnt;
         /* this puts buf on odd-word boundary */
         word               dummy;
         /* data buffer for transmit packet */
         char               pktbuf[ETH_MAX_PKTLEN];
     } tcp_socket_t;
   *Description*
Internal representation of a TCP connection.

udp_handler_t
-------------

     typedef void (*udp_handler_t)(udp_socket_t *SKT,
                                   char         *BUF,
                                   int          LEN,
     			      ip_route_t   *SRC_ROUTE,
                                   word         SRC_PORT);
   *Description*
Prototype for a UDP socket handler. SKT is a pointer to the UDP socket
listener structure. BUF points to the UDP data field and LEN is the
length of that data in byte. SRC_ROUTE is the route to the sender and
SRC_PORT is the sender's port number.

udp_socket_t
------------

     typedef struct _udp_socket {
         struct _udp_socket	*next;
         word		our_port;
         word		pad;
         udp_handler_t       handler;
     } udp_socket_t;
   *Description*
Descriptor for a UDP socket listener.


File: bspint.info,  Node: Packet Buffers,  Next: Ethernet,  Prev: Data Types,  Up: Network Stack

Packet Buffers
==============

   The network code provides a simple packet buffer allocator which is
used by the low-level ethernet poller. All packet buffers are currently
sized to hold a maximum sized ethernet packet.

`__pktbuf_alloc'
----------------

   *Synopsis*
     pktbuf_t *
     __pktbuf_alloc(int NBYTES)
   *Description*
Simple pktbuf allocator. The current implementation ignores NBYTES.  If
successful, a pointer to an iniitalized  `pktbuf_t' structure is
returned. If no more buffers are available, NULL is returned. The
returned `pktbuf_t' is provided with a buffer of `ETH_MAX_PKTLEN' bytes.
The `eth_hdr', `ip_hdr', and `tcp_hdr' fields are valid and `pkt_bytes'
is zero.

`__pktbuf_free'
---------------

   *Synopsis*
     void
     __pktbuf_free(pktbuf_t *PKT)
   *Description*
Return PKT to the pool of free `pktbuf_t' buffers.


File: bspint.info,  Node: Ethernet,  Next: ARP,  Prev: Packet Buffers,  Up: Network Stack

Ethernet
========

   The ethernet interface is based primarily on polling. When the BSP
is blocking on input, the ethernet interface is continually polled.
There is interrupt

`_bsp_install_enet_driver'
--------------------------

   *Synopsis*
     void
     _bsp_install_enet_driver(struct bsp_comm_procs *PROCS);
   *Description*
Boot time initialization routine called by ethernet driver
initialization code to install the ethernet procs.

`__enet_poll'
-------------

   *Synopsis*
     void
     __enet_poll(void)
   *Description*
Low-level ethernet polling routine. This routine attempts to allocate a
packet buffer and if successful, calls the ethernet driver read routine
to get the next available packet. If no packet is available, the packet
buffer is freed and `__enet_poll' returns. If the driver does return a
packet, the ethernet header `type' field is checked to see which
protocol handler to pass the packet to.

`__enet_send'
-------------

   *Synopsis*
     void
     __enet_send(pktbuf_t    *PKT,
                 enet_addr_t DEST,
                 int         ETH_TYPE);
   *Description*
Routine called by higher level protocol handlers to send an ethernet
packet.

Driver
------

   To support a network connection, the architecture or board specific
code must provide an ethernet driver and init code. The ethernet init
code must fill in the `__local_enet_addr' variable with the ethernet
device's local ethernet address and it must pass a `bsp_comm_procs'
structure to `_bsp_net_init'. The `bsp_comm_procs' structure must
provide a `__write' vector, a `__read' vector, and a `__control' vector.

Write
.....

   The buffer passed into the `__write' vector points to an ethernet
header with destination address and type filled in. The ethernet write
routine must fill in the ethernet source address. The length passed to
the `__write' vector is the total length of the packet including
ethernet header.

Read
....

   The ethernet read routine must be non-blocking and polls to see if a
complete packet is ready to be copied into the buffer provided to the
`__read' vector. Only good ethernet packets should be passed to the
higher levels. If a suitable packet has been received, the read routine
copies the packet into the provided buffer. The copying must begin with
the ethernet header. The read routine should return the total packet
length including ethernet header. If no packet is ready, a zero value
should be returned.

Control
.......

   The ethernet `__control' vector should support the following
operations:
   * COMMCTL_INSTALL_DBG_ISR

   * COMMCTL_REMOVE_DBG_ISR

   * COMMCTL_IRQ_DISABLE

   * COMMCTL_IRQ_ENABLE

Interrupts
..........

   The ethernet driver needs to support receive interrupts so that ARP
requests can be handled and the host debugger can asynchronously
interrupt a running program. The interrupt handler should simply call
`gdb_interrupt_check'.

     int rx_irq(int irq_nr, void *regs)
     {
         if (gdb_interrupt_check())
             return 0;
         return 1;
     }


File: bspint.info,  Node: ARP,  Next: BOOTP,  Prev: Ethernet,  Up: Network Stack

ARP
===

   The BSP must handle ARP requests so that host debuggers can find the
ethernet address of the target board. When an ARP packet is found,
`__enet_poll' will call the ARP protocol handler.

`__arp_handler'
---------------

   *Synopsis*
     void
     __arp_handler(pktbuf_t *PKT)
   *Description*
Handle incoming ARP packets. Responds to ARP REQUEST packets destined
for the target board IP address.


File: bspint.info,  Node: BOOTP,  Next: IP,  Prev: ARP,  Up: Network Stack

BOOTP
=====

   The BSP uses the BOOTP protocol to get an IP address based on the
ethernet address. BOOTP packets are carried as UDP data on ports 67 and
68.

`__bootp_find_local_ip'
-----------------------

   *Synopsis*
     int
     __bootp_find_local_ip(void)
   *Description*
Try to find local IP address through BOOTP broadcasts. If successful,
the `__local_ip_addr' variable is filled in with the appropriate
address and zero is returned. If not successful, a non-zero value is
returned.


File: bspint.info,  Node: IP,  Next: UDP,  Prev: BOOTP,  Up: Network Stack

IP
==

   The IP layer is very minimal. Basically, it just performs a checksum,
verifies the destination address, and sends the packet on to the
appropriate higher layer protocol. There is no support for fragmented
packets.

`__ip_handler'
--------------

   *Synopsis*
     void
     __ip_handler(pktbuf_t    *PKT,
                  enet_addr_t SRC_ENET_ADDR);
   *Description*
The IP protocol handler for incoming packets. The incoming packet is
validated and passed to an appropriate higher level protocol handler.

`__ip_send'
-----------

   *Synopsis*
     void
     __ip_send(pktbuf_t   *PKT,
               int        PROTOCOL,
               ip_route_t *DEST);
   *Description*
Routine used by higher level protocols to send an IP packet.  PKT is
the packet buffer with filled in IP data field.  PROTOCOL is the value
for the IP header protocol field.  DEST is the destination IP address
and destination ethernet address. The PKT`->pkt_bytes' should contain
the number of bytes in the IP data field. Any IP options should also
already be filled in by the caller. This routine will fill in the IP
header (other than options), generate an IP checksum, then pass the
packet on to `__enet_send'.


File: bspint.info,  Node: UDP,  Next: TCP,  Prev: IP,  Up: Network Stack

UDP
===

   The BSP provides a very simple UDP implementation. It is used by the
BOOTP code.

`__udp_handler'
---------------

   *Synopsis*
     void
     __udp_handler(pktbuf_t    *PKT,
                   ip_route_t  SRC_ROUTE);
   *Description*
The handler for incoming UDP packets. The checksum is validated and a
simple linear search is made for a `socket listener' on the destination
port. If no handler is found the incoming datagram is ignored,
otherwise the datagram is passed to the socket listener.

`__udp_install_listener'
------------------------

   *Synopsis*
     int
     __udp_install_listener(udp_socket_t  *SKT,
                            word          PORT,
                            udp_handler_t HANDLER)
   *Description*
Install a UDP socket listener. SKT points to a socket structure to use
for the listener. The caller need not initialize any of the fields of
the structure. PORT is the UDP port to listen on and HANDLER is the
handler routine to call when an UDP packet arrives on PORT. The
`udp_socket_t' structure becomed owned by the UDP code until the socket
listener is removed. This routine returns zero if successful, -1 if a
socket listener is already installed for PORT.

`__udp_remove_listener'
-----------------------

   *Synopsis*
     int
     __udp_remove_listener(word PORT)
   *Description*
Stop listening on the given UDP PORT.

`__udp_send'
------------

   *Synopsis*
     void
     __udp_send(char       *BUF,
                int        LEN,
                ip_route_t *DEST_IP,
                word       DEST_PORT,
                word       SRC_PORT)
   *Description*
Send a UDP datagram. Sends LEN bytes of data from BUF.


File: bspint.info,  Node: TCP,  Next: Sockets,  Prev: UDP,  Up: Network Stack

TCP
===

   The TCP implementation is incomplete, but is sufficient to maintain a
reasonable connection to a host based debugger. In particular, TCP
windows (flow control) is not implemented. It is assumed that the debug
protocol will maintain its own flow control.

`__tcp_handler'
---------------

   *Synopsis*
     void
     __tcp_handler(pktbuf_t *PKT, ip_route_t *SRC_ROUTE)
   *Description*
The top-level handler of incoming TCP packets.

`__tcp_poll'
------------

   *Synopsis*
     void
     __tcp_poll(void);
   *Description*
The TCP polling routine. The blocking TCP interfaces will call this
routine periodically to poll for packets and timer events.

`__tcp_listen'
--------------

   *Synopsis*
     int
     __tcp_listen(tcp_socket_t *S,
                  word         PORT);
   *Description*
A non-blocking routine which initializes socket S and places it in a
linked list of socket listeners for the given PORT. Returns zero if
successful, non-zero on failure.

`__tcp_drain'
-------------

   *Synopsis*
     void
     __tcp_drain(tcp_socket_t *S);
   *Description*
This routine blocks until all pending writes for socket S have been
sent and ACKed or the connection closes.

`__tcp_close'
-------------

   *Synopsis*
     void
     __tcp_close(tcp_socket_t *S);
   *Description*
This routine blocks until all pending writes for socket S have been
sent or ACKed, then initiates a connection close.

`__tcp_close_wait'
------------------

   *Synopsis*
     void
     __tcp_close_wait(tcp_socket_t *S);
   *Description*
This routine blocks until the connection for socket S has completely
closed.

`__tcp_read'
------------

   *Synopsis*
     int
     __tcp_read(tcp_socket_t *S,
                char         *BUF,
                int          LEN);
   *Description*
Non-blocking read of up to LEN bytes of data into BUF for the given
socket S. A negative return value indicates that the connection is not
in a state to read data. A zero or positive value indicates the actual
number of bytes read.

`__tcp_write'
-------------

   *Synopsis*
     int
     __tcp_write(tcp_socket_t *S,
                 char         *BUF,
                 int          LEN);
   *Description*
Non-blocking write of up to LEN bytes of data from BUF for the given
socket S. A negative return value indicates that the connection is not
in a state to write data. A zero or positive value indicates the actual
number of bytes written.


File: bspint.info,  Node: Sockets,  Prev: TCP,  Up: Network Stack

Socket Interface
================

   The BSP network stack provides a high level socket interface on top
of TCP. This is a trivial socket interface which is geared toward a
debug stub connection.

`__skt_init'
------------

   *Synopsis*
     void
     __skt_init(tcp_socket_t   *S,
                unsigned short PORT);
   *Description*
Initialize the socket S for a connection on given PORT.

`__skt_wait_for_connect'
------------------------

   *Synopsis*
     void
     __skt_wait_for_connect(tcp_socket_t   *S);
   *Description*
Block while listening for an incoming connection on socket S.

`__skt_read'
------------

   *Synopsis*
     int
     __skt_read(tcp_socket_t *S,
                char         *BUF,
                int          LEN);
   *Description*
Read up to LEN bytes from the given socket S and put those bytes into
BUF. Returns number of bytes read. Zero may be returned if no bytes are
available or if the connection is no longer open.

`__skt_write'
-------------

   *Synopsis*
     int
     __skt_write(tcp_socket_t *S,
                 char         *BUF,
                 int          LEN);
   *Description*
Write LEN bytes from BUF to the given socket S. Returns number of bytes
written. This will block until all data is queued up for writing (not
necessarily ACKed). If returned value is less than LEN, then the
connection was closed. If the given LEN is zero, this routine blocks
until all previous writes have been ACKed.


File: bspint.info,  Node: System Information,  Next: Debug Support,  Prev: Network Stack,  Up: Top

System Information
******************

   An application may need to know about system resources which are
difficult for the application itself to discover. A good example of
this is an application which wants to provide a memory allocator. The
application will need to know the base address and size of each memory
region in the system. RAM testing and sizing is not practical for an
application which is itself running from RAM.

* Menu:

* bsp_sysinfo::


File: bspint.info,  Node: bsp_sysinfo,  Prev: System Information,  Up: System Information

`bsp_sysinfo'
=============

   *Synopsis*
     int
     bsp_sysinfo(enum bsp_info_id ID, ...)
   *Description*
This function takes at least one argument; the ID for the information
desired.  Depending on what information is requested, further arguments
may be needed.

* Menu:

* Platform Info::
* Cache Info::
* Memory Info::
* Comm Info::


File: bspint.info,  Node: Platform Info,  Next: Cache Info,  Prev: bsp_sysinfo,  Up: bsp_sysinfo

Platform Info
-------------

   The board name and CPU name is provided by `bsp_sysinfo' when the ID
is `BSP_INFO_PLATFORM'.  An additional string value may be returned
that gives any extra information needed.  This is useful for trademark
information and is generally board defined.

     err = bsp_sysinfo(BSP_INFO_PLATFORM,
                       struct bsp_platform_info *RESULT);
   A zero return value indicates success, a -1 indicates that this query
is not supported. If successful, the RESULT structure is filled out
with the platform information.

`bsp_platform_info'
...................

     struct bsp_platform_info {
       const char *cpu;
       const char *board;
       const char *extra;
     }
   *Description*
This structure holds pointers to the CPU and board names as well as an
addition board defined string. The BSP declares a global variable to
hold the value returned by `bsp_sysinfo'.

     struct bsp_platform_info _bsp_platform_info = {
         "Unknown",  /* cpu name */
         "Unknown",  /* board name */
         ""          /* extra */
     };
   It is the responsibility of board or architecure specific code to
modify these default values.


File: bspint.info,  Node: Cache Info,  Next: Memory Info,  Prev: Platform Info,  Up: bsp_sysinfo

Cache Info
----------

   Information is provided for instruction, data, and secondary caches.
`bsp_sysinfo' may be passed an ID of `BSP_INFO_DCACHE',
`BSP_INFO_ICACHE', and `BSP_INFO_SCACHE'.

     err = bsp_sysinfo(BSP_INFO_DCACHE,
                       struct bsp_cache_info *RESULT);
   A zero return value indicates success, a -1 indicates that the cache
info is not supported. If successful, the RESULT structure is filled
out with the cache information.

`bsp_cache_info'
................

     struct bsp_cachesize_info {
       int   size;
       short linesize;
       short ways;
     }
   *Description*
This structure contains information about cache layout. `size' is the
total size in bytes, `linesize' is the width of a cache line in bytes,
and `ways' is the number of ways per line. The BSP declares global
variables to the hold the default values returned by `bsp_sysinfo'.

     struct bsp_cachesize_info _bsp_dcache_info = {
         0, 0, 0
     };
     
     struct bsp_cachesize_info _bsp_icache_info = {
         0, 0, 0
     };
     
     struct bsp_cachesize_info _bsp_scache_info = {
         0, 0, 0
     };
   It is the responsibility of board or architecure specific code to
modify these default values.


File: bspint.info,  Node: Memory Info,  Next: Comm Info,  Prev: Cache Info,  Up: bsp_sysinfo

Memory Info
-----------

   The `bsp_sysinfo' interface can provide information about various
memory ranges. This is sometimes necessary because it can be impractical
or impossible to properly size memory regions after that memory region
is used for data or stack.

     err = bsp_sysinfo(BSP_INFO_MEMORY,
                       int index,
                       struct bsp_mem_info *result)
   The return value is zero if successful, -1 if index is invalid.
Caller should start index at zero, then increment index for subsequent
calls until error return indicates no more memory regions. Each
sucessful call fill in the result structure with information about a
memory region.

`bsp_mem_info'
..............

     struct bsp_mem_info {
       void *phys_start;   /* physical start address */
       void *virt_start;   /* virtual start address */
       int  virt_asid;     /* address space id */
       long nbytes;        /* length of region in bytes */
       int  kind;          /* kind of memory */
     #define BSP_MEM_RAM    1
     #define BSP_MEM_FLASH  2
     #define BSP_MEM_ROM    3
     }
   *Description*
The VIRT_START field is necessary because some systems must remap
physical space into a virtual space. The board specific code must
declare a global array of `bsp_mem_info' structures and an integer
variable indicating the number of elements in the array:

     /*
      * Array of memory region descriptors. We just list RAM and FLASH.
      */
     struct bsp_mem_info _bsp_memory_list[] =  {
         { (void *)0, (void *)0, 0, 0, BSP_MEM_RAM },
         { (void *)0x1fc00000, (void *)0x0, 0, 4 * 1024*1024, BSP_MEM_FLASH }
     };
     
     /*
      * Number of memory region descriptors.
      */
     int _bsp_num_mem_regions = 2;


File: bspint.info,  Node: Comm Info,  Prev: Memory Info,  Up: bsp_sysinfo

Comm Info
---------

   The BSP may provide a variable number of communication channels. The
`bsp_sysinfo' interface provides a mechanism to get information about
the number and kinds of communication channels.

     err = bsp_sysinfo(BSP_INFO_COMM,
                       int index,
                       struct bsp_comm_info *result)
   The return value is zero if successful, -1 if index is invalid.
Caller should start index at zero, then increment index for subsequent
calls until error return indicates no more channels. *Note
bsp_comm_info::


File: bspint.info,  Node: Debug Support,  Next: Miscellaneous API,  Prev: System Information,  Up: Top

Debug Support
*************

   The BSP provides debug support in the form of a debug agent to
handle error conditions requiring debugger intervention. As mentioned
in above, there is a vector point for a debug agent to gain control of
a target board when an exception indicates an error condition. The BSP
library and associated header files define a prototype for the debug
agent handler and a function to install this vector as noted in the
section on exception handling. The BSP provides the debug agent with
several architecture specific functions which are useful for debugging.

* Menu:

* Singlestep::
* Registers::
* Debug Events::
* Memory::


File: bspint.info,  Node: Singlestep,  Next: Registers,  Prev: Debug Support,  Up: Debug Support

Singlestep
==========

`bsp_singlestep_setup'
----------------------

   *Synopsis*
     void
     bsp_singlestep_setup(void *SAVED_REGS)
   *Description*
Prepare to execute a single machine instruction when current exception
context returns to the interrupted context. If the debug handler needs
to singlestep, it would call `bsp_singlestep_setup' just prior to
returning. The debug exception handler would then regain control after
a single instruction was executed.

`bsp_singlestep_cleanup'
------------------------

   *Synopsis*
     void
     bsp_singlestep_cleanup(void *SAVED_REGS)
   *Description*
Cleans up after a singlestep operation has completed. In some cases
this just clears a status flag in a CPU register. In other cases, this
routine must restore one or more instructions replaced by breakpoints
inserted by `bsp_singlestep_setup'. This routine must be safe to call
even if `bsp_singlestep_setup' was not called previously.


File: bspint.info,  Node: Registers,  Next: Debug Events,  Prev: Singlestep,  Up: Debug Support

Registers
=========

   The exact layout of the full set of registers saved for the debug
agent handler is private to the CPU and board specific parts of the
BSP. The debug handler must use access functions provided by the CPU
specific code to access the saved registers. The CPU specific code uses
an integer identifier for each register.  For lack of any better
standard, the BSP uses the same register id numbers used by the gdb
remote protocol. The following register access functions should be
provided by the architecture specific code.

`bsp_numregs'
-------------

   *Synopsis*
     int
     bsp_numregs(void)
   *Description*
`bsp_regbyte'
-------------

*Synopsis*
     int
     bsp_regbyte(int REGNO)
   *Description*
Returns the offset in bytes of the given register from the start of the
saved register area.

`bsp_regsize'
-------------

   *Synopsis*
     int
     bsp_regsize(int REGNO)
   *Description*
Returns the size in bytes of the given register.

`bsp_set_register'
------------------

   *Synopsis*
     void
     bsp_set_register(int  REGNO,
                      void *SAVED_REGS,
                      void *VAL)
   *Description*
Sets the value of register REGNO saved in an exception frame pointed to
by SAVED_REGS. The value is copied byte by byte from value buffer
pointed to by VAL. A default version of this routine is provided by the
generic code. This generic version is based simply on `bsp_regbyte' and
`bsp_regsize'.

`bsp_get_register'
------------------

   *Synopsis*
     void
     bsp_get_register(int  REGNO,
                      void *SAVED_REGS,
                      void *VAL)
   *Description*
Gets the value of register REGNO saved in an exception frame pointed to
by SAVED_REGS. The value is copied byte by byte from exception frame to
value buffer pointed to by VAL. A default version of this routine is
provided by the generic code. This generic version is based simply on
`bsp_regbyte' and `bsp_regsize'.


File: bspint.info,  Node: Debug Events,  Next: Memory,  Prev: Registers,  Up: Debug Support

Debug Events
============

   Debug agents also need to know why a program stopped. This can be
determined by an examination of the exception number and the saved
registers. The BSP provides this architecture specific function to map
the exception number and register values into a generic cause value:

`bsp_get_signal'
----------------

   *Synopsis*
     int
     bsp_get_signal(int  EXCEPTION_NUMBER,
                    void *SAVED_REGS)
   *Description*
Returns the reason why the debug agent was invoked. The currently
supported return values are a subset of those expected by GDB:

`TARGET_SIGNAL_INT'
     Program was interrupted.

`TARGET_SIGNAL_ILL'
     Illegal instruction opcode.

`TARGET_SIGNAL_TRAP'
     Breakpoint or watchpoint.

`TARGET_SIGNAL_ABRT'

`TARGET_SIGNAL_FPE'
     Divide-by-zero or other math error.

`TARGET_SIGNAL_BUS'
     Bus error.

`TARGET_SIGNAL_SEGV'
     Invalid memory access.

`bsp_breakpoint'
----------------

   *Synopsis*
     void
     bsp_breakpoint(void);
   *Description*
Causes a breakpoint exception.


File: bspint.info,  Node: Memory,  Prev: Debug Events,  Up: Debug Support

Memory
======

   Debug agents also need to read and write memory belonging to a
program being debugged. This can be dangerous because the engineer
doing the debugging may enter an incorrect address or a program error
may cause a pointer variable to be incorrect. The debug agent must be
able to recover from memory faults so that the problem can be reported.
To support this, the BSP provides functions to safely read and write
memory while in an exception context.

`bsp_memory_read'
-----------------

   *Synopsis*
     int
     bsp_memory_read(void *ADDR,
                     int  ASID,
                     int  RSIZE,
                     int  NREADS,
                     void *BUF);
   *Description*
Safe memory read. Returns the actual number of read operations which
were successful. The caller may check this return value to determine if
an error occurred. This routine attempts to perform NREADS read
operations with each operation being of RSIZE bits. The memory is read
from ADDR and the results are placed in BUF. It is necessary to specify
the size of the read operations in terms of some number of individual
bus operations of a given bit size. This allows for restrictions in
reading and writing some hardware registers. Some architectures may
also support multiple address spaces in which case ASID is used to
specify the address space. The interpretation of ASID is architecture
dependent, although a value of -1 will indicate `default'.

`bsp_memory_write'
------------------

   *Synopsis*
     int
     bsp_memory_write(void *ADDR,
                      int  ASID,
                      int  WSIZE,
                      int  NWRITES,
                      void *BUF);
   *Description*
Safe memory write. Returns the actual number of write operations which
were successful. The caller may check this return value to determine if
an error occurred. This routine attempts to perform NWRITES write
operations with each operation being of WSIZE bits. The data to write
is taken from BUF and written to ADDR. It is necessary to specify the
size of the write operations in terms of some number of individual bus
operations of a given bit size. This allows for restrictions in reading
and writing some hardware registers. Some architectures may also
support multiple address spaces in which case ASID is used to specify
the address space. The interpretation of ASID is architecture
dependent, although a value of -1 will indicate `default'.


File: bspint.info,  Node: Miscellaneous API,  Next: BSP Porting,  Prev: Debug Support,  Up: Top

Miscellaneous Interfaces
************************

* Menu:

* Formatted Output::
* Shared Memory::
* Caches::


File: bspint.info,  Node: Formatted Output,  Next: Shared Memory,  Prev: Miscellaneous API,  Up: Miscellaneous API

Formatted Output
================

   The BSP library provides a number of formatted output routines which
provide a subset of the standard libc conversion specifications.

* Menu:

* bsp_printf::
* bsp_dprintf::
* bsp_sprintf::
* bsp_vsprintf::


File: bspint.info,  Node: bsp_printf,  Next: bsp_dprintf,  Prev: Formatted Output,  Up: Formatted Output

`bsp_printf'
------------

   *Synopsis*
     void
     bsp_printf(const char *FMT, ...)
   *Description*
A stripped down, integer only version of libc `printf'. Output is sent
to the console channel.


File: bspint.info,  Node: bsp_dprintf,  Next: bsp_sprintf,  Prev: bsp_printf,  Up: Formatted Output

`bsp_dprintf'
-------------

   *Synopsis*
     void
     bsp_dprintf(const char *FMT,
                 ...)
   *Description*
A stripped down, integer only version of libc `printf'. Output is sent
to the debug channel.


File: bspint.info,  Node: bsp_sprintf,  Next: bsp_vsprintf,  Prev: bsp_dprintf,  Up: Formatted Output

`bsp_sprintf'
-------------

   *Synopsis*
     void
     bsp_sprintf(char       *STR,
                 const char *FMT,
                 ...)
   *Description*
A stripped down, integer only version of libc `sprintf'.


File: bspint.info,  Node: bsp_vsprintf,  Prev: bsp_sprintf,  Up: Formatted Output

`bsp_vsprintf'
--------------

   *Synopsis*
     void
     bsp_vsprintf(char       *STR,
                  const char *FMT,
                  va_list    AP)
   *Description*
A stripped down, integer only version of libc `vsprintf'.


File: bspint.info,  Node: Shared Memory,  Next: Caches,  Prev: Formatted Output,  Up: Miscellaneous API

Shared Memory Interface
=======================

   One of the requirements of BSP library routines is to be usable
whether the application is linked together with the BSP in ROM or
linked to run from RAM with the BSP in ROM. To support those routines,
the BSP uses a data structure which is shared between the code in ROM
and the separately linked code in RAM.

`bsp_shared_t'
--------------

     typedef struct {
         /* version number for future expansion */
         int		version;
     
         /*
          *  Pointer to the list of pointers to interrupt controller
          *  descriptors.
          */
         const struct bsp_irq_controller **__ictrl_table;
     
         /*
          *  Pointer to the array of exception vectors.
          */
         bsp_vec_t **__exc_table;
     
         /*
          * Pointer to debug handler vector.
          */
         bsp_handler_t *__dbg_vector;
     
         /*
          * User hook to catch debugger 'kill' command.
          */
         bsp_handler_t __kill_vector;
     
         /*
          * Vectored functions for console and debug i/o.
          */
         struct bsp_comm_procs *__console_procs;
         struct bsp_comm_procs *__debug_procs;
     
         /*
          * Vectored cache control functions.
          */
         void (*__flush_dcache)(void *__p, int __nbytes);
         void (*__flush_icache)(void *__p, int __nbytes);
     
         /*
          * Reset function
          * We want to avoid calling this with a trap since
          * we may be calling it from SWI mode (in cygmon).
          * That is problematic, as nested SWI's are not
          * very good.
          */
         void (*__reset)(void);
     
         /*
          * Generic data pointers
          */
         void *__cpu_data;
         void *__board_data;
     
         /*
          * General BSP information access. See bsp.h for details.
          */
         int  (*__sysinfo)(enum bsp_info_id __id, va_list __ap);
     
         /*
          * Set or get active debug and console channels.
          * Returns -1 if unsucessful.
          * If the passed in __comm_id is -1, then the id of
          * the current channel is returned.
          */
         int	 (*__set_debug_comm)(int __comm_id);
         int	 (*__set_console_comm)(int __comm_id);
     
         /*
          * Set or get the current baud rate of a serial comm channel.
          * Returns -1 on if unsuccessful.
          * If the given baud is -1, then the current baudrate is returned.
          */
         int  (*__set_serial_baud)(int __comm_id, int baud);
     
         /*
          * Debug agent data.
          */
         void *__dbg_data;
     
     } bsp_shared_t;
     
     bsp_shared_t *bsp_shared_data;
   *Description*
This structure contains linkages to code and data in a BSP based ROM.
The API routines make use of these linkages so that separately linked
code running in RAM can access the of vectors is used hook into ROM
services. Both ROM code and RAM code are provided with a pointer to
this structure (`bsp_shared_data').


File: bspint.info,  Node: Caches,  Prev: Shared Memory,  Up: Miscellaneous API

Caches
======

   A common operation for debug agents is to set breakpoints. This
usually means data writes to memory used to store instruction opcodes.
To ensure consistency and proper operation, caches must be flushed
after depositing a breakpoint. The BSP provides two architecture
specific functions to support cache flushes.

`bsp_flush_dcache'
------------------

   *Synopsis*
     void
     bsp_flush_dcache(void *P,
                      int  NBYTES)
   *Description*
Write back and invalidate data cache lines in the range of P to (P +
NBYTES). If NBYTES is -1, then flush entire cache.

`bsp_flush_icache'
------------------

   *Synopsis*
     void
     bsp_flush_icache(void *P,
                      int  NBYTES)
   *Description*
Invalidate instruction cache lines in the range of P to (P + NBYTES).

`bsp_reset'
-----------

   *Synopsis*
     void
     bsp_reset(void)
   *Description*
Reset the board.  If the board does not have a mechanism to allow a
software reset then this function does nothing.


File: bspint.info,  Node: BSP Porting,  Prev: Miscellaneous API,  Up: Top

BSP Porting
***********

New Architectures
=================

Configuration
-------------

   The BSP uses `autoconf' generated configure scripts to generate
makefiles based on a specified architecture. To add a new architecure
to the BSP requires adding support to the configuration scripts for
that architecture. This is done in the `configure.in' file.
Configurations are based on the target architecture which is specificed
using a three part naming scheme. The full naming scheme encodes three
pieces of information in the following pattern:

     ARCHITECTURE-VENDOR-OS

   There are several script variables which must be defined for each
target architecture supported by the BSP:

`archdir'
     This specifies the name of the architecture specific directory.

`boards'
     This is a space separated list of board specific directories which
     are located within the architecture specific directory.

`extra_subdirs'
     This is a space separated list of subdirectories which need to be
     created during the configure process.  This allows different
     variant of the same board to be built using one set of source.

Makefile Fragment
-----------------

   Every architecture port must include a makefile fragment named
`cpu.mk' in the architecture specific directory. This makefile fragment
should contain definitions for the following variables:

`BUILD_OPTIONS'
     This is a space separated list of optional components to include
     in the build. Currently, the only option that is not included by
     default is `BUILD_TCP', which should be appended to this variable
     if ethernet based debugging is to be enabled.

`CPU_SRCDIR'
     This is the subdirectory containing the CPU specific sources.
     This is generally set to `top_srcdir/archdir'

`CPU_INCDIR'
     This is the subdirectory containing the CPU specific headers.
     This is generally set to `$(CPU_SRCDIR)/include'

`CPU_HEADERS'
     This is a space separated list of architecture specific header
     files which should be installed as part of the BSP installation.
     Header files which are only needed to build the BSP library should
     not be included in this list.  The filenames should be relative to
     `$(CPU_INCDIR)'.

`CPU_OBJS'
     This is a list of object files which should be included in all BSP
     libraries based on this architecture.

`CPU_CFLAGS'
     Compiler flags which are common to all board ports based on this
     architecture.

`CPU_LDFLAGS'
     Linker flags which are common to all board ports based on this
     architecture.

`CPU_DEFINES'
     Preprocessor defines which are common to all board ports based on
     this architecture.

   Follow these variable definitions with any special build rules for
the given architecture.  The files defined in `CPU_OBJS' will be built
by rules in `common.mk' with dependencies automatically generated.
There may be object files which are used by only a subset of boards. In
this case, `cpu.mk' should include build rules for those objects as
well, but should not list them with `CPU_OBJS'. The pattern rules
defined in `common.mk' can be used to simplify these additions.  The
board specific makefile fragment may then include those objects in
`BOARD_OBJS' as necessary.

Required Files
--------------

`include/gdb-cpu.h'
     This file must define `NUMREGS' to be the number of registers
     expected by the hostside GDB debugger.

`include/bsp/cpu.h'
     Architecture specific header which must provide several items.

Required Data and Code
----------------------

New Boards
==========

Configuration
-------------

   The first step to porting to a new board is to add that board to the
configuration. This is done in the `bsp/configure.in' file. For each
supported architecture, configure.in has a list of supported boards for
that architecture. Suppose you want to add board `fooppc' to the list
of boards for `powerpc-eabi' builds. Looking in `configure.in', you
will see some code which looks like:

     powerpc-*-eabi)
           archdir="ppc";
           boards="cma101 mbx evb403 yellowknife/yka yellowknife/ykb yellowknife/yklb";
           extra_subdirs="yellowknife";
           ;;

   You will need to add `fooppc' to the boards variable. Anytime
`configure.in' is modified, the configure script must be regenerated
using `autoconf'.  Now that the board `fooppc' is added to the
configure script, configure will try to find a makefile fragment named
`board.mk' in the directory `bsp/ppc/fooppc'.

Makefile Fragment
-----------------

   Every board port must include a makefile fragment named `board.mk'
in the board specific directory. This makefile fragment should contain
definitions for the following variables:

`BUILD_OPTIONS'
     This is a space separated list of optional components to include
     in the build. Currently, the only option that is not included by
     default is `BUILD_TCP', which should be appended to this variable
     if ethernet based debugging is to be enabled.

`BOARD_NAME'
     This is the name of the board.  Generally this will be the same as
     the subdirectory containing the board specific sources.

`BOARD_SRCDIR'
     This is the subdirectory containing the board specific sources.
     This is generally set to `top_srcdir/archdir/$(BOARD_NAME)'

`BOARD_INCDIR'
     This is the subdirectory containing the board specific headers.
     This is generally set to `$(BOARD_SRCDIR)/include'

`BOARD_HEADERS'
     This is a space separated list of board specific header files which
     should be installed as part of the BSP installation. Header files
     which are only needed to build the BSP library should not be
     included in this list.  The filenames should be relative to
     `$(BOARD_INCDIR)'.

`BOARD_LIBBSP'
     This is the name of the BSP library. It must be unique among all
     board ports for a given architecture.  This is generally set to
     `lib$(BOARD_NAME).a'

`BOARD_OBJS'
     This is a list of board specific object files which should be
     included in the BSP library.

`BOARD_CFLAGS'
     Compiler flags for this particular board port.

`BOARD_LDFLAGS'
     Linker flags for this particular board port.

`BOARD_DEFINES'
     Preprocessor defines for this particular board port.

`BOARD_SPECS_STRIP'
     This contains the string to strip off of the front of the specs
     file name before installing it.  This will allow us to have
     multiple specs files for different target variants that will all
     get installed with the same name.

`BOARD_SPECS'
`BOARD_RAM_SPECS'
     These are the names of the specs file fragments used during
     compiling and linking applications for ROM or RAM respectively.

`BOARD_ROM_STARTUP'
`BOARD_RAM_STARTUP'
     These are lists of board specific object files that implement the
     board hardware initialization and C Runtime startup when compiling
     and linking applications for ROM or RAM respectively. These files
     are specified to `gcc' by the specs file and should not be
     included in the BSP library.

`BOARD_EXTRAS'
     Any extra files that need to be built for a given board should be
     listed here.

`BOARD_EXTRA_LIBS'
     Any extra files that need to be installed into the library path
     should be listed here.

`BOARD_CLEAN'
     Any extra intermediate files that should be removed on `make
     clean'.

   Follow these variable definitions with any special build rules for
the given architecture.  The files defined in `BOARD_OBJS' will be built
by rules in `common.mk' with dependencies automatically generated.

Specs Files
-----------

   Specs files are a mechanism to override certain default options of
the toolchain.. They are not documented except in the source code of
gcc. Their use will probably be deprecated in the near future, but they
are currently necessary. The specs files must follow a very strict
syntax and are easily broken by adding or removing blank lines.  The
best approach is to clone specs files from a board port of the same
architecture, changing only the names of startfiles, linker scripts,
etc.

Required Data and Code
----------------------

   Typically, board specific parts of the BSP are provided in a single
assembler file and a single C file. The assembler file must contain the
`_bsp_init_stack' routine. *Note Board Startup::.

   The typical board specific C file[s] will contain drivers for
communication devices (serial or ethernet), support for any supported
board specific interrupt controllers, and any other board
initialization code. The following are data and rotuines required:

`_bsp_comm_list'
     *Note _bsp_comm_list::

`_bsp_num_comms'
     *Note _bsp_num_comms::.

`_bsp_memory_list'
`_bsp_num_mem_regions'
     *Note Memory Info:: `_bsp_memory_list'.

`_bsp_init_board_comm'
     *Note _bsp_init_board_comm::.

`_bsp_install_board_irq_controllers'
     *Note _bsp_install_board_irq_controllers::.

`_bsp_board_init'
     *Note _bsp_board_init::


