\input texinfo
@setfilename bspint.info
@tex
% NOTE LOCAL KLUGE TO AVOID TOO MUCH WHITESPACE
\global\long\def\example{%
\begingroup
\let\aboveenvbreak=\par
\let\afterenvbreak=\par
\parskip=0pt
\lisp}
\global\long\def\Eexample{%
\Elisp
\endgroup
\vskip -\parskip% to cancel out effect of following \par
}
@end tex

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

@ifinfo
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.

@ignore
Permission is granted to process this file through Tex and print the
results, provided the printed document carries copying permission notice
identical to this one except for the removal of this paragraph (this
paragraph not being relevant to the printed manual).

@end ignore
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).
@end ifinfo

@setchapternewpage on
@setchapternewpage odd
@settitle Cygnus BSP Internals

@titlepage
@title{Cygnus BSP Internals}
@subtitle{A guide to the internals of the Cygnus Board Support Package}
@author Mark Salter
@author Cygnus Solutions
@page
@tex
\def\$#1${{#1}}  % Kluge: collect RCS revision info without $...$
\xdef\manvers{\$Revision: 1.10 $}  % For use in headers, footers too
{\parskip=0pt
\hfill Cygnus Solutions\par
\hfill \manvers\par
\hfill \TeX{}info \texinfoversion\par
}
\global\parindent=0pt
@end tex

@vskip 0pt plus 1filll
Copyright @copyright{} 1999 Cygnus Solutions

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.

@end titlepage

@node Top, Requirements, , (dir)
@top Scope of this Document

This document describes the Cygnus Board Support Package. It includes a
description of the BSP's architecture, as well as information on specific
implementations of that architecture.

@menu
* Requirements::
* Overview::
* Exceptions::
* Board Startup::
* Comm Channels::
* Network Stack::
* System Information::
* Debug Support::
* Miscellaneous API::
* BSP Porting::
@end menu

@node Requirements, Overview, Top, Top
@chapter Requirements

The basic requirement of the BSP is to provide embedded runtime support
for the GNU toolchain. This includes:

@itemize @bullet
@item
A debug stub to support GDB's remote protocol.
@item
A minimal syscall handler and bindings to support newlib (libc).
@item
Startup code to support ROMable applications.
@item
Startup code to support applications downloaded to RAM.
@end itemize

In general, this support for the GNU tools in a cross-compilation
embedded environment must be able to support a number of runtime
configurations:

@itemize @bullet
@item
User application/OS linked with board support in ROM. This linkage may
also include debug stub and library support.
@item
Standalone debug ROM consisting of board startup code, debug stub and
library support linked with minimal application to invoke the debug
stub. User application/OS can be downloaded and debugged in RAM by
using a remote debugger such as gdb.
@item
Same as above, but with the minimal application being replaced by a ROM
monitor to provide a command line interface for ASM level debugging.
@item
FLASH boot sector (or maybe small PROM) containing board support linked
with simple application to support loading/launching a user application/OS
contained in FLASH.
@item
Same as above, but the application in FLASH is a ROM monitor or standalone
debug stub so that user application/OS can be downloaded and debugged
in RAM.
@end itemize

All of the above configurations must be able to support arbitrary applications
with or without an operating system. It is also desireable to facilitate the
porting of this runtime support to proprietary hardware by requiring only a
minimal, well defined set of board specific code.

@node Overview, Exceptions, Requirements, Top
@chapter Overview

The overall BSP support is divided into common code, architecture specific
code and board specific code. This structure is represented in the BSP
directory hierarchy.

@menu
* Files::
* Naming Conventions::
@end menu

@node Files, Naming Conventions, Overview, Overview
@section Files

@table @file
@item bsp/common
BSP files which are common across all architectures. Among these are:

@table @file
@item breakpoint.c
Common bsp breakpoint handling.
@item bsp.c
Common bsp startup code.
@item bsp.ld
BSP linker script command file.
@item bsp_cache.c
BSP cache support.
@item bsp_if.c
Miscellaneous BSP support routines.
@item bsp_reset.c
Generic reset handling.  Not supported on all platforms.
@item bsplog.c
Debug log for internal BSP use.
@item common.mk
@itemx common_top.mk
Makefile fragment common to all BSP ports.
@item console-io.c
Console channel I/O routines.
@item debug-io.c
Debug channel I/O routines.
@item gdb-data.c
Shared data handling for GDB remote protocol stub.
@item gdb-threads.c
Generic support for multithread debugging.
@item gdb.c
Generic code for GDB remote protocol stub.
@item generic-mem.c
Generic versions of @code{bsp_memory_read} and @code{bsp_memory_write}.
@item generic-reg.c
Generic versions of @code{bsp_set_register} and @code{bsp_get_register}.
@item irq.c
@itemx irq-rom.c
Common exception/interrupt handling code.
@item main.c
Minimal BSP ROM application for standalone gdb stub.
@item net.c
High level interface to tcp/ip channel.
@item printf.c
@itemx sprintf.c
@itemx vprintf.c
Stripped down versions of formatting routines.
@item queue.c
General circular queue support for use in drivers.
@item shared-data.c
Shared data support.
@item syscall.c
Common syscall handler.
@item sysinfo.c
Declarations and handler for getting system information.
@item threads-syscall.c
Pseudo system calls to communicate with a kernel supporting gdb
thread-aware debugging.
@end table

@item bsp/syslib
BSP files which provide trap bindings for newlib.
@table @file
@item close.c
close() system call.
@item exit.c
exit() system call.
@item fstat.c
fstat() system call.
@item getpid.c
getpid() system call.
@item gettimeofday.c
gettimeofday() system call.
@item isatty.c
isatty() system call.
@item kill.c
kill() system call.
@item lseek.c
lseek() system call.
@item open.c
open() system call.
@item print.c
print() system call.
@item raise.c
raise() system call.
@item read.c
read() system call.
@item sbrk.c
sbrk() system call.
@item times.c
times() system call.
@item unlink.c
unlink() system call.
@item write.c
write() system call.
@end table

@item bsp/include
Internal BSP header files which are common across all architectures:
@table @file
@item bsp-trap.h
BSP Syscall definitions.
@item bsp_if.h
Internal shared memory interface between RAM based applications and
ROM based applications.
@item bsp_start.h
Generic C startup code as inline functions.
@item bsplog.h
General memory-based logging facility.
@item gdb-threads.h
Packet processing for thread aware debugging.
@item gdb.h
Definitions for GDB remote protocol stub.
@item net.h
Network stack interfaces.
@item queue.h
General circular queue support for use in drivers.
@item syscall.h
General definitions for use by the syscall subsystem. 
@item threads-syscall.h
Pseudo system calls to communicate with a kernel supporting gdb
thread-aware debugging.
@item bsp/bsp.h
Generic external interface declarations.
@item bsp/dbg-thread-api.h
Declarations used in supporting thread aware debugging.
@item bsp/defs.h
General definitions used in the BSP.
@item bsp/gdb-data.h
Shared memory interface to gdb remote stub.
@item bsp/hex-utils.h
Utilities for decoding hexadecimal encoded integers.
@end table

@item bsp/net
Trivial network stack to support BOOTP acquisition of IP address and
a minimal TCP debug channel.
@table @file
@item arp.c
ARP packet handler.
@item bootp.c
Support for getting IP address from BOOTP/DHCP server.
@item cksum.c
TCP/IP checksum utility routines.
@item enet.c
Low-level generic interface to poll for ethernet packets.
@item icmp.c
Respond to incoming PING packets.
@item ip.c
Trivial IP packet handler.
@item pktbuf.c
Simple allocator for packet buffers.
@item socket.c
Interface to TCP sockets.
@item tcp.c
Trivial TCP implementation.
@item timers.c
Simple polled timer support.
@item udp.c
Trivial UDP support.
@end table

@item bsp/<arch_name>
Files which are specific to a specific architecture. There is
one such directory for each supported architecture.
@item bsp/<arch_name>/<board_name>
Files which are specific to a specific board of a specific
architecure.
@end table

@node Naming Conventions, , Files, Overview
@section Naming Conventions

The interfaces described in this document fall into two broad areas. First,
there is the exported API which may be used internally by the BSP itself or
externally by a user application. This interface works equally well whether or
not the user application is directly linked with the boot code. That is, an
application being debugged in RAM may use this interface even if the main part
of the BSP is in ROM/FLASH. Secondly, there is the private interface which is
used internally and works only when linked with the main BSP in ROM/FLASH.
A user application should never need to use this interface as it is intended
to be used between the debug, board, and library support modules as well as
between generic, architecture specific, and board specific layers of those
modules. In general a function name beginning with @code{bsp_} is used for
exported functions which may be used by a user application. Function names
beginning with @code{_bsp_} are used by internal interfaces between generic,
architecture specific, and board specific code.

@node Exceptions, Board Startup, Overview, Top
@chapter Exceptions

