$NetBSD: README.port,v 1.4 2006/11/24 22:52:16 wiz Exp $

What to Look for when Porting the IPKDB Interface
===============================================

Try to avoid calling any routine from the rest of the kernel.
(It's OK to call these routines during initialization).
You wouldn't be able to set breakpoints within these routines
during debugging, since this would hang the debugging interface.


Interface between IPKDB and Ethernet Board (sys/dev/yy/if_xx.c)
--------------------------------------------------------------

General Considerations


There is a problem when the debugger uses the same ethernet board as
does the rest of the kernel.  For one thing there might arrive packets
destined for the kernel during debugging sessions.  These packets
are currently lost.  For packets on their way out the driver has
to leave the interrupt pending condition alone, so the interrupt
handler gets a chance to send more packets via the interface.


Configuration Files


For any interface that may be used for debugging there should be
an option, put into opt_ipkdb.h, that is enabled if the kernel
shall actually use this interface.  The relevant part of the
"files" file for interface "xx" would look like this:

	defopt	opt_ipkdb.h	IPKDB_XX	: IPKDB
	device	xx: ether, ifnet, arp
	file	dev/zz/if_xx.c		xx | ipkdb_xx

The file dev/zz/if_xx.c contains both the code of the kernel
driver and the IPKDB driver for this interface.  You should
#include "opt_ipkdb.h" in there and conditionalize the
compilation of the IPKDB driver with
#ifdef IPKDB_XX

The appropriate part of the machine configuration would read like
this:

	options 	IPKDBKEY="\"IPKDB key for remote debugging\""
	options 	IPKDB_XX


Driver Code


In order to be able to find the debugging interface, the driver
has to provide an attach routine that the machine dependent code
can call at an appropriate time (see below).  The attach routine
should take as its first argument a pointer to a struct ipkdb_if
plus some additional parameters that allow it to access the
devices registers, hopefully using bus_space_* methods.
In the ipkdb_if structure, the attach routine must initialize
the following fields:

	myenetaddr	fill this with the own ethernet address of
			the device/machine.
	flags		mark at least IPKDB_MYHW here.
	name		Name of the device, only used for a message.
	start		routine called everytime IPKDB is entered.
	leave		routine called everytime IPKDB is left.
	receive		routine called to receive a packet.
	send		routine called to send a packet.

Additional fields that may be set are:

	myinetaddr	fill this with the own internet address,
			and mark IPKDB_MYIP in flags.
	port		may be used as a pointer to some device
			dependent data.  Unused by other code.

The routine should check for existence of the ethernet board.
This routine should also note enough information so it is able
to later find the system driver instance for the same board in
order to coordinate its action with the system driver.

The routine should return 0 on success and -1 on failure.

The remainder of the routines are called via function pointers
in the ipkdb_if structure.  The probe routine needs to fill in
these function pointers with proper values.

void start(struct ipkdb_if *kip)

This routine gets called every time the debugger is entered.
kip is a pointer to the ipkdb_if structure used for debugging.

It should initialize the hardware and software interface.

This routine should also note the current state of the board
(as far as it can) so a later call to leave can reinstantiate
this state.

void leave(struct ipkdb_if *kip)

This routine is called whenever the debugger is left.  It should
restore the ethernet hardware to the state prior to the last call to
start.

int receive(struct ipkdb_if *kip, u_char *buf, int poll)

This routine should return an ethernet packet to the buffer pointed to
by buf and return its length.  The packet should be complete with the
ethernet header, i.e. it starts with the recipient address, but does not
contain the ethernet checksum.

If poll is set, it should return immediately, if no packet is available.
Otherwise it should wait for the next packet.

This routine shall return the number of bytes transferred to buf.

void send(struct ipkdb_if *kip, u_char *buf, int l)

This routine should send an ethernet packet out of the debugging
interface.  The packet is already complete with the ethernet header,
but does not contain the ethernet checksum.


Interface between IPKDB and Machine (sys/arch/xxx/xxx/ipkdb_glue.c)
-----------------------------------------------------------------


void ipkdbinit(void)

This routine gets called when the debugger should be entered for the
first time.

int ipkdb_poll(void)

This routine gets called after a panic to check for a keypress by the user.
If implemented it allows the user to press any key on the console to do
the automatic reboot after a panic.  Otherwise the debugging interface
will wait forever for some remote debugger to attach in case of a panic.

int ipkdbcmds(void)

There should be call to this routine from somewhere in locore when the
trap mechanism determines that the debugger should be entered, i.e. on
a single step or breakpoint interrupt from kernel code.  The trapping
mechanism should already have stored the registers into the global area
ipkdbregs.  The layout of this area must be the same as that expected
by GDB.  The return value of this routine is 0, if the user wants to
continue, 1 if the user wants to do single stepping, and 2 if the user
has detached from debugging.

int ipkdbfbyte(u_char *p)

This routine should fetch a byte from address p. It must not enter any
trap handling code, but instead return -1 on inability to access the data.

void ipkdbsbyte(u_char *p,u_char c)

This routine should set the byte pointed to by p to the value given as c.
The routine must not enter any trap handling code.  Furthermore it should
reset the modification bit in the relevant page table entry to the value
before the store.


sys/arch/xxx/include/ipkdb.h


Machine dependent definitions and protoypes should be in
sys/arch/xxx/include/ipkdb.h, i.e. in <machine/ipkdb.h>.  This includes
the size of the array ipkdbregs, that holds the contents of the registers
of the debuggee at the time IPKDB is entered.
