7da71e5f9e
Add support for i386 debugging and pci-based ne2000 boards.
173 lines
6.2 KiB
Plaintext
173 lines
6.2 KiB
Plaintext
$NetBSD: README.port,v 1.3 2000/03/22 20:58:29 ws 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 existance 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.
|