To be useful, a debug agent such as a gdb stub will need to be able to take
control from an application being debugged. This can be the result of a program
error causing an exception or it can result from user input over the debug
channel. In the latter case, an interrupt must be generated so that the debug
agent can take control from the application being debugged. In order to support
this basic functionality, the BSP must install exception and interrupt
handlers. Unfortunately, there is seldom a clear distinction between exceptions
which need to be handled by the debug agent and those needed by the user
application. To further complicate matters, it is often the case that the debug
channel interrupt must go through one or more interrupt controllers which are
shared with other system devices. This requires the BSP to provide an interface
which allows exceptions and interrupts to be shared with the program being
debugged.

@menu
* Low-level::
* Interrupts::
* High-level::
* Summary::
@end menu

@node Low-level, Interrupts, Exceptions, Exceptions
@section Low-level Exception Handling

The BSP provides a consistent model of exception handling which is independent
of the underlying hardware architecture. At the lowest level, there is a vector
table which provides a vector service routine (@code{VSR}) pointer for each
exception which may be generated by the underlying hardware. On some
architectures, this table and the trampoline code used to dispatch through
it may not be necessary. For instance, the Fujitsu FR30 provides a suitable
vector table in hardware. In addition to the hardware related vectors, the
BSP may define other entries in the VSR table which provide hooks for other
services such as multithread debugging support for embedded OSes.

@subsection Default VSR

The BSP library provides a default VSR which is installed into the VSR table by
the BSP ROM startup code. This VSR establishes a higher level exception
mechanism which allows chaining of high-level language exception handlers.

@example

      default VSR entry point
                |
        switch to BSP stack
       save volatile registers
                |
     run user exception handler(s).
                |
      restore volatile registers
     switch back to original stack
                |
    zero returned from user handler?
             |     |
            No    Yes
             |     |
             |   Jump to debug agent entry point
             |
    return from exception

@end example

The user exception handlers are run by calling @code{_bsp_exc_dispatch}.
@xref{_bsp_exc_dispatch}. In the case of an error return from the user
exception handler, the VSR code jumps to the debug agent VSR entry point
which does the following:

@example

       debug VSR entry point
                |
        switch to BSP stack
        save all registers
                |
        debug agent handler
                |
         restore registers
      switch to original stack
                |
        return from exception

@end example

The exception handling mechanism for invoking the debug agent is very
different from other debug stub implementations where some set of individual
exception vectors are patched and completely taken over by the debug agent.
The set of vectors which indicate a problem requiring debug agent intervention
is both board and application dependent. This is not a good approach in all
cases. For instance, the application being debugged may make use of MMU
hardware. If the debug agent has control and tries to access memory, an MMU
exception may occur. If the debug agent has the MMU exception vector patched,
then the memory reference would appear to be an error even in cases where it
was a valid application address. If the application has the MMU exception
vector patched and the memory reference is invalid, then there is no mechanism
for the debug agent to catch that error. This problem is avoided by always
allowing the application exception handler to run and determine whether or not
debugger intervention is needed.

With some CPU architectures, it may make sense for the BSP to demux some
exceptions into more specific exceptions. For example, the MIPS architecture
has a general exception vector at the hardware level, but the BSP handler for
this exception will determine the more specific exception cause and provide
individual user exception vectors for all of those possible causes. Other 
architectures may require more than just a simple register save before
calling the exception handler or debug agent. The ARM architecture for instance
uses a number of different operating modes, each with a separate stack, for the
various kinds of exceptions. In such cases, the BSP may force the CPU into a
specific mode before calling the debug agent or user vectors.

@node Interrupts, High-level, Low-level, Exceptions
@section Interrupts

Because the BSP must support interrupts, it must deal with some number of
interrupt controllers. Generally, there are two types of interrupt controllers.
Those which use a priority scheme and those which don't. Priority based
interrupt controllers typically allow each interrupt to be assigned a priority
number. Interrupts are enabled and disabled based on their priority level.
Non-priority interrupt controllers typically enable and disable individual
interrupts using a bitmask. Both types of interrupt control may exist on any
given board. Sometimes an interrupt controller is integrated into the CPU,
sometimes it is external to the CPU and sometimes both are present. This
BSP is only interested in providing a common API to enable or disable
interrupts. The BSP interfaces do not support configuration of interrupt
controllers other than a default initialization. If a BSP client needs
a different configuration, then the BSP may be modified or the client
code outside of the BSP may reconfigure the interrupt system.

@menu
* bsp_irq_controller::
* _bsp_install_irq_controller::
@end menu

@node bsp_irq_controller, _bsp_install_irq_controller, Interrupts, Interrupts

In order for the common BSP code to deal with unknown numbers and kinds of
interrupt controllers, the architecture and board specific layers must inform
the generic BSP code of any interrupt controllers needed to support a debug
channel or error interrupt. The interrupt controllers are described by a data
type and the BSP is informed of them through an API.

@tindex bsp_irq_controller
@subsection @code{bsp_irq_controller}
@example
struct bsp_irq_controller @{
  /*
   * ID numbers for the first and last irqs handled by this
   * controller.
   */
  short	first;
  short	last;

  /* 
   * Pointer to array of bsp_vec_t pointers. These are the
   * heads of the linked list of ISRs for each irq handled
   * by this controller.
   */
  bsp_vec_t **vec_list;

  /*
   * Pointer to initialization routine which is run once at
   * boot time. This is where the controller is initialized
   * if necessary. This routine also installs a handler to
   * catch events which need to be handled by this controller.
   * For a first level interrupt controller, this is probably
   * an exception. It could be an interrupt handler if this
   * controller chains into another interrupt controller.
   */
  void (*init)(const struct bsp_irq_controller *ic);

  /*
   * Pointer to routines used to disable and enable interrupts
   * handled by this controller. The irq_nr passed is relative
   * to the first irq handled by this controller. That is, it
   * will range from zero to (last - first).
   */
  int  (*disable)(const struct bsp_irq_controller *ic, int irq_nr);
  void (*enable)(const struct bsp_irq_controller *ic, int irq_nr);
@};

@end example
@strong{Description}@*
A minimal representation of an interrupt controller.

@node _bsp_install_irq_controller, ,bsp_irq_controller, Interrupts

It is necessary to provide an API for runtime installation of interrupt
controllers. This allows a single BSP to support several versions of
the same board and to cleanly separate the installation of architectural
interrupt controllers and board-specific controllers.

@findex _bsp_install_irq_controller
@subsection @code{_bsp_install_irq_controller}
@strong{Synopsis}
@example
void
_bsp_install_irq_controller(const struct bsp_irq_controller *@var{ic});

@end example
@strong{Description}@*
Routine called by architecture and/or board specific initialization layers
to inform the common layer of an interrupt controller. The pointer passed
in must remain valid, therefore it should be a pointer to a statically
declared structure. This routine simply saves the pointer for use by the
common interrupt handling code.


@node High-level, Summary, Interrupts, Exceptions
@section High-level API

Higher level code needing access to exception handling may install an exception
vector to handle a given exception. C calling conventions are used for this
vector and the amount of context saved is architecture dependent. Anything
that could be destroyed across a C function call must be saved. 

@menu
* bsp_handler_t:: Handler protoype.
* bsp_vec_t:: Handler list element.
* bsp_install_vec:: Install a user handler.
* bsp_remove_vec:: Remove a user handler.
* bsp_install_dbg_handler:: Install a debug agent.
* bsp_invoke_dbg_handler:: Invoke the debug agent.
* _bsp_exc_dispatch:: Run user handlers.
* bsp_enable_irq:: Enable an interrupt.
* bsp_disable_irq:: Disable an interrupt.
@end menu

@node bsp_handler_t, bsp_vec_t, High-level, High-level
@tindex bsp_handler_t
@subsection @code{bsp_handler_t}
@example
typedef int (*bsp_handler_t)(int  @var{exc_nr},
                             void *@var{saved_regs})

@end example
@strong{Description}@*
Protoype for high-level execption and interrupt handlers. The integer return
value is used to determine whether or not the program may continue without
invoking the debug handler as shown above. A zero value will cause the debug
handler to be invoked. A non-zero value leads to a normal resumption of the
interrupted program. @var{exc_nr} indictates which exception (or interrupt)
caused the handler to be invoked and @var{saved_regs} is a pointer to the
exception stack frame where registers are saved.

@node bsp_vec_t, bsp_install_vec, bsp_handler_t, High-level
@tindex bsp_vec_t
@subsection @code{bsp_vec_t}
@example
typedef struct bsp_vec @{
  bsp_handler_t  handler;   /* pointer to handler */
  struct bsp_vec *next;     /* for chaining */
@} bsp_vec_t;

@end example
@strong{Description}@*
Used to create a linked list or interrupt and exception handlers.

@node bsp_install_vec, bsp_remove_vec, bsp_vec_t, High-level
@findex bsp_install_vec
@subsection @code{bsp_install_vec}
@strong{Synopsis}
@example
bsp_vec_t *bsp_install_vec(int @var{vec_kind},
                           int @var{vec_nr},
                           int @var{op},
                           bsp_vect_t *@var{vec});

