summaryrefslogtreecommitdiff
path: root/sys/arch/i386/stand/libsa
diff options
context:
space:
mode:
authorTom Cosgrove <tom@cvs.openbsd.org>2004-03-19 13:48:21 +0000
committerTom Cosgrove <tom@cvs.openbsd.org>2004-03-19 13:48:21 +0000
commit96c309c384e99b742c4307ece38772c4841ffad2 (patch)
treecdeec8f47d46f4ab706d96f40f448bd51c1ea38b /sys/arch/i386/stand/libsa
parent4700fd56f6db1ac60a4bef5eb9c8a0b7451a19d7 (diff)
Enter pxeboot, derived from the NetBSD implementation. Initially
intended to support network installs using bsd.rd over TFTP. Thanks to the many who tested, including Diana Eichert. ok deraadt@
Diffstat (limited to 'sys/arch/i386/stand/libsa')
-rw-r--r--sys/arch/i386/stand/libsa/Makefile6
-rw-r--r--sys/arch/i386/stand/libsa/diskprobe.c5
-rw-r--r--sys/arch/i386/stand/libsa/exec_i386.c5
-rw-r--r--sys/arch/i386/stand/libsa/gateA20.c12
-rw-r--r--sys/arch/i386/stand/libsa/gidt.S10
-rw-r--r--sys/arch/i386/stand/libsa/gidt.h35
-rw-r--r--sys/arch/i386/stand/libsa/libsa.h16
-rw-r--r--sys/arch/i386/stand/libsa/machdep.c44
-rw-r--r--sys/arch/i386/stand/libsa/ps2probe.c (renamed from sys/arch/i386/stand/libsa/ps2probe.h)8
-rw-r--r--sys/arch/i386/stand/libsa/pxe.c547
-rw-r--r--sys/arch/i386/stand/libsa/pxe.h528
-rw-r--r--sys/arch/i386/stand/libsa/pxe_call.S202
-rw-r--r--sys/arch/i386/stand/libsa/pxe_net.c184
-rw-r--r--sys/arch/i386/stand/libsa/pxe_net.h44
-rw-r--r--sys/arch/i386/stand/libsa/pxe_netif.h43
-rw-r--r--sys/arch/i386/stand/libsa/pxeboot.h53
16 files changed, 1699 insertions, 43 deletions
diff --git a/sys/arch/i386/stand/libsa/Makefile b/sys/arch/i386/stand/libsa/Makefile
index 23a372f994d..1a435b2c74a 100644
--- a/sys/arch/i386/stand/libsa/Makefile
+++ b/sys/arch/i386/stand/libsa/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.42 2003/08/08 07:38:45 deraadt Exp $
+# $OpenBSD: Makefile,v 1.43 2004/03/19 13:48:18 tom Exp $
.include "${.CURDIR}/../Makefile.inc"
@@ -22,7 +22,7 @@ CLEANFILES+= gidt.o debug_i386.o alloca.o \
SRCS+= gidt.S debug_i386.S alloca.S \
biosdev.c bioscons.c gateA20.c apmprobe.c \
memprobe.c diskprobe.c pciprobe.c smpprobe.c \
- time.c biosprobe.c
+ time.c biosprobe.c ps2probe.c pxe.c pxe_net.c pxe_call.S
CLEANFILES+= unixdev.o unixsys.o nullfs.o
.endif
@@ -42,7 +42,7 @@ SRCS+= arp.c ether.c in_cksum.c net.c netif.c rpc.c
SRCS+= bootp.c bootparam.c rarp.c
# boot filesystems
-SRCS+= ufs.c nfs.c cd9660.c
+SRCS+= ufs.c nfs.c tftp.c cd9660.c
# debugger
SRCS+= debug.c
diff --git a/sys/arch/i386/stand/libsa/diskprobe.c b/sys/arch/i386/stand/libsa/diskprobe.c
index b2bbf03a091..27cc00c7d47 100644
--- a/sys/arch/i386/stand/libsa/diskprobe.c
+++ b/sys/arch/i386/stand/libsa/diskprobe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: diskprobe.c,v 1.25 2004/03/09 19:12:13 tom Exp $ */
+/* $OpenBSD: diskprobe.c,v 1.26 2004/03/19 13:48:18 tom Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
@@ -171,7 +171,6 @@ diskprobe(void)
bios_diskinfo_t *bios_diskinfo;
/* Init stuff */
- printf("disk:");
TAILQ_INIT(&disklist);
/* Do probes */
@@ -203,8 +202,6 @@ diskprobe(void)
addbootarg(BOOTARG_CKSUMLEN, sizeof(u_int32_t), &bios_cksumlen);
addbootarg(BOOTARG_DISKINFO, i * sizeof(bios_diskinfo_t),
bios_diskinfo);
-
- printf("\n");
}
diff --git a/sys/arch/i386/stand/libsa/exec_i386.c b/sys/arch/i386/stand/libsa/exec_i386.c
index 2274278b864..d4ce2e33d02 100644
--- a/sys/arch/i386/stand/libsa/exec_i386.c
+++ b/sys/arch/i386/stand/libsa/exec_i386.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: exec_i386.c,v 1.29 2004/03/09 19:12:13 tom Exp $ */
+/* $OpenBSD: exec_i386.c,v 1.30 2004/03/19 13:48:18 tom Exp $ */
/*
* Copyright (c) 1997-1998 Michael Shalayeff
@@ -54,6 +54,9 @@ run_loadfile(u_long *marks, int howto)
bios_consdev_t cd;
extern int com_speed; /* from bioscons.c */
+ if (sa_cleanup != NULL)
+ (*sa_cleanup)();
+
cd.consdev = cn_tab->cn_dev;
cd.conspeed = com_speed;
addbootarg(BOOTARG_CONSDEV, sizeof(cd), &cd);
diff --git a/sys/arch/i386/stand/libsa/gateA20.c b/sys/arch/i386/stand/libsa/gateA20.c
index 38b592bb4df..00bfad10613 100644
--- a/sys/arch/i386/stand/libsa/gateA20.c
+++ b/sys/arch/i386/stand/libsa/gateA20.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gateA20.c,v 1.9 2003/08/11 06:23:09 deraadt Exp $ */
+/* $OpenBSD: gateA20.c,v 1.10 2004/03/19 13:48:18 tom Exp $ */
/*
* Ported to boot 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
@@ -43,6 +43,16 @@
/*
+ * "Probe"-style routine (no parameters) to turn A20 on
+ */
+void
+gateA20on(void)
+{
+ gateA20(1);
+}
+
+
+/*
* Gate A20 for high memory
*/
void
diff --git a/sys/arch/i386/stand/libsa/gidt.S b/sys/arch/i386/stand/libsa/gidt.S
index e0810e8569b..f4a51db396a 100644
--- a/sys/arch/i386/stand/libsa/gidt.S
+++ b/sys/arch/i386/stand/libsa/gidt.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: gidt.S,v 1.27 2004/01/13 23:54:07 millert Exp $ */
+/* $OpenBSD: gidt.S,v 1.28 2004/03/19 13:48:18 tom Exp $ */
/*
* Copyright (c) 1997 Michael Shalayeff
@@ -36,11 +36,7 @@
#undef _LOCORE
#include <assym.h>
-#define SNULL 0x00
-#define S32TEXT 0x08
-#define S32DATA 0x10
-#define S16TEXT 0x18
-#define S16DATA 0x20
+#include "gidt.h"
#ifdef GIDT_DEBUG
#define gidt_debug0 ; \
@@ -204,11 +200,13 @@ idt:
idtb(36); idtb(37); idtb(38); idtb(39); idtb(40); idtb(41)
idtb(42); idtb(43); idtb(44); idtb(45); idtb(46); idtb(47)
#undef idte
+ .globl Idtr
Idtr: .word . - idt - 1
.long idt
.word 0
.align 8
+ .globl Idtr_real
Idtr_real: .word 1023
.long 0
.word 0
diff --git a/sys/arch/i386/stand/libsa/gidt.h b/sys/arch/i386/stand/libsa/gidt.h
new file mode 100644
index 00000000000..457709674c1
--- /dev/null
+++ b/sys/arch/i386/stand/libsa/gidt.h
@@ -0,0 +1,35 @@
+/* $OpenBSD: gidt.h,v 1.1 2004/03/19 13:48:18 tom Exp $ */
+
+/*
+ * Copyright (c) 2004 Tom Cosgrove
+ * Copyright (c) 1997 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#define SNULL 0x00
+#define S32TEXT 0x08
+#define S32DATA 0x10
+#define S16TEXT 0x18
+#define S16DATA 0x20
diff --git a/sys/arch/i386/stand/libsa/libsa.h b/sys/arch/i386/stand/libsa/libsa.h
index 4fec71c0b44..f2cae0987f1 100644
--- a/sys/arch/i386/stand/libsa/libsa.h
+++ b/sys/arch/i386/stand/libsa/libsa.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: libsa.h,v 1.38 2003/06/03 20:22:12 mickey Exp $ */
+/* $OpenBSD: libsa.h,v 1.39 2004/03/19 13:48:18 tom Exp $ */
/*
* Copyright (c) 1996-1999 Michael Shalayeff
@@ -33,9 +33,19 @@
#define DEFAULT_KERNEL_ADDRESS 0
+struct i386_boot_probes {
+ char *name;
+ void (**probes)(void);
+ int count;
+};
+
+extern void (*sa_cleanup)(void);
+
void gateA20(int);
+void gateA20on(void);
void smpprobe(void);
+void ps2probe(void);
void pciprobe(void);
void memprobe(void);
void diskprobe(void);
@@ -57,6 +67,10 @@ extern const int nbdevs;
extern u_int cnvmem, extmem; /* XXX global pass memprobe()->machdep_start() */
extern int ps2model;
+extern struct i386_boot_probes probe_list[];
+extern int nibprobes;
+extern void (*devboot_p)(dev_t, char *);
+
/* diskprobe.c */
extern bios_diskinfo_t bios_diskinfo[];
extern u_int32_t bios_cksumlen;
diff --git a/sys/arch/i386/stand/libsa/machdep.c b/sys/arch/i386/stand/libsa/machdep.c
index d74c043a68a..5dc8cf90680 100644
--- a/sys/arch/i386/stand/libsa/machdep.c
+++ b/sys/arch/i386/stand/libsa/machdep.c
@@ -1,6 +1,7 @@
-/* $OpenBSD: machdep.c,v 1.34 2003/08/11 06:23:09 deraadt Exp $ */
+/* $OpenBSD: machdep.c,v 1.35 2004/03/19 13:48:18 tom Exp $ */
/*
+ * Copyright (c) 2004 Tom Cosgrove
* Copyright (c) 1997-1999 Michael Shalayeff
* All rights reserved.
*
@@ -29,8 +30,6 @@
#include "libsa.h"
#include <machine/apmvar.h>
#include <machine/biosvar.h>
-#include "debug.h"
-#include "ps2probe.h"
volatile struct BIOS_regs BIOS_regs;
@@ -40,30 +39,25 @@ volatile struct BIOS_regs BIOS_regs;
#define CKPT(c) /* c */
#endif
-extern int debug;
-int ps2model;
-
void
machdep(void)
{
- /* here */ CKPT('0');
- printf("probing:");
-#ifndef _TEST
- /* probe for a model number, gateA20() neds ps2model */
- ps2probe(); CKPT('1');
- gateA20(1); CKPT('2');
- debug_init(); CKPT('3');
-#endif
- /* call console init before doing any io */
- cninit(); CKPT('4');
-#ifndef _TEST
- apmprobe(); CKPT('5');
- pciprobe(); CKPT('6');
-/* smpprobe(); CKPT('7'); */
- memprobe(); CKPT('8');
- printf("\n");
+ int i, j;
+ struct i386_boot_probes *pr;
- diskprobe(); CKPT('9');
-#endif
- CKPT('Z');
+ /*
+ * The list of probe routines is now in conf.c.
+ */
+ for (i = 0; i < nibprobes; i++) {
+ pr = &probe_list[i];
+ if (pr != NULL) {
+ printf("%s:", pr->name);
+
+ for (j = 0; j < pr->count; j++) {
+ (*(pr->probes)[j])();
+ }
+
+ printf("\n");
+ }
+ }
}
diff --git a/sys/arch/i386/stand/libsa/ps2probe.h b/sys/arch/i386/stand/libsa/ps2probe.c
index 78018bd1a83..898fe5cf54f 100644
--- a/sys/arch/i386/stand/libsa/ps2probe.h
+++ b/sys/arch/i386/stand/libsa/ps2probe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ps2probe.h,v 1.3 2003/06/03 20:22:12 mickey Exp $ */
+/* $OpenBSD: ps2probe.c,v 1.1 2004/03/19 13:48:18 tom Exp $ */
/*
* Copyright (c) 2001 Michael Shalayeff
@@ -26,7 +26,11 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-static __inline void
+#include "libsa.h"
+
+int ps2model;
+
+void
ps2probe(void)
{
char *p;
diff --git a/sys/arch/i386/stand/libsa/pxe.c b/sys/arch/i386/stand/libsa/pxe.c
new file mode 100644
index 00000000000..b159b51f5dc
--- /dev/null
+++ b/sys/arch/i386/stand/libsa/pxe.c
@@ -0,0 +1,547 @@
+/* $OpenBSD: pxe.c,v 1.1 2004/03/19 13:48:18 tom Exp $ */
+/* $NetBSD: pxe.c,v 1.5 2003/03/11 18:29:00 drochner Exp $ */
+
+/*
+ * Copyright 2001 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2000 Alfred Perlstein <alfred@freebsd.org>
+ * All rights reserved.
+ * Copyright (c) 2000 Paul Saab <ps@freebsd.org>
+ * All rights reserved.
+ * Copyright (c) 2000 John Baldwin <jhb@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Support for the Intel Preboot Execution Environment (PXE).
+ *
+ * PXE provides a UDP implementation as well as a UNDI network device
+ * driver. UNDI is much more complicated to use than PXE UDP, so we
+ * use PXE UDP as a cheap and easy way to get PXE support.
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#ifdef _STANDALONE
+#include <lib/libkern/libkern.h>
+#else
+#include <string.h>
+#endif
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+
+#include <lib/libsa/stand.h>
+#include <lib/libsa/net.h>
+#include <lib/libsa/bootp.h>
+
+#include "pxeboot.h"
+#include "pxe.h"
+#include "pxe_netif.h"
+
+void (*pxe_call)(u_int16_t);
+
+void pxecall_bangpxe(u_int16_t); /* pxe_call.S */
+void pxecall_pxenv(u_int16_t); /* pxe_call.S */
+
+char pxe_command_buf[256];
+
+BOOTPLAYER bootplayer;
+
+struct in_addr servip; /* for tftp */ /* XXX init this */
+
+/* static struct btinfo_netif bi_netif; */
+
+/*****************************************************************************
+ * This section is a replacement for libsa/udp.c
+ *****************************************************************************/
+
+/* Caller must leave room for ethernet, ip, and udp headers in front!! */
+ssize_t
+pxesendudp(struct iodesc *d, void *pkt, size_t len)
+{
+ t_PXENV_UDP_WRITE *uw = (void *) pxe_command_buf;
+
+ uw->status = 0;
+
+ uw->ip = d->destip.s_addr;
+ uw->gw = gateip.s_addr;
+ uw->src_port = d->myport;
+ uw->dst_port = d->destport;
+ uw->buffer_size = len;
+ uw->buffer.segment = VTOPSEG(pkt);
+ uw->buffer.offset = VTOPOFF(pkt);
+
+ pxe_call(PXENV_UDP_WRITE);
+
+ if (uw->status != PXENV_STATUS_SUCCESS) {
+ /* XXX This happens a lot; it shouldn't. */
+ if (uw->status != PXENV_STATUS_FAILURE)
+ printf("sendudp: PXENV_UDP_WRITE failed: 0x%x\n",
+ uw->status);
+ return -1;
+ }
+
+ return len;
+}
+
+/*
+ * Receive a UDP packet and validate it for us.
+ * Caller leaves room for the headers (Ether, IP, UDP).
+ */
+ssize_t
+pxereadudp(struct iodesc *d, void *pkt, size_t len, time_t tleft)
+{
+ t_PXENV_UDP_READ *ur = (void *) pxe_command_buf;
+ struct udphdr *uh;
+ struct ip *ip;
+
+ uh = (struct udphdr *)pkt - 1;
+ ip = (struct ip *)uh - 1;
+
+ bzero(ur, sizeof(*ur));
+
+ ur->dest_ip = d->myip.s_addr;
+ ur->d_port = d->myport;
+ ur->buffer_size = len;
+ ur->buffer.segment = VTOPSEG(pkt);
+ ur->buffer.offset = VTOPOFF(pkt);
+
+ /* XXX Timeout unused. */
+
+ pxe_call(PXENV_UDP_READ);
+
+ if (ur->status != PXENV_STATUS_SUCCESS) {
+ /* XXX This happens a lot; it shouldn't. */
+ if (ur->status != PXENV_STATUS_FAILURE)
+ printf("readudp: PXENV_UDP_READ_failed: 0x%0x\n",
+ ur->status);
+ return -1;
+ }
+
+ ip->ip_src.s_addr = ur->src_ip;
+ uh->uh_sport = ur->s_port;
+ uh->uh_dport = d->myport;
+
+ return ur->buffer_size;
+}
+
+/*
+ * netif layer:
+ * open, close, shutdown: called from dev_net.c
+ * socktodesc: called by network protocol modules
+ *
+ * We only allow one open socket.
+ */
+
+static int pxe_inited;
+static struct iodesc desc;
+
+int
+pxe_netif_open()
+{
+ t_PXENV_UDP_OPEN *uo = (void *) pxe_command_buf;
+
+#ifdef NETIF_DEBUG
+ printf("pxe_netif_open()\n");
+#endif
+ if (!pxe_inited) {
+ if (pxe_init(0) != 0)
+ return -1;
+ pxe_inited = 1;
+ }
+ /* BI_ADD(&bi_netif, BTINFO_NETIF, sizeof(bi_netif)); */
+
+ bzero(uo, sizeof(*uo));
+
+ uo->src_ip = bootplayer.yip;
+
+ pxe_call(PXENV_UDP_OPEN);
+
+ if (uo->status != PXENV_STATUS_SUCCESS) {
+ printf("pxe_netif_open: PXENV_UDP_OPEN failed: 0x%x\n",
+ uo->status);
+ return -1;
+ }
+
+ bcopy(bootplayer.CAddr, desc.myea, ETHER_ADDR_LEN);
+
+ /*
+ * Since the PXE BIOS has already done DHCP, make sure we
+ * don't reuse any of its transaction IDs.
+ */
+ desc.xid = bootplayer.ident;
+
+ return 0;
+}
+
+void
+pxe_netif_close(sock)
+ int sock;
+{
+ t_PXENV_UDP_CLOSE *uc = (void *) pxe_command_buf;
+
+#ifdef NETIF_DEBUG
+ if (sock != 0)
+ printf("pxe_netif_close: sock=%d\n", sock);
+#endif
+
+ uc->status = 0;
+
+ pxe_call(PXENV_UDP_CLOSE);
+
+ if (uc->status != PXENV_STATUS_SUCCESS)
+ printf("pxe_netif_end: PXENV_UDP_CLOSE failed: 0x%x\n",
+ uc->status);
+}
+
+void
+pxe_netif_shutdown()
+{
+#ifdef NETIF_DEBUG
+ printf("pxe_netif_shutdown()\n");
+#endif
+
+ pxe_shutdown();
+}
+
+struct iodesc *
+pxesocktodesc(sock)
+ int sock;
+{
+
+#ifdef NETIF_DEBUG
+ if (sock != 0)
+ return 0;
+ else
+#endif
+ return &desc;
+}
+
+/*****************************************************************************
+ * PXE initialization and support routines
+ *****************************************************************************/
+
+u_int16_t pxe_command_buf_seg;
+u_int16_t pxe_command_buf_off;
+
+extern u_int16_t bangpxe_off, bangpxe_seg;
+extern u_int16_t pxenv_off, pxenv_seg;
+
+/* static struct btinfo_netif bi_netif; */
+
+void
+pxeprobe(void)
+{
+ if (!pxe_inited) {
+ if (pxe_init(1) == 0) {
+ pxe_inited = 1;
+ }
+ }
+}
+
+int
+pxe_init(int quiet)
+{
+ t_PXENV_GET_CACHED_INFO *gci = (void *) pxe_command_buf;
+ pxenv_t *pxenv;
+ pxe_t *pxe;
+ char *cp;
+ int i;
+ u_int8_t cksum, *ucp;
+
+ /*
+ * Checking for the presence of PXE is a machine-dependent
+ * operation. On the IA-32, this can be done two ways:
+ *
+ * Int 0x1a function 0x5650
+ *
+ * Scan memory for the !PXE or PXENV+ signatures
+ *
+ * We do the latter, since the Int method returns a pointer
+ * to a deprecated structure (PXENV+).
+ */
+
+ pxenv = NULL;
+ pxe = NULL;
+
+ for (cp = (char *)0xa0000; cp > (char *)0x10000; cp -= 2) {
+ if (pxenv == NULL) {
+ pxenv = (pxenv_t *)cp;
+ if (memcmp(pxenv->Signature, S_SIZE("PXENV+")) != 0)
+ pxenv = NULL;
+ else {
+ for (i = 0, ucp = (u_int8_t *)cp, cksum = 0;
+ i < pxenv->Length; i++)
+ cksum += ucp[i];
+ if (cksum != 0) {
+ printf("\npxe_init: bad cksum (0x%x) "
+ "for PXENV+ at 0x%lx\n", cksum,
+ (u_long) cp);
+ pxenv = NULL;
+ }
+ }
+ }
+
+ if (pxe == NULL) {
+ pxe = (pxe_t *)cp;
+ if (memcmp(pxe->Signature, S_SIZE("!PXE")) != 0)
+ pxe = NULL;
+ else {
+ for (i = 0, ucp = (u_int8_t *)cp, cksum = 0;
+ i < pxe->StructLength; i++)
+ cksum += ucp[i];
+ if (cksum != 0) {
+ printf("pxe_init: bad cksum (0x%x) "
+ "for !PXE at 0x%lx\n", cksum,
+ (u_long) cp);
+ pxe = NULL;
+ }
+ }
+ }
+
+ if (pxe != NULL && pxenv != NULL)
+ break;
+ }
+
+ if (pxe == NULL && pxenv == NULL) {
+ if (!quiet) printf("pxe_init: No PXE BIOS found.\n");
+ return 1;
+ }
+
+ if (pxenv == NULL) {
+ /* assert(pxe != NULL); */
+
+ printf(quiet ? " pxe!" : "PXE present\n");
+ }
+ else { /* pxenv != NULL */
+ int bang = 0;
+
+ if (pxenv->Version >= 0x0201 && pxe != NULL) {
+ /* 2.1 or greater -- don't use PXENV+ */
+ bang = 1;
+ }
+
+ if (quiet) {
+ printf(" pxe%c[%d.%d]",
+ (bang ? '!' : '+'),
+ (pxenv->Version >> 8) & 0xff,
+ pxenv->Version & 0xff);
+ }
+ else {
+ printf("PXE BIOS Version %d.%d\n",
+ (pxenv->Version >> 8) & 0xff,
+ pxenv->Version & 0xff);
+ }
+
+ if (bang) {
+ pxenv = NULL;
+ }
+ }
+
+ if (pxe != NULL) {
+ pxe_call = pxecall_bangpxe;
+ bangpxe_off = pxe->EntryPointSP.offset;
+ bangpxe_seg = pxe->EntryPointSP.segment;
+ } else {
+ pxe_call = pxecall_pxenv;
+ pxenv_off = pxenv->RMEntry.offset;
+ pxenv_seg = pxenv->RMEntry.segment;
+ }
+
+ /*
+ * Pre-compute the segment/offset of the pxe_command_buf
+ * to make things nicer in the low-level calling glue.
+ */
+ pxe_command_buf_seg = VTOPSEG(pxe_command_buf);
+ pxe_command_buf_off = VTOPOFF(pxe_command_buf);
+
+ /*
+ * Get the cached info from the server's Discovery reply packet.
+ */
+ bzero(gci, sizeof(*gci));
+ gci->PacketType = PXENV_PACKET_TYPE_CACHED_REPLY;
+ pxe_call(PXENV_GET_CACHED_INFO);
+
+ if (gci->Status != PXENV_STATUS_SUCCESS) {
+ printf("\npxeinfo: PXENV_GET_CACHED_INFO failed: 0x%x\n",
+ gci->Status);
+ return 1;
+ }
+
+ memcpy(&bootplayer,
+ SEGOFF2FLAT(gci->Buffer.segment, gci->Buffer.offset),
+ gci->BufferSize);
+
+ bcopy(&bootplayer.yip, &myip.s_addr, sizeof(myip.s_addr));
+ bcopy(&bootplayer.sip, &servip.s_addr, sizeof(servip.s_addr));
+
+ /* Compute our "natural" netmask. */
+ if (IN_CLASSA(myip.s_addr))
+ netmask = IN_CLASSA_NET;
+ else if (IN_CLASSB(myip.s_addr))
+ netmask = IN_CLASSB_NET;
+ else
+ netmask = IN_CLASSC_NET;
+
+ return 0;
+}
+
+void
+pxeinfo(void)
+{
+ u_int8_t *p;
+#ifdef PXE_DEBUG
+ t_PXENV_UNDI_GET_NIC_TYPE *gnt = (void *) pxe_command_buf;
+#endif
+
+ printf(" mac %s", ether_sprintf(bootplayer.CAddr));
+ p = (u_int8_t *)&myip.s_addr;
+ printf(", ip %d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+ p = (u_int8_t *)&servip.s_addr;
+ printf(", server %d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+
+#ifdef PXE_DEBUG
+ /*
+ * Get network interface information.
+ */
+ bzero(gnt, sizeof(*gnt));
+ pxe_call(PXENV_UNDI_GET_NIC_TYPE);
+
+ if (gnt->Status != PXENV_STATUS_SUCCESS) {
+ printf("\npxeinfo: PXENV_UNDI_GET_NIC_TYPE failed: 0x%x\n",
+ gnt->Status);
+ return;
+ }
+
+ switch (gnt->NicType) {
+ case PCI_NIC:
+ case CardBus_NIC:
+ /* strncpy(bi_netif.ifname, "pxe", sizeof(bi_netif.ifname)); */
+ /* bi_netif.bus = BI_BUS_PCI; */
+ /* bi_netif.addr.tag = gnt->info.pci.BusDevFunc; */
+
+ printf("\nPXE: Using %s device at bus %d device %d function %d\n",
+ gnt->NicType == PCI_NIC ? "PCI" : "CardBus",
+ (gnt->info.pci.BusDevFunc >> 8) & 0xff,
+ (gnt->info.pci.BusDevFunc >> 3) & 0x1f,
+ gnt->info.pci.BusDevFunc & 0x7);
+ break;
+
+ case PnP_NIC:
+ /* XXX Make bootinfo work with this. */
+ printf("\nPXE: Using PnP device at 0x%x\n",
+ gnt->info.pnp.CardSelNum);
+ }
+#endif
+}
+
+void
+pxe_shutdown(void)
+{
+ int try;
+ t_PXENV_UNLOAD_STACK *unload = (void *) pxe_command_buf;
+ t_PXENV_UNDI_SHUTDOWN *shutdown = (void *) pxe_command_buf;
+#ifdef PXE_DEBUG
+ t_PXENV_UDP_CLOSE *close = (void *) pxe_command_buf;
+#endif
+
+ if (pxe_call == NULL)
+ return;
+
+ /* Close any open UDP connections. Ignore return value. */
+ pxe_call(PXENV_UDP_CLOSE);
+#ifdef PXE_DEBUG
+ printf("pxe_shutdown: PXENV_UDP_CLOSE returned 0x%x\n", close->status);
+#endif
+
+ /* Sometimes PXENV_UNDI_SHUTDOWN doesn't work at first */
+ for (try = 3; try > 0; try--) {
+ pxe_call(PXENV_UNDI_SHUTDOWN);
+
+ if (shutdown->Status == PXENV_STATUS_SUCCESS)
+ break;
+
+ printf("pxe_shutdown: PXENV_UNDI_SHUTDOWN failed: 0x%x\n",
+ shutdown->Status);
+
+ if (try != 1)
+ sleep(1);
+ }
+
+ /* Have multiple attempts at PXENV_UNLOAD_STACK, too */
+ for (try = 3; try > 0; try--) {
+ pxe_call(PXENV_UNLOAD_STACK);
+
+ if (unload->Status == PXENV_STATUS_SUCCESS)
+ break;
+
+ printf("pxe_shutdown: PXENV_UNLOAD_STACK failed: 0x%x\n",
+ unload->Status);
+
+ if (try != 1)
+ sleep(1);
+ }
+}
diff --git a/sys/arch/i386/stand/libsa/pxe.h b/sys/arch/i386/stand/libsa/pxe.h
new file mode 100644
index 00000000000..37b5ceead0d
--- /dev/null
+++ b/sys/arch/i386/stand/libsa/pxe.h
@@ -0,0 +1,528 @@
+/* $OpenBSD: pxe.h,v 1.1 2004/03/19 13:48:18 tom Exp $ */
+/* $NetBSD: pxe.h,v 1.1 2002/02/16 03:37:40 thorpej Exp $ */
+
+/*
+ * Copyright (c) 2000 Alfred Perlstein <alfred@freebsd.org>
+ * All rights reserved.
+ * Copyright (c) 2000 Paul Saab <ps@freebsd.org>
+ * All rights reserved.
+ * Copyright (c) 2000 John Baldwin <jhb@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Note that these structures and types are named according to
+ * the Intel PXE documentation.
+ */
+
+#define S_SIZE(s) s, sizeof(s) - 1
+
+#define IP_STR "%d.%d.%d.%d"
+#define IP_ARGS(ip) \
+ (int)(ip >> 24) & 0xff, (int)(ip >> 16) & 0xff, \
+ (int)(ip >> 8) & 0xff, (int)ip & 0xff
+
+#define MAC_STR "%02x:%02x:%02x:%02x:%02x:%02x"
+#define MAC_ARGS(mac) \
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]
+
+typedef struct {
+ uint16_t offset;
+ uint16_t segment;
+} SEGOFF16_t __attribute__((__packed__));
+
+typedef struct {
+ uint16_t Seg_Addr;
+ uint32_t Phy_Addr;
+ uint16_t Seg_Size;
+} SEGDESC_t __attribute__((__packed__));
+
+typedef uint16_t SEGSEL_t;
+typedef uint16_t PXENV_STATUS_t;
+typedef uint32_t IP4_t;
+typedef uint32_t ADDR32_t;
+typedef uint16_t UDP_PORT_t;
+
+#define MAC_ADDR_LEN 16
+typedef uint8_t MAC_ADDR[MAC_ADDR_LEN];
+
+/* PXENV+ */
+typedef struct {
+ uint8_t Signature[6]; /* 'PXENV+' */
+ uint16_t Version; /* MSB = major, LSB = minor */
+ uint8_t Length; /* structure length */
+ uint8_t Checksum; /* checksum pad */
+ SEGOFF16_t RMEntry; /* SEG:OFF to PXE entry point */
+ /* don't use PMOffset and PMSelector (from the 2.1 PXE manual) */
+ uint32_t PMOffset; /* Protected mode entry */
+ SEGSEL_t PMSelector; /* Protected mode selector */
+ SEGSEL_t StackSeg; /* Stack segment address */
+ uint16_t StackSize; /* Stack segment size (bytes) */
+ SEGSEL_t BC_CodeSeg; /* BC Code segment address */
+ uint16_t BC_CodeSize; /* BC Code segment size (bytes) */
+ SEGSEL_t BC_DataSeg; /* BC Data segment address */
+ uint16_t BC_DataSize; /* BC Data segment size (bytes) */
+ SEGSEL_t UNDIDataSeg; /* UNDI Data segment address */
+ uint16_t UNDIDataSize; /* UNDI Data segment size (bytes) */
+ SEGSEL_t UNDICodeSeg; /* UNDI Code segment address */
+ uint16_t UNDICodeSize; /* UNDI Code segment size (bytes) */
+ SEGOFF16_t PXEPtr; /* SEG:OFF to !PXE struct,
+ only present when Version > 2.1 */
+} __attribute__((__packed__)) pxenv_t;
+
+/* !PXE */
+typedef struct {
+ uint8_t Signature[4];
+ uint8_t StructLength;
+ uint8_t StructCksum;
+ uint8_t StructRev;
+ uint8_t reserved_1;
+ SEGOFF16_t UNDIROMID;
+ SEGOFF16_t BaseROMID;
+ SEGOFF16_t EntryPointSP;
+ SEGOFF16_t EntryPointESP;
+ SEGOFF16_t StatusCallout;
+ uint8_t reserved_2;
+ uint8_t SegDescCn;
+ SEGSEL_t FirstSelector;
+ SEGDESC_t Stack;
+ SEGDESC_t UNDIData;
+ SEGDESC_t UNDICode;
+ SEGDESC_t UNDICodeWrite;
+ SEGDESC_t BC_Data;
+ SEGDESC_t BC_Code;
+ SEGDESC_t BC_CodeWrite;
+} __attribute__((__packed__)) pxe_t;
+
+#define PXENV_START_UNDI 0x0000
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint16_t ax;
+ uint16_t bx;
+ uint16_t dx;
+ uint16_t di;
+ uint16_t es;
+} __attribute__((__packed__)) t_PXENV_START_UNDI;
+
+#define PXENV_UNDI_STARTUP 0x0001
+typedef struct {
+ PXENV_STATUS_t Status;
+} __attribute__((__packed__)) t_PXENV_UNDI_STARTUP;
+
+#define PXENV_UNDI_CLEANUP 0x0002
+typedef struct {
+ PXENV_STATUS_t Status;
+} __attribute__((__packed__)) t_PXENV_UNDI_CLEANUP;
+
+#define PXENV_UNDI_INITIALIZE 0x0003
+typedef struct {
+ PXENV_STATUS_t Status;
+ ADDR32_t ProtocolIni; /* Phys addr of a copy of the
+ driver module */
+ uint8_t reserved[8];
+} __attribute__((__packed__)) t_PXENV_UNDI_INITALIZE;
+
+
+#define MAXNUM_MCADDR 8
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint16_t MCastAddrCount;
+ MAC_ADDR McastAddr[MAXNUM_MCADDR];
+} __attribute__((__packed__)) t_PXENV_UNDI_MCAST_ADDRESS;
+
+#define PXENV_UNDI_RESET_ADAPTER 0x0004
+typedef struct {
+ PXENV_STATUS_t Status;
+ t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
+} __attribute__((__packed__)) t_PXENV_UNDI_RESET;
+
+#define PXENV_UNDI_SHUTDOWN 0x0005
+typedef struct {
+ PXENV_STATUS_t Status;
+} __attribute__((__packed__)) t_PXENV_UNDI_SHUTDOWN;
+
+#define PXENV_UNDI_OPEN 0x0006
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint16_t OpenFlag;
+ uint16_t PktFilter;
+# define FLTR_DIRECTED 0x0001
+# define FLTR_BRDCST 0x0002
+# define FLTR_PRMSCS 0x0003
+# define FLTR_SRC_RTG 0x0004
+
+ t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
+} __attribute__((__packed__)) t_PXENV_UNDI_OPEN;
+
+#define PXENV_UNDI_CLOSE 0x0007
+typedef struct {
+ PXENV_STATUS_t Status;
+} __attribute__((__packed__)) t_PXENV_UNDI_CLOSE;
+
+#define PXENV_UNDI_TRANSMIT 0x0008
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint8_t Protocol;
+# define P_UNKNOWN 0
+# define P_IP 1
+# define P_ARP 2
+# define P_RARP 3
+
+ uint8_t XmitFlag;
+# define XMT_DESTADDR 0x0000
+# define XMT_BROADCAST 0x0001
+
+ SEGOFF16_t DestAddr;
+ SEGOFF16_t TBD;
+ uint32_t Reserved[2];
+} __attribute__((__packed__)) t_PXENV_UNDI_TRANSMIT;
+
+#define MAX_DATA_BLKS 8
+typedef struct {
+ uint16_t ImmedLength;
+ SEGOFF16_t Xmit;
+ uint16_t DataBlkCount;
+ struct DataBlk {
+ uint8_t TDPtrType;
+ uint8_t TDRsvdByte;
+ uint16_t TDDataLen;
+ SEGOFF16_t TDDataPtr;
+ } DataBlock[MAX_DATA_BLKS];
+} __attribute__((__packed__)) t_PXENV_UNDI_TBD;
+
+#define PXENV_UNDI_SET_MCAST_ADDRESS 0x0009
+typedef struct {
+ PXENV_STATUS_t Status;
+ t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
+} __attribute__((__packed__)) t_PXENV_UNDI_SET_MCAST_ADDR;
+
+#define PXENV_UNDI_SET_STATION_ADDRESS 0x000A
+typedef struct {
+ PXENV_STATUS_t Status;
+ MAC_ADDR StationAddress; /* Temp MAC addres to use */
+} __attribute__((__packed__)) t_PXENV_UNDI_SET_STATION_ADDR;
+
+#define PXENV_UNDI_SET_PACKET_FILTER 0x000B
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint8_t filter; /* see UNDI_OPEN (0x0006) */
+} __attribute__((__packed__)) t_PXENV_UNDI_SET_PACKET_FILTER;
+
+#define PXENV_UNDI_GET_INFORMATION 0x000C
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint16_t BaseIo; /* Adapter base I/O address */
+ uint16_t IntNumber; /* Adapter IRQ number */
+ uint16_t MaxTranUnit; /* Adapter maximum transmit
+ unit */
+ uint16_t HwType; /* Type of protocol at the
+ hardware addr */
+# define ETHER_TYPE 1
+# define EXP_ETHER_TYPE 2
+# define IEEE_TYPE 6
+# define ARCNET_TYPE 7
+
+ uint16_t HwAddrLen; /* Length of hardware address */
+ MAC_ADDR CurrentNodeAddress; /* Current hardware address */
+ MAC_ADDR PermNodeAddress; /* Permanent hardware address */
+ SEGSEL_t ROMAddress; /* Real mode ROM segment
+ address */
+ uint16_t RxBufCt; /* Receive queue length */
+ uint16_t TxBufCt; /* Transmit queue length */
+} __attribute__((__packed__)) t_PXENV_UNDI_GET_INFORMATION;
+
+#define PXENV_UNDI_GET_STATISTICS 0x000D
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint32_t XmitGoodFrames; /* Number of successful
+ transmissions */
+ uint32_t RcvGoodFrames; /* Number of good frames
+ received */
+ uint32_t RcvCRCErrors; /* Number of frames with
+ CRC errors */
+ uint32_t RcvResourceErrors; /* Number of frames dropped */
+} __attribute__((__packed__)) t_PXENV_UNDI_GET_STATISTICS;
+
+#define PXENV_UNDI_CLEAR_STATISTICS 0x000E
+typedef struct {
+ PXENV_STATUS_t Status;
+} __attribute__((__packed__)) t_PXENV_UNDI_CLEAR_STATISTICS;
+
+#define PXENV_UNDI_INITIATE_DIAGS 0x000F
+typedef struct {
+ PXENV_STATUS_t Status;
+} __attribute__((__packed__)) t_PXENV_UNDI_INITIATE_DIAGS;
+
+#define PXENV_UNDI_FORCE_INTERRUPT 0x0010
+typedef struct {
+ PXENV_STATUS_t Status;
+} __attribute__((__packed__)) t_PXENV_UNDI_FORCE_INTERRUPT;
+
+#define PXENV_UNDI_GET_MCAST_ADDRESS 0x0011
+typedef struct {
+ PXENV_STATUS_t Status;
+ IP4_t InetAddr; /* IP mulicast address */
+ MAC_ADDR MediaAddr; /* MAC multicast address */
+} __attribute__((__packed__)) t_PXENV_UNDI_GET_MCAST_ADDR;
+
+#define PXENV_UNDI_GET_NIC_TYPE 0x0012
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint8_t NicType; /* Type of NIC */
+# define PCI_NIC 2
+# define PnP_NIC 3
+# define CardBus_NIC 4
+
+ union {
+ struct {
+ uint16_t Vendor_ID;
+ uint16_t Dev_ID;
+ uint8_t Base_Class;
+ uint8_t Sub_Class;
+ uint8_t Prog_Intf;
+ uint8_t Rev;
+ uint16_t BusDevFunc;
+ uint16_t SubVendor_ID;
+ uint16_t SubDevice_ID;
+ } pci, cardbus;
+ struct {
+ uint32_t EISA_Dev_ID;
+ uint8_t Base_Class;
+ uint8_t Sub_Class;
+ uint8_t Prog_Intf;
+ uint16_t CardSelNum;
+ } pnp;
+ } info;
+} __attribute__((__packed__)) t_PXENV_UNDI_GET_NIC_TYPE;
+
+#define PXENV_UNDI_GET_IFACE_INFO 0x0013
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint8_t IfaceType[16]; /* Name of MAC type in ASCII. */
+ uint32_t LinkSpeed; /* Defined in NDIS 2.0 spec */
+ uint32_t ServiceFlags; /* Defined in NDIS 2.0 spec */
+ uint32_t Reserved[4]; /* must be 0 */
+} __attribute__((__packed__)) t_PXENV_UNDI_GET_NDIS_INFO;
+
+#define PXENV_UNDI_ISR 0x0014
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint16_t FuncFlag; /* PXENV_UNDI_ISR_OUT_xxx */
+ uint16_t BufferLength; /* Length of Frame */
+ uint16_t FrameLength; /* Total length of reciever
+ frame */
+ uint16_t FrameHeaderLength; /* Length of the media header
+ in Frame */
+ SEGOFF16_t Frame; /* receive buffer */
+ uint8_t ProtType; /* Protocol type */
+ uint8_t PktType; /* Packet Type */
+# define PXENV_UNDI_ISR_IN_START 1
+# define PXENV_UNDI_ISR_IN_PROCESS 2
+# define PXENV_UNDI_ISR_IN_GET_NEXT 3
+
+ /* one of these will be returned for PXENV_UNDI_ISR_IN_START */
+# define PXENV_UNDI_ISR_OUT_OURS 0
+# define PXENV_UNDI_ISR_OUT_NOT_OUTS 1
+
+ /*
+ * one of these will bre returnd for PXEND_UNDI_ISR_IN_PROCESS
+ * and PXENV_UNDI_ISR_IN_GET_NEXT
+ */
+# define PXENV_UNDI_ISR_OUT_DONE 0
+# define PXENV_UNDI_ISR_OUT_TRANSMIT 2
+# define PXENV_UNDI_ISR_OUT_RECIEVE 3
+# define PXENV_UNDI_ISR_OUT_BUSY 4
+} __attribute__((__packed__)) t_PXENV_UNDI_ISR;
+
+#define PXENV_STOP_UNDI 0x0015
+typedef struct {
+ PXENV_STATUS_t Status;
+} __attribute__((__packed__)) t_PXENV_STOP_UNDI;
+
+#define PXENV_TFTP_OPEN 0x0020
+typedef struct {
+ PXENV_STATUS_t Status;
+ IP4_t ServerIPAddress;
+ IP4_t GatewayIPAddress;
+ uint8_t FileName[128];
+ UDP_PORT_t TFTPPort;
+ uint16_t PacketSize;
+} __attribute__((__packed__)) t_PXENV_TFTP_OPEN;
+
+#define PXENV_TFTP_CLOSE 0x0021
+typedef struct {
+ PXENV_STATUS_t Status;
+} __attribute__((__packed__)) t_PXENV_TFTP_CLOSE;
+
+#define PXENV_TFTP_READ 0x0022
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint16_t PacketNumber;
+ uint16_t BufferSize;
+ SEGOFF16_t Buffer;
+} __attribute__((__packed__)) t_PXENV_TFTP_READ;
+
+#define PXENV_TFTP_READ_FILE 0x0023
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint8_t FileName[128];
+ uint32_t BufferSize;
+ ADDR32_t Buffer;
+ IP4_t ServerIPAddress;
+ IP4_t GatewayIPAddress;
+ IP4_t McastIPAddress;
+ UDP_PORT_t TFTPClntPort;
+ UDP_PORT_t TFTPSrvPort;
+ uint16_t TFTPOpenTimeOut;
+ uint16_t TFTPReopenDelay;
+} __attribute__((__packed__)) t_PXENV_TFTP_READ_FILE;
+
+#define PXENV_TFTP_GET_FSIZE 0x0025
+typedef struct {
+ PXENV_STATUS_t Status;
+ IP4_t ServerIPAddress;
+ IP4_t GatewayIPAddress;
+ uint8_t FileName[128];
+ uint32_t FileSize;
+} __attribute__((__packed__)) t_PXENV_TFTP_GET_FSIZE;
+
+#define PXENV_UDP_OPEN 0x0030
+typedef struct {
+ PXENV_STATUS_t status;
+ IP4_t src_ip; /* IP address of this station */
+} __attribute__((__packed__)) t_PXENV_UDP_OPEN;
+
+#define PXENV_UDP_CLOSE 0x0031
+typedef struct {
+ PXENV_STATUS_t status;
+} __attribute__((__packed__)) t_PXENV_UDP_CLOSE;
+
+#define PXENV_UDP_READ 0x0032
+typedef struct {
+ PXENV_STATUS_t status;
+ IP4_t src_ip; /* IP of sender */
+ IP4_t dest_ip; /* Only accept packets sent to
+ this IP */
+ UDP_PORT_t s_port; /* UDP source port of sender */
+ UDP_PORT_t d_port; /* Only accept packets sent to
+ this port */
+ uint16_t buffer_size; /* Size of the packet buffer */
+ SEGOFF16_t buffer; /* SEG:OFF to the packet buffer */
+} __attribute__((__packed__)) t_PXENV_UDP_READ;
+
+#define PXENV_UDP_WRITE 0x0033
+typedef struct {
+ PXENV_STATUS_t status;
+ IP4_t ip; /* dest ip addr */
+ IP4_t gw; /* ip gateway */
+ UDP_PORT_t src_port; /* source udp port */
+ UDP_PORT_t dst_port; /* destination udp port */
+ uint16_t buffer_size; /* Size of the packet buffer */
+ SEGOFF16_t buffer; /* SEG:OFF to the packet buffer */
+} __attribute__((__packed__)) t_PXENV_UDP_WRITE;
+
+#define PXENV_UNLOAD_STACK 0x0070
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint8_t reserved[10];
+} __attribute__((__packed__)) t_PXENV_UNLOAD_STACK;
+
+
+#define PXENV_GET_CACHED_INFO 0x0071
+typedef struct {
+ PXENV_STATUS_t Status;
+ uint16_t PacketType; /* type (defined right here) */
+# define PXENV_PACKET_TYPE_DHCP_DISCOVER 1
+# define PXENV_PACKET_TYPE_DHCP_ACK 2
+# define PXENV_PACKET_TYPE_CACHED_REPLY 3
+ uint16_t BufferSize; /* max to copy, leave at 0 for
+ pointer */
+ SEGOFF16_t Buffer; /* copy to, leave at 0 for pointer */
+ uint16_t BufferLimit; /* max size of buffer in BC dataseg ? */
+} __attribute__((__packed__)) t_PXENV_GET_CACHED_INFO;
+
+
+/* structure filled in by PXENV_GET_CACHED_INFO
+ * (how we determine which IP we downloaded the initial bootstrap from)
+ * words can't describe...
+ */
+typedef struct {
+ uint8_t opcode;
+# define BOOTP_REQ 1
+# define BOOTP_REP 2
+ uint8_t Hardware; /* hardware type */
+ uint8_t Hardlen; /* hardware addr len */
+ uint8_t Gatehops; /* zero it */
+ uint32_t ident; /* random number chosen by client */
+ uint16_t seconds; /* seconds since did initial
+ bootstrap */
+ uint16_t Flags; /* seconds since did initial
+ bootstrap */
+# define BOOTP_BCAST 0x8000 /* ? */
+ IP4_t cip; /* Client IP */
+ IP4_t yip; /* Your IP */
+ IP4_t sip; /* IP to use for next boot stage */
+ IP4_t gip; /* Relay IP ? */
+ MAC_ADDR CAddr; /* Client hardware address */
+ uint8_t Sname[64]; /* Server's hostname (Optional) */
+ uint8_t bootfile[128]; /* boot filename */
+ union {
+# if 1
+# define BOOTP_DHCPVEND 1024 /* DHCP extended vendor
+ field size */
+# else
+# define BOOTP_DHCPVEND 312 /* DHCP standard vendor
+ field size */
+# endif
+ uint8_t d[BOOTP_DHCPVEND]; /* raw array of
+ vendor/dhcp options */
+ struct {
+ uint8_t magic[4]; /* DHCP magic cookie */
+# ifndef VM_RFC1048
+# define VM_RFC1048 0x63825363L /* ? */
+# endif
+ uint32_t flags; /* bootp flags/opcodes */
+ uint8_t pad[56]; /* I don't think intel
+ knows what a union
+ does... */
+ } v;
+ } vendor;
+} __attribute__((__packed__)) BOOTPLAYER;
+
+#define PXENV_RESTART_TFTP 0x0073
+#define t_PXENV_RESTART_TFTP t_PXENV_TFTP_READ_FILE
+
+#define PXENV_START_BASE 0x0075
+typedef struct {
+ PXENV_STATUS_t Status;
+} __attribute__((__packed__)) t_PXENV_START_BASE;
+
+#define PXENV_STOP_BASE 0x0076
+typedef struct {
+ PXENV_STATUS_t Status;
+} __attribute__((__packed__)) t_PXENV_STOP_BASE;
+
+#define PXENV_STATUS_SUCCESS 0
+#define PXENV_STATUS_FAILURE 1
+/* ...there are tons more, but we don't really care about them right now... */
diff --git a/sys/arch/i386/stand/libsa/pxe_call.S b/sys/arch/i386/stand/libsa/pxe_call.S
new file mode 100644
index 00000000000..5085b79b653
--- /dev/null
+++ b/sys/arch/i386/stand/libsa/pxe_call.S
@@ -0,0 +1,202 @@
+/* $OpenBSD: pxe_call.S,v 1.1 2004/03/19 13:48:18 tom Exp $ */
+/* $NetBSD: pxe_call.S,v 1.2 2002/03/27 17:24:22 kanaoka Exp $ */
+
+/*
+ * Copyright 2001 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Low level PXE BIOS call glue.
+ */
+
+#include <machine/asm.h>
+#include <assym.h>
+
+#include "gidt.h"
+
+ENTRY(pxecall_bangpxe)
+ .code32
+ pushl %ebp
+ movl %esp, %ebp
+ pushl %ebx
+ pushl %ecx
+ pushl %edx
+
+ /* For simplicity, just move all 32 bits. */
+ movl 8(%ebp), %ebx
+
+ pushw _C_LABEL(pxe_command_buf_seg)
+ pushw _C_LABEL(pxe_command_buf_off)
+ pushw %bx
+
+ call prot_to_real /* Enter real mode */
+ .code16
+
+ sti
+ /* The encoding is: 0x9a offlo offhi seglo seghi */
+ lcall $0, $0xffff
+ .globl _C_LABEL(bangpxe_off)
+_C_LABEL(bangpxe_off) = . - 4
+ .globl _C_LABEL(bangpxe_seg)
+_C_LABEL(bangpxe_seg) = . - 2
+
+ cli
+ call real_to_prot /* Leave real mode */
+ .code32
+
+ add $6, %esp
+
+ popl %edx
+ popl %ecx
+ popl %ebx
+ popl %ebp
+ ret
+
+ENTRY(pxecall_pxenv)
+ .code32
+ pushl %ebp
+ movl %esp, %ebp
+ pushl %ebx
+ pushl %ecx
+ pushl %edx
+ pushl %edi
+
+ /* For simplicity, just move all 32 bits. */
+ movl 8(%ebp), %ebx
+
+ call prot_to_real /* Enter real mode */
+ .code16
+
+ /* prot_to_real() has already set %es to BOOTSEG */
+ lea _C_LABEL(pxe_command_buf), %di
+
+ /* The encoding is: 0x9a offlo offhi seglo seghi */
+ lcall $0, $0xffff
+ .globl _C_LABEL(pxenv_off)
+_C_LABEL(pxenv_off) = . - 4
+ .globl _C_LABEL(pxenv_seg)
+_C_LABEL(pxenv_seg) = . - 2
+
+ call real_to_prot /* Leave real mode */
+ .code32
+
+ popl %edi
+ popl %edx
+ popl %ecx
+ popl %ebx
+ popl %ebp
+ ret
+
+/*
+ * prot_to_real()
+ *
+ * Switch the processor back into real mode.
+ */
+ .globl prot_to_real
+prot_to_real:
+ .code32
+ ljmp $S16TEXT, $p2r16 - LINKADDR
+p2r16:
+ .code16
+
+ movw $S16DATA, %ax
+ movw %ax, %ds
+ movw %ax, %es
+
+ movl %cr0, %eax /* Disable protected mode */
+ andl $~CR0_PE, %eax
+ movl %eax, %cr0
+
+ /* reload real cs:ip */
+ data32 ljmp $(LINKADDR >> 4), $p2r16real - LINKADDR
+p2r16real:
+ xorw %ax, %ax /* Reset segment registers: */
+ movw %ax, %ds /* %ds: so we can get at Idtr_real */
+ movw %ax, %ss /* %ss: for our stack */
+
+ .extern Idtr_real
+ data32 addr32 lidt Idtr_real; /* Set up IDT for real mode */
+
+ movw %cs, %ax
+ movw %ax, %ds
+ movw %ax, %es /* Set %ds = %es = %cs */
+
+ /*
+ * We were called from 32-bit mode, so there's a 32-bit
+ * return address on the stack. No segment. This is within
+ * the flat memory model, so we need to adjust it back so
+ * that it's relative to our 16-bit %cs.
+ */
+ popl %eax
+ subl $LINKADDR, %eax
+ pushw %ax
+ ret
+
+/*
+ * real_to_prot()
+ *
+ * Switch the processor back into protected mode.
+ */
+ .globl real_to_prot
+real_to_prot:
+ .code16
+
+ xorw %ax, %ax
+ movw %ax, %ds /* Load %ds so we can get at Gdtr */
+ data32 addr32 lgdt Gdtr /* Load the GDT */
+
+ movl %cr0, %eax /* Enable protected mode */
+ orl $CR0_PE, %eax
+ movl %eax, %cr0
+
+ data32 ljmp $S32TEXT, $r2p32 /* Reload %cs, flush pipeline */
+r2p32:
+ .code32
+ /* Reload 32-bit %ds, %ss, %es */
+ movl $S32DATA, %eax
+ mov %ax, %ds
+ mov %ax, %ss
+ mov %ax, %es
+
+ /* Load IDT for debugger and DOS/BIOS interface */
+ .extern Idtr
+ lidt Idtr
+
+ xorl %eax, %eax
+ popw %ax /* 16-bit return addr on stack */
+ addl $LINKADDR, %eax
+ pushl %eax /* Now have correct 32-bit ret addr */
+ ret
+
+ .end
diff --git a/sys/arch/i386/stand/libsa/pxe_net.c b/sys/arch/i386/stand/libsa/pxe_net.c
new file mode 100644
index 00000000000..df252771486
--- /dev/null
+++ b/sys/arch/i386/stand/libsa/pxe_net.c
@@ -0,0 +1,184 @@
+/* $OpenBSD: pxe_net.c,v 1.1 2004/03/19 13:48:18 tom Exp $ */
+/* $NetBSD: dev_net.c,v 1.4 2003/03/12 13:15:08 drochner Exp $ */
+
+/*-
+ * Copyright (c) 1997 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Gordon W. Ross.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This module implements a "raw device" interface suitable for
+ * use by the stand-alone I/O library NFS and TFTP code. This interface
+ * does not support any "block" access, and exists only for the
+ * purpose of initializing the network interface and getting boot
+ * parameters.
+ *
+ * At open time, this does:
+ *
+ * find interface - netif_open()
+ * BOOTP for IP address - bootp()
+ */
+
+#include <machine/stdarg.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#include <lib/libkern/libkern.h>
+
+#include <lib/libsa/stand.h>
+#include <lib/libsa/net.h>
+#include "pxe_netif.h"
+#include "pxe_net.h"
+
+static int netdev_sock = -1;
+static int netdev_opens;
+
+int net_getparams(int);
+
+/*
+ * Called by devopen after it sets f->f_dev to our devsw entry.
+ * This opens the low-level device and sets f->f_devdata.
+ * This is declared with variable arguments...
+ */
+int
+net_open(struct open_file *f, ...)
+{
+ int error = 0;
+
+#ifdef NETIF_DEBUG
+ if (debug)
+ printf("net_open()\n");
+#endif
+
+ /* On first open, do netif open, mount, etc. */
+ if (netdev_opens == 0) {
+ /* Find network interface. */
+ if (netdev_sock < 0) {
+ netdev_sock = pxe_netif_open();
+ if (netdev_sock < 0) {
+ printf("net_open: netif_open() failed\n");
+ return ENXIO;
+ }
+#ifdef NETIF_DEBUG
+ if (debug)
+ printf("net_open: netif_open() succeeded\n");
+#endif
+ }
+#ifdef notyet
+ if (rootip.s_addr == 0) {
+ /* Get root IP address, and path, etc. */
+ error = net_getparams(netdev_sock);
+ if (error) {
+ /* getparams makes its own noise */
+ pxe_netif_close(netdev_sock);
+ netdev_sock = -1;
+ return error;
+ }
+ }
+#endif
+ }
+ netdev_opens++;
+ f->f_devdata = &netdev_sock;
+ return error;
+}
+
+int
+net_close(struct open_file *f)
+{
+#ifdef NETIF_DEBUG
+ if (debug)
+ printf("net_close: opens=%d\n", netdev_opens);
+#endif
+
+ /* On last close, do netif close, etc. */
+ f->f_devdata = NULL;
+ /* Extra close call? */
+ if (netdev_opens <= 0)
+ return 0;
+ netdev_opens--;
+ /* Not last close? */
+ if (netdev_opens > 0)
+ return 0;
+ rootip.s_addr = 0;
+ if (netdev_sock >= 0) {
+#ifdef NETIF_DEBUG
+ if (debug)
+ printf("net_close: calling netif_close()\n");
+#endif
+ pxe_netif_close(netdev_sock);
+ netdev_sock = -1;
+ }
+ return 0;
+}
+
+int
+net_ioctl(struct open_file *f, u_long cmd, void *data)
+{
+ return EIO;
+}
+
+int
+net_strategy(void *devdata, int rw, daddr_t blk, size_t size, void *buf,
+ size_t *rsize)
+{
+ return EIO;
+}
+
+
+/*
+ * Get info for network boot: our IP address, our hostname,
+ * server IP address, and our root path on the server.
+ */
+extern int bootp(int);
+
+int
+net_getparams(int sock)
+{
+ /*
+ * Try to get boot info using BOOTP. If we succeed, then
+ * the server IP address, gateway, and root path will all
+ * be initialized. If any remain uninitialized, we will
+ * use RARP and RPC/bootparam (the Sun way) to get them.
+ */
+ bootp(sock);
+ if (myip.s_addr != 0)
+ return 0;
+ if (debug)
+ printf("net_getparams: BOOTP failed\n");
+
+ return EIO;
+}
diff --git a/sys/arch/i386/stand/libsa/pxe_net.h b/sys/arch/i386/stand/libsa/pxe_net.h
new file mode 100644
index 00000000000..406c15599c4
--- /dev/null
+++ b/sys/arch/i386/stand/libsa/pxe_net.h
@@ -0,0 +1,44 @@
+/* $OpenBSD: pxe_net.h,v 1.1 2004/03/19 13:48:18 tom Exp $ */
+/* $NetBSD$ */
+
+/*-
+ * Copyright (c) 1997 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Gordon W. Ross.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* pxe_net.c */
+int net_open(struct open_file *, ...);
+int net_close(struct open_file *);
+int net_ioctl(struct open_file *, u_long, void *);
+int net_strategy(void *, int , daddr_t , size_t, void *, size_t *);
diff --git a/sys/arch/i386/stand/libsa/pxe_netif.h b/sys/arch/i386/stand/libsa/pxe_netif.h
new file mode 100644
index 00000000000..b8cddcc9cc9
--- /dev/null
+++ b/sys/arch/i386/stand/libsa/pxe_netif.h
@@ -0,0 +1,43 @@
+/* $OpenBSD: pxe_netif.h,v 1.1 2004/03/19 13:48:18 tom Exp $ */
+/* $NetBSD$ */
+
+/*-
+ * Copyright (c) 1997 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Gordon W. Ross.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* pxe.c */
+int pxe_netif_open(void);
+void pxe_netif_close(int);
+void pxe_netif_shutdown(void);
diff --git a/sys/arch/i386/stand/libsa/pxeboot.h b/sys/arch/i386/stand/libsa/pxeboot.h
new file mode 100644
index 00000000000..e2a6a28f05c
--- /dev/null
+++ b/sys/arch/i386/stand/libsa/pxeboot.h
@@ -0,0 +1,53 @@
+/* $OpenBSD: pxeboot.h,v 1.1 2004/03/19 13:48:18 tom Exp $ */
+/* $NetBSD$ */
+
+/*
+ * Copyright 2001 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Flat address space for [pxe]boot in protected mode */
+#define VTOPSEG(vaddr) (((u_int32_t) vaddr) >> 4)
+#define VTOPOFF(vaddr) (((u_int32_t) vaddr) & 0xf)
+
+#define SEGOFF2FLAT(seg, off) ((void *)((((u_int32_t)(seg))<<4) + \
+ ((u_int32_t)(off))))
+
+void pxeprobe(void);
+void pxeinfo(void);
+
+ssize_t pxesendudp(struct iodesc *, void *, size_t);
+ssize_t pxereadudp(struct iodesc *, void *, size_t, time_t);
+
+int pxe_init(int);
+void pxe_shutdown(void);