@end example
@strong{Description}@*
Installs an interrupt or exception  vector chain pointed to
by @var{vec}. @var{vec_kind} should be @code{BSP_VEC_EXCEPTION}
or @code{BSP_VEC_INTERRUPT}. @var{vec_nr} identifies the exception
or interrupt. @var{op} should be one of:

@table @code
@item BSP_VEC_REPLACE
Replace existing chain.
@item BSP_VEC_CHAIN_FIRST
Install vector at head of current chain.
@item BSP_VEC_CHAIN_LAST
Install vector at end of current chain.
@end table

If @var{op} is @code{BSP_VEC_REPLACE}, a pointer to the replaced vector chain
is returned, otherwise the return value is meaningless.

It is important to note that the caller of @samp{bsp_install_vec} is
responsible for allocating the bsp_vec_t structure. This structure must be
reserved for use by the BSP until bsp_remove_vec is called. This was done
this way to keep the BSP from having to reserve a pool of memory of uncertain
size to support a memory allocator for the structures. That is, memory is
only allocated for those exceptions and interrupts which are actually used.


@node bsp_remove_vec, bsp_install_dbg_handler, bsp_install_vec, High-level
@findex bsp_remove_vec
@subsection @code{bsp_remove_vec}
@strong{Synopsis}
@example
void
bsp_remove_vec(int        @var{vec_kind},
               int        @var{vec_nr},
               bsp_vect_t *@var{vec});

@end example
@strong{Description}@*
Remove the vector pointed to by @var{vec} from and interrupt or
exception chain. @var{vec_kind} should be @code{BSP_VEC_EXCEPTION}
or @code{BSP_VEC_INTERRUPT}. @var{vec_nr} identifies the exception
or interrupt.


@node bsp_install_dbg_handler, bsp_invoke_dbg_handler, bsp_remove_vec, High-level
@findex bsp_install_dbg_handler
@subsection @code{bsp_install_dbg_handler}
@strong{Synopsis}
@example
bsp_handler_t
bsp_install_dbg_handler(bsp_handler_t @var{new_handler})

@end example
@strong{Description}@*
This routine installs @var{new_handler} as the current debug handler
and returns the previous handler.


@node bsp_invoke_dbg_handler, _bsp_exc_dispatch, bsp_install_dbg_handler, High-level
@findex bsp_invoke_dbg_handler
@subsection @code{bsp_invoke_dbg_handler}
@strong{Synopsis}
@example
void
bsp_invoke_dbg_handler(int  @var{exception_number},
                       void *@var{saved_regs})

@end example
@strong{Description}@*
This routine calls the debug handler vector directly from a user exception
or interrupt handler. This may be desireable because some boards use an
interrupt line to signal a bus error. If the interrupt handler simply
returned indicating an error, the debug agent would report a SIGINT. This
could be confusing, so the bus error interrupt handler could use this
routine to invoke the debug handler with a special @var{exception_number}
to indicate a bus error.

@node _bsp_exc_dispatch, bsp_enable_irq, bsp_invoke_dbg_handler, High-level
@findex _bsp_exc_dispatch
@subsection @code{_bsp_exc_dispatch}
@strong{Synopsis}
@example
int
_bsp_exc_dispatch(int  @var{exc_nr},
                  void *@var{saved_regs})

@end example
@strong{Description}@*
This routine provides a common API which low-level exception handlers
may use to invoke user exception handlers. Each installed user handler
for the given exception @var{exc_nr} is called in turn until one
returns a non-zero value or no more handlers exist. If there are
no handlers installed or none of the handlers installed return a 
non-zero value, this routine will return zero. If a called user
handler returns a non-zero value, this routine returns a non-zero
value.

@node bsp_enable_irq, bsp_disable_irq, _bsp_exc_dispatch, High-level
@findex bsp_enable_irq
@subsection @code{bsp_enable_irq}
@strong{Synopsis}
@example
void
bsp_enable_irq(int @var{irq_nr});

@end example
@strong{Description}@*
Enables the interrupt identified by @var{irq_nr}.

@node bsp_disable_irq, , bsp_enable_irq, High-level
@findex bsp_disable_irq
@subsection @code{bsp_disable_irq}
@strong{Synopsis}
@example
int
bsp_disable_irq(int @var{irq_nr});

@end example
@strong{Description}@*
Disables the interrupt identified by @var{irq_nr}. If
true if the interrupt was not already disabled, false
if the interrupt was already disabled.

@node Summary, , High-level, Exceptions
@section Summary

It should be noted that the user application is in no way forced to use this
exception handling mechanism provided by the BSP. In the vast majority of
cases, there is no reason not to use an exception handler written in a high
level language. There are exceptions (pun intended) to this. For example, the
MIPS architecture uses a software managed TLB as part of its MMU. A TLB refill
exception can be generated relatively often and in most cases a handler only
needs a small number of instructions to do its work. It would be very
inefficient to have to save and restore registers for such an exception. The
BSP ensures that a user application may simply install its own low level
exception handler over the top of the default handler put in place by the BSP.
On some architectures this is as simple as placing the exception vector
table in RAM. On other architectures, such as the AM30, exception vectors must
be in ROM, so the BSP must provide a hook for low-level exception handling as
well as the normal high level vectors.

In general, the same is true of interrupts. The application being debugged or
otherwise using the BSP may install its own interrupt handling. There is a
caveat in doing so, however. By replacing the BSP interrupt handling mechanism,
an application will probably break the ability of the debugger to interrupt a
running program asynchronously.


@node Board Startup, Comm Channels, Exceptions, Top
@chapter Board Startup

The reset startup code is the minimal amount of assembly code to enable
a higher level language to complete the board initialization. It is
board independent, but has necessary calls to board specific startup code.
It does the usual things like copying initialized data from ROM to RAM and
zeroing bss. The final initialization step is to call @code{bsp_init}
to finish initialization and start the application.

@menu
* _bsp_init_stack::
* _bsp_init::
* _bsp_init_board_comm::
* _bsp_install_cpu_irq_controllers::
* _bsp_install_board_irq_controllers::
* _bsp_cpu_init::
* _bsp_board_init::
@end menu

@node _bsp_init_stack, _bsp_init, Board Startup, Board Startup
When the reset startup code first takes control, it is likely that there is
not a usable stack pointer. One of the first things to be done is to setup a
usable stack. This is done by a call to the board specific assembler routine:

@findex _bsp_init_stack
@example
_bsp_init_stack
@end example

For some CPU architectures, it will not be possible to use a normal subroutine
call because those architectures require a stack to do so. In these cases, some
convention must be established to make this call. For instance, a prototype BSP
for the AM32 (MN103002) jumps to the @code{_bsp_init_stack} routine with the return
address passed in register a0:

@example
  .extern _bsp_init_stack
  mov _bsp_init_stack,a1
  mov 1f,a0
  jmp (a1)
1:

@end example

The @code{_bsp_init_stack} code may also need to perform hardware initializations to
enable bus operations. This is typically the case for highly integrated MCUs.
It may also be neccessary to probe the memory subsystem to discover the number
and sizes of various memory regions and caches.

After @code{_bsp_init_stack} returns, a valid stack exists and RAM accesses are
possible. The startup code will then copy initialized data from ROM to RAM and
clear the @code{.bss} area. At this point, the startup code will execute compiler
generated initialization code such as static constructors. Finally, the startup
code will jump to @code{_bsp_init}.


@node _bsp_init, _bsp_init_board_comm, _bsp_init_stack, Board Startup
@findex _bsp_init
@subsection @code{_bsp_init}
@strong{Synopsis}
@example
int
_bsp_init(void)

@end example
@strong{Description}@*
This routine will call CPU architecture and board-specific routines to complete
initialization before the application @code{main} routine is called. _bsp_init calls
a number of initialization routines which must be provided by the CPU or board
specific parts of the BSP as noted.

@node _bsp_init_board_comm, _bsp_install_cpu_irq_controllers, _bsp_init, Board Startup
@findex _bsp_init_board_comm
@subsection @code{_bsp_init_board_comm}
@strong{Synopsis}
@example
void
_bsp_init_board_comm(void)

@end example
@strong{Description}@*
This board specific routine should set up the board just enough to
enable debugging printfs to work. No interrupts should be used at
this point because the interrupt handling parts of the BSP have not
yet been initialized.

@node _bsp_install_cpu_irq_controllers, _bsp_install_board_irq_controllers, _bsp_init_board_comm, Board Startup
@findex _bsp_install_cpu_irq_controllers
@subsection @code{_bsp_install_cpu_irq_controllers}
@strong{Synopsis}
@example
void
_bsp_install_cpu_irq_controllers(void)

@end example
@strong{Description}@*
This is the architecture specific routine used to 'install' irq
controllers. It should call @code{_bsp_install_irq_controller} for each
interrupt controller which is integral to the CPU/MCU.

@node _bsp_install_board_irq_controllers, _bsp_cpu_init, _bsp_install_cpu_irq_controllers, Board Startup
@findex _bsp_install_board_irq_controllers
@subsection @code{_bsp_install_board_irq_controllers}
@strong{Synopsis}
@example
void
_bsp_install_board_irq_controllers(void)

@end example
@strong{Description}@*
This is the board specific routine used to 'install' irq controllers.
It should call @code{_bsp_install_irq_controller} for each peripheral
interrupt controller on the board.

@node _bsp_cpu_init, _bsp_board_init, _bsp_install_board_irq_controllers, Board Startup
@findex _bsp_cpu_init
@subsection @code{_bsp_cpu_init}
@strong{Synopsis}
@example
void
_bsp_cpu_init(void)

@end example
@strong{Description}@*
This CPU specific routine is responsible for any final CPU related
initializations which should be performed before calling @code{main}. 
    
@node _bsp_board_init, , _bsp_cpu_init, Board Startup
@findex _bsp_board_init
@subsection @code{_bsp_board_init}
@strong{Synopsis}
@example
void
_bsp_board_init(void)

@end example
@strong{Description}@*
This routine is responsible for any final board specific initialization
which should be performed before @code{main} is called.
    

@node Comm Channels, Network Stack, Board Startup, Top
@chapter Communication Channels

The BSP provides support for one or more communication channels. One of these
channels is needed for the debug channel. This debug channel may also serve as
the console I/O channel. Alternatively, if more than one channel is supported
for a given board, then a separate channel may be dedicated as the console I/O
channel. If no console channel is explictly selected, then console I/O is sent
to the debug channel. Each communication channel is identified by a small integer
from zero to N-1, where N is the total number of supported channels. A client of
the BSP can query for information about the communication channels.
@xref{System Information}.

@menu
* External Comm API::
* Internal Comm API::
* Comm Interrupts::
@end menu

@node External Comm API, Internal Comm API, Comm Channels, Comm Channels
@section External Interfaces

The following routines are the external interfaces to the BSP communciation
channels. These routines may be used by ROM based and RAM based applications.

@menu
* bsp_console_write::
* bsp_console_putc::
* bsp_console_read::
* bsp_console_getc::
* bsp_debug_write::
* bsp_debug_putc::
* bsp_debug_read::
* bsp_debug_getc::
* bsp_debug_irq_disable::
* bsp_debug_irq_enable::
* bsp_set_debug_comm::
* bsp_set_console_comm::
* bsp_set_serial_baud::
@end menu

@node bsp_console_write, bsp_console_putc, External Comm API, External Comm API
@findex bsp_console_write
@subsection @code{bsp_console_write}
@strong{Synopsis}
@example
void
bsp_console_write(const char *@var{p},
                  int        @var{len})

@end example
@strong{Description}@*
Write @var{len} characters from buffer pointed to by @var{p} to
the console output channel.

@node bsp_console_putc, bsp_console_read, bsp_console_write, External Comm API
@findex bsp_console_putc
@subsection @code{bsp_console_putc}
@strong{Synopsis}
@example
void
bsp_console_putc(char @var{ch})

@end example
@strong{Description}@*
Write character @var{ch} to the console output channel.

@node bsp_console_read, bsp_console_getc, bsp_console_putc, External Comm API
@findex bsp_console_read
@subsection @code{bsp_console_read}
@strong{Synopsis}
@example
int
bsp_console_read(char *@var{p},
                 int  @var{len})

@end example
@strong{Description}@*
Read up to @var{len} characters from console input channel. Place
characters read into buffer starting at @var{p}. This routine will
not block, so caller must be prepared to handle a return value of
zero.

@node bsp_console_getc, bsp_debug_write, bsp_console_read, External Comm API
@findex bsp_console_getc
@subsection @code{bsp_console_getc}
@strong{Synopsis}
@example
int
bsp_console_getc(void)

@end example
@strong{Description}@*
Read and return one character from the console input channel. This
routine will block until a character becomes available.

@node bsp_debug_write, bsp_debug_putc, bsp_console_getc, External Comm API
@findex bsp_debug_write
@subsection @code{bsp_console_write}
@strong{Synopsis}
@example
void
bsp_debug_write(const char *@var{p},
                int        @var{len})

@end example
@strong{Description}@*
Write @var{len} characters from buffer pointed to by @var{p} to
the debug output channel.

@node bsp_debug_putc, bsp_debug_read, bsp_debug_write, External Comm API
@findex bsp_debug_putc
@subsection @code{bsp_debug_putc}
@strong{Synopsis}
@example
void
bsp_debug_putc(char @var{ch})

@end example
@strong{Description}@*
Write character @var{ch} to the debug output channel.

@node bsp_debug_read, bsp_debug_getc, bsp_debug_putc, External Comm API
@findex bsp_debug_read
@subsection @code{bsp_debug_read}
@strong{Synopsis}
@example
int
bsp_debug_read(char *@var{p},
               int  @var{len})

@end example
@strong{Description}@*
Read up to @var{len} characters from debug input channel. Place
characters read into buffer starting at @var{p}. This routine will
not block, so caller must be prepared to handle a return value of
zero.

@node bsp_debug_getc, bsp_debug_irq_disable, bsp_debug_read, External Comm API
@findex bsp_debug_getc
@subsection @code{bsp_debug_getc}
@strong{Synopsis}
@example
int
bsp_debug_getc(void)

@end example
@strong{Description}@*
Read and return one character from the debug input channel. This
routine will block until a character becomes available.

@node bsp_debug_irq_disable, bsp_debug_irq_enable, bsp_debug_getc, External Comm API
@findex bsp_debug_irq_disable
@subsection @code{bsp_debug_irq_disable}
@strong{Synopsis}
@example
int
bsp_debug_irq_disable(void)

@end example
@strong{Description}@*
Disable the receive interrupt for the debug channel. Returns zero if the interrupt
was already disabled, non-zero otherwise.

@node bsp_debug_irq_enable, bsp_set_debug_comm, bsp_debug_irq_disable, External Comm API
@findex bsp_debug_irq_enable
@subsection @code{bsp_debug_irq_enable}
@strong{Synopsis}
@example
void
bsp_debug_irq_enable(void)

@end example
@strong{Description}@*
Enable the receive interrupt for the debug channel.


@node bsp_set_debug_comm, bsp_set_console_comm, bsp_debug_irq_enable, External Comm API
@findex bsp_set_debug_comm
@subsection @code{bsp_set_debug_comm}
@strong{Synopsis}
@example
int
bsp_set_debug_comm(int @var{comm_id})

@end example
@strong{Description}@*
Set or get the active debug channel to channel @var{comm_id}. Return zero if
successful. If @var{comm_id} is -1, then the current debug channel is returned.

@node bsp_set_console_comm, bsp_set_serial_baud, bsp_set_debug_comm, External Comm API
@findex bsp_set_console_comm
@subsection @code{bsp_set_console_comm}
@strong{Synopsis}
@example
int
bsp_set_console_comm(int @var{comm_id})

@end example
@strong{Description}@*
Set or get the active console channel to channel @var{comm_id}. Return zero if
successful. If @var{comm_id} is -1, then the current console channel is returned.

@node bsp_set_serial_baud, , bsp_set_console_comm, External Comm API
@findex bsp_set_serial_baud
@subsection @code{bsp_set_serial_baud}
@strong{Synopsis}
@example
int
bsp_set_serial_baud(int @var{comm_id},
                    int @var{baud})

@end example
@strong{Description}@*
Set the speed of channel @var{comm_id} to @var{baud} bits per second.
A return value of zero indicates success. A non-zero return value indicates
that the desired baud rate is unsupported for the given channel. If @var{baud}
is -1, then the current baudrate is returned.

@node Internal Comm API, Comm Interrupts, External Comm API, Comm Channels
@section Internal Interfaces

The generic comm handling layer expects the architecture or board specific code
to provide information about the comm channels supported by the board. This
information is provided in a simple global array and a channel count variable.

@menu
* bsp_comm_info::
* bsp_comm_procs::
* bsp_comm_channel::
* _bsp_comm_list::
* _bsp_num_comms::
@end menu

@node bsp_comm_info, bsp_comm_procs, Internal Comm API, Internal Comm API
@tindex bsp_comm_info
@subsection @code{bsp_comm_info}
@example
struct bsp_comm_info @{
  char    *name;
  short   kind;
#define BSP_COMM_SERIAL 1
#define BSP_COMM_ENET   2
  short   protocol;
#define BSP_PROTO_NONE  0
#define BSP_PROTO_UDP   1
#define BSP_PROTO_TCP   2
@}

@end example
@strong{Description}@*
Basic information about a communication channel.

@node bsp_comm_procs, bsp_comm_channel, bsp_comm_info, Internal Comm API
@tindex bsp_comm_procs
@subsection @code{bsp_comm_procs}
@strong{Synopsis}
@example
struct bsp_comm_procs @{
  /*
   * Implementation dependent data pointer passed to the
   * following procs when called.
   */
  void *ch_data;

  /*
   * Write a buffer of the given length.
   */
  void (*__write)(void *ch_data, const char *buf, int len);

  /*
   * Fill a buffer with up to the given length. Returns
   * the actual number of characters read (may be zero).
   */
  int  (*__read)(void *ch_data, char *buf, int len);

  /*
   * Send a single character.
   */
  void (*__putc)(void *ch_data, char ch);

  /*
   * Read a single character. If no character is immediately
   * available, will block until one becomes available.
   */
  int  (*__getc)(void *ch_data);

  /*
   * Catchall comm port control.
   */
  int  (*__control)(void *ch_data, int func, ...);

  /*
   * For serial ports, the control function may be used to set
   * and get the current baud rate. Usage:
   * 
   *   err = (*__control)(COMMCTL_SETBAUD, int bits_per_second);
   *     err => Zero if successful, -1 if error.
   *
   *   baud = (*__control)(COMMCTL_GETBAUD);
   *     baud => -1 if error, current baud otherwise.
   */
#define COMMCTL_SETBAUD 0
#define COMMCTL_GETBAUD 1

  /*
   * Install and remove debugger interrupt handlers. These
   * are the receiver interrupt routines which may be used
   * to receive a request to stop a running program.
   */
#define COMMCTL_INSTALL_DBG_ISR 2
#define COMMCTL_REMOVE_DBG_ISR  3

    /*
     * Disable comm port interrupt. Returns TRUE if
     * interrupt was enabled, FALSE otherwise.
     */
#define COMMCTL_IRQ_DISABLE 4
    /*
     * Enable comm port interrupt.
     */
#define COMMCTL_IRQ_ENABLE 5
@};

@end example
@strong{Description}@*
This is the low-level interface to the communication channel drivers. All
higher level APIs go through these vectors. 

@node bsp_comm_channel, _bsp_comm_list, bsp_comm_procs, Internal Comm API
@tindex bsp_comm_channel
@subsection @code{bsp_comm_channel}
@example
struct bsp_comm_channel @{
  struct bsp_comm_info   info;
  struct bsp_comm_procs  procs;
@};

@end example
@strong{Description}@*
This structure is a complete description of a single BSP communication channel.
It contains general information (@code{bsp_comm_info}) and a set of vectors
(@code{bsp_comm_procs}) for performing communication channel functions.


@node _bsp_comm_list, _bsp_num_comms, bsp_comm_channel, Internal Comm API
@vindex _bsp_comm_list
@subsection @code{_bsp_comm_list}
@strong{Synopsis}
@example
struct bsp_comm_channel _bsp_comm_list[];

@end example
@strong{Description}@*
Array to hold descriptors of each supported communication channel.

@node _bsp_num_comms, , _bsp_comm_list, Internal Comm API
@vindex _bsp_num_comms
@subsection @code{_bsp_num_comms}
@strong{Synopsis}
@example
int _bsp_num_comms;

@end example
@strong{Description}@*
The number of supported communication channels. For each communication channel,
there is an entry in the @code{_bsp_comm_list} array.


@node Comm Interrupts, ,Internal Comm API, Comm Channels
@section Interrupts

Each communication channel driver should provide support for a receive data
interrupt so that a debug agent may interrupt a running program. The exact
nature of this "stop" command is private to the specific debug protocol being
used. For the gdb remote remote protocol, reception of a @code{^C} character
is used to interrupt the running program.

A non-zero return value indicates that the interrupt handler should indicate
an error condition so that the debug handler can take control from the running
program being debugged. It is the responsibility of the debug agent to make
sure this function pointer is set to point to the desired protocol specific
function.


@node Network Stack, System Information, Comm Channels, Top
@chapter Network Stack

A prototype network stack has been created to provide a high speed channel
between host and target boards. This network code relies on a link level
driver provided by the board specific code in the BSP. It provides very
minimal support for @code{UDP}, @code{TCP}, and @code{BOOTP} services.
The network stack is designed to work in a polled manner with interrupts
disabled. There is minimal interrupt support for received packets so
that a target board will answer @code{ARP} and @code{ICMP} (@code{PING})
requests while an application is running.

@menu
* Data Types::
* Packet Buffers::
* Ethernet::
* ARP::
* BOOTP::
* IP::
* UDP::
* TCP::
* Sockets::
@end menu

@node Data Types, Packet Buffers, Network Stack, Network Stack
@section Data Types

@file{include/net.h} defines many data types for the network stack. The
basic scalar types are:

@table @code
@item octet
An unsigned 8-bit integer.
@item word
An unsigned 16-bit integer.
@item dword
An unsigned 32-bit integer.
@end table

@tindex enet_addr_t
@subsection @code{enet_addr_t}
@example
typedef octet enet_addr_t[6];

@end example
@strong{Description}@*
Ethernet address type.

@tindex ip_addr_t
@subsection @code{ip_addr_t}
@example
typedef octet enet_addr_t[4];

@end example
@strong{Description}@*
Internet Protocol address type.

@tindex eth_header_t
@subsection @code{eth_header_t}
@example
typedef struct @{
    enet_addr_t   destination;
    enet_addr_t   source;
    word          type;
@} eth_header_t;

@end example
@strong{Description}@*
Ethernet protocol header. The @code{type} field values that the BSP is
interested in are:
@itemize @bullet
@item
ETH_TYPE_IP
@item
ETH_TYPE_ARP
@item
ETH_TYPE_RARP
@end itemize

@tindex arp_header_t
@subsection @code{arp_header_t}
@example
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;

@end example
@strong{Description}@*
The ARP/RARP header. This header immediately follows the ethernet header
when the ethernet @code{type} is @code{ETH_TYPE_ARP} or @code{ETH_TYPE_RARP}.
In the case of the BSP, the only @code{hw_type} value is @code{ARP_HW_ETHER}.
The opcode field is one of:
@itemize @bullet
@item
ARP_REQUEST
@item
ARP_REPLY
@item
RARP_REQUEST
@item
RARP_REPLY
@end itemize

@tindex ip_header_t
@subsection @code{ip_header_t}
@example
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;

@end example
@strong{Description}@*
The IP protocol header. Supported @code{protocol} fields are:
@itemize @bullet
@item
IP_PROTO_ICMP
@item
IP_PROTO_TCP
@item
IP_PROTO_UDP
@end itemize

@tindex ip_route_t
@subsection @code{ip_route_t}
@example
typedef struct @{
    ip_addr_t    ip_addr;
    enet_addr_t  enet_addr;
@} ip_route_t;

@end example
@strong{Description}@*
Structure to bind an IP address to an ethernet address.

@tindex udp_header_t
@subsection @code{udp_header_t}
@example
typedef struct @{
    word	src_port;
    word	dest_port;
    word	length;
    word	checksum;
@} udp_header_t;

@end example
@strong{Description}@*
User Datagram Protocol header. This header follows the IP header when the IP
header @code{protocol} field is @code{IP_PROTO_UDP}.

@tindex tcp_header_t
@subsection @code{tcp_header_t}
@example
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;

@end example
@strong{Description}@*
Transaction Control Protocol header. This header follows the IP header when the
IP header @code{protocol} field is @code{IP_PROTO_TCP}.

@tindex icmp_header_t
@subsection @code{icmp_header_t}
@example
typedef struct @{
    octet	type;
    octet	code;
    word	checksum;
    word	ident;
    word	seqnum;
@} icmp_header_t;

@end example
@strong{Description}@*
ICMP protocol header.This header follows the IP header when the IP header
@code{protocol} field is @code{IP_PROTO_ICMP}. The BSP uses ICMP to respond to
@samp{ping} packets.

@tindex bootp_header_t
@subsection @code{bootp_header_t}
@example
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;

@end example
@strong{Description}@*
BOOTP protocol header. This header follows a UDP protocol header.

@tindex pktbuf_t
@subsection @code{pktbuf_t}
@example
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;

@end example
@strong{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 @code{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. @code{pkt_bytes} is a count of bytes used by the packet.
@code{bufsize} is the total size of the packet buffer and @code{buf} points to
the start of actual buffer. Several convenience macros are provided to access
protocol headers:
@example

#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

@end example

@tindex tcp_socket_t
@subsection tcp_socket_t
@example
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;

@end example
@strong{Description}@*
Internal representation of a TCP connection.

@tindex udp_handler_t
@subsection udp_handler_t
@example
typedef void (*udp_handler_t)(udp_socket_t *@var{skt},
                              char         *@var{buf},
                              int          @var{len},
			      ip_route_t   *@var{src_route},
                              word         @var{src_port});

@end example
@strong{Description}@*
Prototype for a UDP socket handler. @var{skt} is a pointer to
the UDP socket listener structure. @var{buf} points to the
UDP data field and @var{len} is the length of that data in
byte. @var{src_route} is the route to the sender and @var{src_port}
is the sender's port number.

@tindex udp_socket_t
@subsection udp_socket_t
@example
typedef struct _udp_socket @{
    struct _udp_socket	*next;
    word		our_port;
    word		pad;
    udp_handler_t       handler;
@} udp_socket_t;

@end example
@strong{Description}@*
Descriptor for a UDP socket listener.

@node Packet Buffers, Ethernet, Data Types, Network Stack
@section 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.

@findex __pktbuf_alloc
@subsection @code{__pktbuf_alloc}
@strong{Synopsis}
@example
pktbuf_t *
__pktbuf_alloc(int @var{nbytes})

@end example
@strong{Description}@*
Simple pktbuf allocator. The current implementation ignores @var{nbytes}.
If successful, a pointer to an iniitalized  @code{pktbuf_t} structure is
returned. If no more buffers are available, NULL is returned. The returned
@code{pktbuf_t} is provided with a buffer of @code{ETH_MAX_PKTLEN} bytes.
The @code{eth_hdr}, @code{ip_hdr}, and @code{tcp_hdr} fields are valid
and @code{pkt_bytes} is zero.

@findex __pktbuf_free
@subsection @code{__pktbuf_free}
@strong{Synopsis}
@example
void
__pktbuf_free(pktbuf_t *@var{pkt})

@end example
@strong{Description}@*
Return @var{pkt} to the pool of free @code{pktbuf_t} buffers.

@node Ethernet, ARP, Packet Buffers, Network Stack
@section 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

@findex _bsp_install_enet_driver
@subsection @code{_bsp_install_enet_driver}
@strong{Synopsis}
@example
void
_bsp_install_enet_driver(struct bsp_comm_procs *@var{procs});

@end example
@strong{Description}@*
Boot time initialization routine called by ethernet driver initialization
code to install the ethernet procs.

@findex __enet_poll
@subsection @code{__enet_poll}
@strong{Synopsis}
@example
void
__enet_poll(void)

@end example
@strong{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 @code{__enet_poll} returns. If the
driver does return a packet, the ethernet header @code{type} field
is checked to see which protocol handler to pass the packet to.

@findex __enet_send
@subsection @code{__enet_send}
@strong{Synopsis}
@example
void
__enet_send(pktbuf_t    *@var{pkt},
            enet_addr_t @var{dest},
            int         @var{eth_type});

@end example
@strong{Description}@*
Routine called by higher level protocol handlers to send an ethernet
packet.


@subsection 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 @code{__local_enet_addr} variable with the ethernet device's
local ethernet address and it must pass a @code{bsp_comm_procs} structure
to @code{_bsp_net_init}. The @code{bsp_comm_procs} structure must provide
a @code{__write} vector, a @code{__read} vector, and a @code{__control}
vector.

@subsubsection Write

The buffer passed into the @code{__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 @code{__write} vector is the total length of the packet including
ethernet header.

@subsubsection 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
@code{__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.

@subsubsection Control

The ethernet @code{__control} vector should support the following operations:
@itemize @bullet
@item COMMCTL_INSTALL_DBG_ISR
@item COMMCTL_REMOVE_DBG_ISR
@item COMMCTL_IRQ_DISABLE
@item COMMCTL_IRQ_ENABLE
@end itemize

@subsubsection 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 @code{gdb_interrupt_check}.
@example

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

@end example

@node ARP, BOOTP, Ethernet, Network Stack
@section 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,
@code{__enet_poll} will call the ARP protocol handler.

@findex __arp_handler
@subsection @code{__arp_handler}
@strong{Synopsis}
@example
void
__arp_handler(pktbuf_t *@var{pkt})

@end example
@strong{Description}@*
Handle incoming ARP packets. Responds to ARP REQUEST packets destined
for the target board IP address.

@node BOOTP, IP, ARP, Network Stack
@section 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.

@findex __bootp_find_local_ip
@subsection @code{__bootp_find_local_ip}
@strong{Synopsis}
@example
int
__bootp_find_local_ip(void)

@end example
@strong{Description}@*
Try to find local IP address through BOOTP broadcasts. If successful,
the @code{__local_ip_addr} variable is filled in with the appropriate
address and zero is returned. If not successful, a non-zero value is
returned.

@node IP, UDP, BOOTP, Network Stack
@section 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.

@findex __ip_handler
@subsection @code{__ip_handler}
@strong{Synopsis}
@example
void
__ip_handler(pktbuf_t    *@var{pkt},
             enet_addr_t @var{src_enet_addr});

@end example
@strong{Description}@*
The IP protocol handler for incoming packets. The incoming packet is
validated and passed to an appropriate higher level protocol handler.

@findex __ip_send
@subsection @code{__ip_send}
@strong{Synopsis}
@example
void
__ip_send(pktbuf_t   *@var{pkt},
          int        @var{protocol},
          ip_route_t *@var{dest});

@end example
@strong{Description}@*
Routine used by higher level protocols to send an IP packet.
@var{pkt} is the packet buffer with filled in IP data field.
@var{protocol} is the value for the IP header protocol field.
@var{dest} is the destination IP address and destination
ethernet address. The @var{pkt}@code{->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 @code{__enet_send}.

@node UDP, TCP, IP, Network Stack
@section UDP

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

@findex __udp_handler
@subsection @code{__udp_handler}
@strong{Synopsis}
@example
void
__udp_handler(pktbuf_t    *@var{pkt},
              ip_route_t  @var{src_route});

@end example
@strong{Description}@*
The handler for incoming UDP packets. The checksum is validated and
a simple linear search is made for a @samp{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.

@findex __udp_install_listener
@subsection @code{__udp_install_listener}
@strong{Synopsis}
@example
int
__udp_install_listener(udp_socket_t  *@var{skt},
                       word          @var{port},
                       udp_handler_t @var{handler})

@end example
@strong{Description}@*
Install a UDP socket listener. @var{skt} points to a socket structure
to use for the listener. The caller need not initialize any of the
fields of the structure. @var{port} is the UDP port to listen on and
@var{handler} is the handler routine to call when an UDP packet arrives
on @var{port}. The @code{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
@var{port}.

@findex __udp_remove_listener
@subsection @code{__udp_remove_listener}
@strong{Synopsis}
@example
int
__udp_remove_listener(word @var{port})

@end example
@strong{Description}@*
Stop listening on the given UDP @var{port}.

@findex __udp_send
@subsection @code{__udp_send}
@strong{Synopsis}
@example
void
__udp_send(char       *@var{buf},
           int        @var{len},
           ip_route_t *@var{dest_ip},
           word       @var{dest_port},
           word       @var{src_port})

@end example
@strong{Description}@*
Send a UDP datagram. Sends @var{len} bytes of data from @var{buf}.

@node TCP, Sockets, UDP, Network Stack
@section 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.

@findex __tcp_handler
@subsection @code{__tcp_handler}
@strong{Synopsis}
@example
void
__tcp_handler(pktbuf_t *@var{pkt}, ip_route_t *@var{src_route})

@end example
@strong{Description}@*
The top-level handler of incoming TCP packets.

@findex __tcp_poll
@subsection @code{__tcp_poll}
@strong{Synopsis}
@example
void
__tcp_poll(void);

@end example
@strong{Description}@*
The TCP polling routine. The blocking TCP interfaces will call
this routine periodically to poll for packets and timer events.

@findex __tcp_listen
@subsection @code{__tcp_listen}
@strong{Synopsis}
@example
int
__tcp_listen(tcp_socket_t *@var{s},
             word         @var{port});

@end example
@strong{Description}@*
A non-blocking routine which initializes socket @var{s} and places it
in a linked list of socket listeners for the given @var{port}. Returns
zero if successful, non-zero on failure.

@findex __tcp_drain
@subsection @code{__tcp_drain}
@strong{Synopsis}
@example
void
__tcp_drain(tcp_socket_t *@var{s});

@end example
@strong{Description}@*
This routine blocks until all pending writes for socket @var{s} have been
sent and ACKed or the connection closes.

@findex __tcp_close
@subsection @code{__tcp_close}
@strong{Synopsis}
@example
void
__tcp_close(tcp_socket_t *@var{s});

@end example
@strong{Description}@*
This routine blocks until all pending writes for socket @var{s} have been
sent or ACKed, then initiates a connection close.

@findex __tcp_close_wait
@subsection @code{__tcp_close_wait}
@strong{Synopsis}
@example
void
__tcp_close_wait(tcp_socket_t *@var{s});

@end example
@strong{Description}@*
This routine blocks until the connection for socket @var{s} has completely
closed.

@findex __tcp_read
@subsection @code{__tcp_read}
@strong{Synopsis}
@example
int
__tcp_read(tcp_socket_t *@var{s},
           char         *@var{buf},
           int          @var{len});

@end example
@strong{Description}@*
Non-blocking read of up to @var{len} bytes of data into @var{buf} for the
given socket @var{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.


@findex __tcp_write
@subsection @code{__tcp_write}
@strong{Synopsis}
@example
int
__tcp_write(tcp_socket_t *@var{s},
            char         *@var{buf},
            int          @var{len});

@end example
@strong{Description}@*
Non-blocking write of up to @var{len} bytes of data from @var{buf} for the
given socket @var{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.

@node Sockets, , TCP, Network Stack
@section 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.

@findex __skt_init
@subsection @code{__skt_init}
@strong{Synopsis}
@example
void
__skt_init(tcp_socket_t   *@var{s},
           unsigned short @var{port});

@end example
@strong{Description}@*
Initialize the socket @var{s} for a connection on given @var{port}.


@findex __skt_wait_for_connect
@subsection @code{__skt_wait_for_connect}
@strong{Synopsis}
@example
void
__skt_wait_for_connect(tcp_socket_t   *@var{s});

@end example
@strong{Description}@*
Block while listening for an incoming connection on socket @var{s}.


@findex __skt_read
@subsection @code{__skt_read}
@strong{Synopsis}
@example
int
__skt_read(tcp_socket_t *@var{s},
           char         *@var{buf},
           int          @var{len});

@end example
@strong{Description}@*
Read up to @var{len} bytes from the given socket @var{s} and put those
bytes into @var{buf}. Returns number of bytes read. Zero may be returned
if no bytes are available or if the connection is no longer open.

@findex __skt_write
@subsection @code{__skt_write}
@strong{Synopsis}
@example
int
__skt_write(tcp_socket_t *@var{s},
            char         *@var{buf},
            int          @var{len});

@end example
@strong{Description}@*
Write @var{len} bytes from @var{buf} to the given socket @var{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 @var{len}, then
the connection was closed. If the given @var{len} is zero, this routine blocks
until all previous writes have been ACKed.


@node System Information, Debug Support, Network Stack, Top
@chapter 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::
@end menu

@node bsp_sysinfo, , System Information, System Information
@findex bsp_sysinfo
@section @code{bsp_sysinfo}
@strong{Synopsis}
@example
int
bsp_sysinfo(enum bsp_info_id @var{id}, ...)

@end example
@strong{Description}@*
This function takes at least one argument; the @var{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::
@end menu

@node Platform Info, Cache Info, bsp_sysinfo, bsp_sysinfo
@subsection Platform Info
The board name and CPU name is provided by @code{bsp_sysinfo} when the
@var{id} is @code{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.
@example

err = bsp_sysinfo(BSP_INFO_PLATFORM,
                  struct bsp_platform_info *@var{result});

@end example
A zero return value indicates success, a -1 indicates that this query
is not supported. If successful, the @var{result} structure is filled
out with the platform information.

@tindex bsp_platform_info
@subsubsection @code{bsp_platform_info}
@example
struct bsp_platform_info @{
  const char *cpu;
  const char *board;
  const char *extra;
@}

@end example
@strong{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 @code{bsp_sysinfo}.
@example

struct bsp_platform_info _bsp_platform_info = @{
    "Unknown",  /* cpu name */
    "Unknown",  /* board name */
    ""          /* extra */
@};

@end example
It is the responsibility of board or architecure specific code to modify
these default values.


@node Cache Info, Memory Info, Platform Info, bsp_sysinfo
@subsection Cache Info
Information is provided for instruction, data, and secondary caches.
@code{bsp_sysinfo} may be passed an @var{id} of @code{BSP_INFO_DCACHE},
@code{BSP_INFO_ICACHE}, and @code{BSP_INFO_SCACHE}.
@example

err = bsp_sysinfo(BSP_INFO_DCACHE,
                  struct bsp_cache_info *@var{result});

@end example
A zero return value indicates success, a -1 indicates that the cache
info is not supported. If successful, the @var{result} structure is filled
out with the cache information.

@tindex bsp_cache_info
@subsubsection @code{bsp_cache_info}
@example
struct bsp_cachesize_info @{
  int   size;
  short linesize;
  short ways;
@}

@end example
@strong{Description}@*
This structure contains information about cache layout. @code{size} is the total
size in bytes, @code{linesize} is the width of a cache line in bytes, and
@code{ways} is the number of ways per line. The BSP declares global variables
to the hold the default values returned by @code{bsp_sysinfo}.
@example

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
@};

@end example
It is the responsibility of board or architecure specific code to modify
these default values.


@node Memory Info, Comm Info, Cache Info, bsp_sysinfo
@subsection Memory Info
The @code{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.
@example

err = bsp_sysinfo(BSP_INFO_MEMORY,
                  int index,
                  struct bsp_mem_info *result)

@end example
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.

@tindex bsp_mem_info
@subsubsection @code{bsp_mem_info}
@example
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
@}

@end example
@strong{Description}@*
The @var{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 @code{bsp_mem_info} structures and an integer variable
indicating the number of elements in the array:
@example

/*
 * 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;

@end example

@node Comm Info, , Memory Info, bsp_sysinfo
@subsection Comm Info
The BSP may provide a variable number of communication channels. The
@code{bsp_sysinfo} interface provides a mechanism to get information
about the number and kinds of communication channels.
@example

err = bsp_sysinfo(BSP_INFO_COMM,
                  int index,
                  struct bsp_comm_info *result)

@end example
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. @xref{bsp_comm_info}


@node Debug Support, Miscellaneous API, System Information, Top
@chapter 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::
@end menu


@node Singlestep, Registers, Debug Support, Debug Support
@section Singlestep

@findex bsp_singlestep_setup
@subsection @code{bsp_singlestep_setup}
@strong{Synopsis}
@example
void
bsp_singlestep_setup(void *@var{saved_regs})

@end example
@strong{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 @code{bsp_singlestep_setup} just prior to
returning. The debug exception handler would then regain control after
a single instruction was executed.

@findex bsp_singlestep_cleanup
@subsection @code{bsp_singlestep_cleanup}
@strong{Synopsis}
@example
void
bsp_singlestep_cleanup(void *@var{saved_regs})

@end example
@strong{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 @code{bsp_singlestep_setup}. This routine
must be safe to call even if @code{bsp_singlestep_setup} was not
called previously.

@node Registers, Debug Events, Singlestep, Debug Support
@section 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.

@findex bsp_numregs
@subsection @code{bsp_numregs}
@strong{Synopsis}
@example
int
bsp_numregs(void)

@end example
@strong{Description}@*

@findex bsp_regbyte
@subsection @code{bsp_regbyte}
@strong{Synopsis}
@example
int
bsp_regbyte(int @var{regno})

@end example
@strong{Description}@*
Returns the offset in bytes of the given register from the start of
the saved register area.

@findex bsp_regsize
@subsection @code{bsp_regsize}
@strong{Synopsis}
@example
int
bsp_regsize(int @var{regno})

@end example
@strong{Description}@*
Returns the size in bytes of the given register.

@findex bsp_set_register
@subsection @code{bsp_set_register}
@strong{Synopsis}
@example
void
bsp_set_register(int  @var{regno},
                 void *@var{saved_regs},
                 void *@var{val})

@end example
@strong{Description}@*
Sets the value of register @var{regno} saved in an exception frame pointed
to by @var{saved_regs}. The value is copied byte by byte from value buffer
pointed to by @var{val}. A default version of this routine is provided by
the generic code. This generic version is based simply on @code{bsp_regbyte}
and @code{bsp_regsize}.

@findex bsp_get_register
@subsection @code{bsp_get_register}
@strong{Synopsis}
@example
void
bsp_get_register(int  @var{regno},
                 void *@var{saved_regs},
                 void *@var{val})

@end example
@strong{Description}@*
Gets the value of register @var{regno} saved in an exception frame pointed
to by @var{saved_regs}. The value is copied byte by byte from exception
frame to value buffer pointed to by @var{val}. A default version of this
routine is provided by the generic code. This generic version is based
simply on @code{bsp_regbyte} and @code{bsp_regsize}.


@node Debug Events, Memory, Registers, Debug Support
@section 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:

@findex bsp_get_signal
@subsection @code{bsp_get_signal}
@strong{Synopsis}
@example
int
bsp_get_signal(int  @var{exception_number},
               void *@var{saved_regs})

@end example
@strong{Description}@*
Returns the reason why the debug agent was invoked. The currently supported
return values are a subset of those expected by GDB:

@table @code
@item TARGET_SIGNAL_INT
Program was interrupted.
@item TARGET_SIGNAL_ILL
Illegal instruction opcode.
@item TARGET_SIGNAL_TRAP
Breakpoint or watchpoint.
@item TARGET_SIGNAL_ABRT
@item TARGET_SIGNAL_FPE
Divide-by-zero or other math error.
@item TARGET_SIGNAL_BUS
Bus error.
@item TARGET_SIGNAL_SEGV
Invalid memory access.
@end table

@findex bsp_breakpoint
@subsection @code{bsp_breakpoint}
@strong{Synopsis}
@example
void
bsp_breakpoint(void);

@end example
@strong{Description}@*
Causes a breakpoint exception.

@node Memory, , Debug Events, Debug Support
@section 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.

@findex bsp_memory_read
@subsection @code{bsp_memory_read}
@strong{Synopsis}
@example
int
bsp_memory_read(void *@var{addr},
                int  @var{asid},
                int  @var{rsize},
                int  @var{nreads},
                void *@var{buf});

@end example
@strong{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 @var{nreads} read operations with
each operation being of @var{rsize} bits. The memory is read from @var{addr}
and the results are placed in @var{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 @var{asid} is used to specify the address space. The
interpretation of @var{asid} is architecture dependent, although a value of
-1 will indicate @samp{default}.


@findex bsp_memory_write
@subsection @code{bsp_memory_write}
@strong{Synopsis}
@example
int
bsp_memory_write(void *@var{addr},
                 int  @var{asid},
                 int  @var{wsize},
                 int  @var{nwrites},
                 void *@var{buf});

@end example
@strong{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 @var{nwrites} write operations with
each operation being of @var{wsize} bits. The data to write is taken from
@var{buf} and written to @var{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 @var{asid} is used to specify the address space. The
interpretation of @var{asid} is architecture dependent, although a value of -1
will indicate @samp{default}.


@node Miscellaneous API, BSP Porting, Debug Support, Top
@chapter Miscellaneous Interfaces

@menu
* Formatted Output::
* Shared Memory::
* Caches::
@end menu

@node Formatted Output, Shared Memory, Miscellaneous API, Miscellaneous API
@section 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::
@end menu 

@node bsp_printf, bsp_dprintf, Formatted Output, Formatted Output
@findex bsp_printf
@subsection @code{bsp_printf}
@strong{Synopsis}
@example
void
bsp_printf(const char *@var{fmt}, @var{...})

@end example
@strong{Description}@*
A stripped down, integer only version of libc @code{printf}. Output is
sent to the console channel.

@node bsp_dprintf, bsp_sprintf, bsp_printf, Formatted Output
@findex bsp_dprintf
@subsection @code{bsp_dprintf}
@strong{Synopsis}
@example
void
bsp_dprintf(const char *@var{fmt},
            @var{...})

@end example
@strong{Description}@*
A stripped down, integer only version of libc @code{printf}. Output is
sent to the debug channel.

@node bsp_sprintf, bsp_vsprintf, bsp_dprintf, Formatted Output
@findex bsp_sprintf
@subsection @code{bsp_sprintf}
@strong{Synopsis}
@example
void
bsp_sprintf(char       *@var{str},
            const char *@var{fmt},
            @var{...})

@end example
@strong{Description}@*
A stripped down, integer only version of libc @code{sprintf}.

@node bsp_vsprintf, , bsp_sprintf, Formatted Output
@findex bsp_vsprintf
@subsection @code{bsp_vsprintf}
@strong{Synopsis}
@example
void
bsp_vsprintf(char       *@var{str},
             const char *@var{fmt},
             va_list    @var{ap})

@end example
@strong{Description}@*
A stripped down, integer only version of libc @code{vsprintf}.


@node Shared Memory, Caches, Formatted Output, Miscellaneous API
@section 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.

@tindex bsp_shared_t
@tindex bsp_shared_data
@subsection @code{bsp_shared_t}
@example
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;

@end example
@strong{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 (@code{bsp_shared_data}).


@node Caches, , Shared Memory, Miscellaneous API
@section 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.

@findex bsp_flush_dcache
@subsection @code{bsp_flush_dcache}
@strong{Synopsis}
@example
void
bsp_flush_dcache(void *@var{p},
                 int  @var{nbytes})

@end example
@strong{Description}@*
Write back and invalidate data cache lines in the range of @var{p} to 
(@var{p} + @var{nbytes}). If @var{nbytes} is -1, then flush entire cache.


@findex bsp_flush_icache
@subsection @code{bsp_flush_icache}
@strong{Synopsis}
@example
void
bsp_flush_icache(void *@var{p},
                 int  @var{nbytes})

@end example
@strong{Description}@*
Invalidate instruction cache lines in the range of @var{p} to
(@var{p} + @var{nbytes}).


@findex bsp_reset
@subsection @code{bsp_reset}
@strong{Synopsis}
@example
void
bsp_reset(void)

@end example
@strong{Description}@*
Reset the board.  If the board does not have a mechanism to allow
a software reset then this function does nothing.





@node BSP Porting, , Miscellaneous API, Top
@chapter BSP Porting

@section New Architectures

@subsection Configuration

The BSP uses @samp{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 @file{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:

@example
ARCHITECTURE-VENDOR-OS
@end example

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

@table @code
@item archdir
This specifies the name of the architecture specific directory.
@item boards
This is a space separated list of board specific directories which are located
within the architecture specific directory.
@item 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.
@end table


@subsection Makefile Fragment
Every architecture port must include a makefile fragment named @file{cpu.mk}
in the architecture specific directory. This makefile fragment should contain
definitions for the following variables:

@table @code
@item 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
@file{BUILD_TCP}, which should be appended to this variable if ethernet based
debugging is to be enabled.
@item CPU_SRCDIR
This is the subdirectory containing the CPU specific sources.  This is
generally set to @file{top_srcdir/archdir}
@item CPU_INCDIR
This is the subdirectory containing the CPU specific headers.  This is
generally set to @file{$(CPU_SRCDIR)/include}
@item 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 @file{$(CPU_INCDIR)}.
@item CPU_OBJS
This is a list of object files which should be included in all BSP libraries
based on this architecture.
@item CPU_CFLAGS
Compiler flags which are common to all board ports based on this architecture.
@item CPU_LDFLAGS
Linker flags which are common to all board ports based on this architecture.
@item CPU_DEFINES
Preprocessor defines which are common to all board ports based on this architecture.
@end table

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

@subsection Required Files

@table @file
@item include/gdb-cpu.h
This file must define @code{NUMREGS} to be the number of registers expected by
the hostside GDB debugger.
@item include/bsp/cpu.h
Architecture specific header which must provide several items.
@end table

@subsection Required Data and Code

@table @code
@end table

@section New Boards
@subsection Configuration
The first step to porting to a new board is to add that board to the
configuration. This is done in the @file{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 @samp{fooppc} to the list of boards
for @code{powerpc-eabi} builds. Looking in @file{configure.in}, you will see
some code which looks like:

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

@end example

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

@subsection Makefile Fragment
Every board port must include a makefile fragment named @file{board.mk} in the
board specific directory. This makefile fragment should contain definitions for
the following variables:

@table @code
@item 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
@file{BUILD_TCP}, which should be appended to this variable if ethernet based
debugging is to be enabled.
@item BOARD_NAME
This is the name of the board.  Generally this will be the same as the
subdirectory containing the board specific sources.
@item BOARD_SRCDIR
This is the subdirectory containing the board specific sources.  This is
generally set to @file{top_srcdir/archdir/$(BOARD_NAME)}
@item BOARD_INCDIR
This is the subdirectory containing the board specific headers.  This is
generally set to @file{$(BOARD_SRCDIR)/include}
@item 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 @file{$(BOARD_INCDIR)}.
@item 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 @file{lib$(BOARD_NAME).a}
@item BOARD_OBJS
This is a list of board specific object files which should be included in the
BSP library.
@item BOARD_CFLAGS
Compiler flags for this particular board port.
@item BOARD_LDFLAGS
Linker flags for this particular board port.
@item BOARD_DEFINES
Preprocessor defines for this particular board port.
@item 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.
@item BOARD_SPECS
@itemx BOARD_RAM_SPECS
These are the names of the specs file fragments used during compiling
and linking applications for ROM or RAM respectively.
@item BOARD_ROM_STARTUP
@itemx 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
@file{gcc} by the specs file and should not be included in the BSP
library.
@item BOARD_EXTRAS
Any extra files that need to be built for a given board should be listed
here.
@item BOARD_EXTRA_LIBS
Any extra files that need to be installed into the library path should
be listed here.
@item BOARD_CLEAN
Any extra intermediate files that should be removed on @file{make clean}.
@end table

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

@subsection 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.

@subsection 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
@code{_bsp_init_stack} routine. @xref{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:

@table @code
@item _bsp_comm_list
@xref{_bsp_comm_list}
@item _bsp_num_comms
@xref{_bsp_num_comms}.
@item _bsp_memory_list
@itemx _bsp_num_mem_regions
@xref{Memory Info}
@code{_bsp_memory_list}.
@item _bsp_init_board_comm
@xref{_bsp_init_board_comm}.
@item _bsp_install_board_irq_controllers
@xref{_bsp_install_board_irq_controllers}.
@item _bsp_board_init
@xref{_bsp_board_init}
@end table

@tex
% I think something like @colophon should be in texinfo.  In the
% meantime:
\long\def\colophon{\hbox to0pt{}\vfill
\centerline{The body of this manual is set in}
\centerline{\fontname\tenrm,}
\centerline{with headings in {\bf\fontname\tenbf}}
\centerline{and examples in {\tt\fontname\tentt}.}
\centerline{{\it\fontname\tenit\/},}
\centerline{{\bf\fontname\tenbf}, and}
\centerline{{\sl\fontname\tensl\/}}
\centerline{are used for emphasis.}\vfill}
\page\colophon
@end tex

@contents
@bye
