pxe.h revision 367457
1/*
2 * Copyright (c) 2000 Alfred Perlstein <alfred@freebsd.org>
3 * All rights reserved.
4 * Copyright (c) 2000 Paul Saab <ps@freebsd.org>
5 * All rights reserved.
6 * Copyright (c) 2000 John Baldwin <jhb@freebsd.org>
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $FreeBSD: stable/11/stand/i386/libi386/pxe.h 367457 2020-11-07 18:10:59Z dim $
30 */
31
32/*
33 * The typedefs and structures declared in this file
34 * clearly violate style(9), the reason for this is to conform to the
35 * typedefs/structure-names used in the Intel literature to avoid confusion.
36 *
37 * It's for your own good. :)
38 */
39
40/* It seems that intel didn't think about ABI,
41 * either that or 16bit ABI != 32bit ABI (which seems reasonable)
42 * I have to thank Intel for the hair loss I incurred trying to figure
43 * out why PXE was mis-reading structures I was passing it (at least
44 * from my point of view)
45 *
46 * Solution: use gcc's '__packed' to correctly align
47 * structures passed into PXE
48 * Question: does this really work for PXE's expected ABI?
49 */
50#define	PACKED		__packed
51
52#define	S_SIZE(s)	s, sizeof(s) - 1
53
54#define	PXENFSROOTPATH	"/pxeroot"
55
56typedef struct {
57	uint16_t		offset;
58	uint16_t		segment;
59} SEGOFF16_t;
60
61typedef struct {
62	uint16_t		Seg_Addr;
63	uint32_t		Phy_Addr;
64	uint16_t		Seg_Size;
65} SEGDESC_t;
66
67typedef	uint16_t		SEGSEL_t;
68typedef	uint16_t		PXENV_STATUS_t;
69typedef	uint32_t		IP4_t;
70typedef	uint32_t		ADDR32_t;
71typedef	uint16_t		UDP_PORT_t;
72
73#define	MAC_ADDR_LEN		16
74typedef	uint8_t			MAC_ADDR[MAC_ADDR_LEN];
75
76/* PXENV+ */
77typedef struct {
78	uint8_t		Signature[6];	/* 'PXENV+' */
79	uint16_t	Version;	/* MSB = major, LSB = minor */
80	uint8_t		Length;		/* structure length */
81	uint8_t		Checksum;	/* checksum pad */
82	SEGOFF16_t	RMEntry;	/* SEG:OFF to PXE entry point */
83	/* don't use PMOffset and PMSelector (from the 2.1 PXE manual) */
84	uint32_t	PMOffset;	/* Protected mode entry */
85	SEGSEL_t	PMSelector;	/* Protected mode selector */
86	SEGSEL_t	StackSeg;	/* Stack segment address */
87	uint16_t	StackSize;	/* Stack segment size (bytes) */
88	SEGSEL_t	BC_CodeSeg;	/* BC Code segment address */
89	uint16_t	BC_CodeSize;	/* BC Code segment size (bytes) */
90	SEGSEL_t	BC_DataSeg;	/* BC Data segment address */
91	uint16_t	BC_DataSize;	/* BC Data segment size (bytes) */
92	SEGSEL_t	UNDIDataSeg;	/* UNDI Data segment address */
93	uint16_t	UNDIDataSize;	/* UNDI Data segment size (bytes) */
94	SEGSEL_t	UNDICodeSeg;	/* UNDI Code segment address */
95	uint16_t	UNDICodeSize;	/* UNDI Code segment size (bytes) */
96	SEGOFF16_t	PXEPtr;		/* SEG:OFF to !PXE struct,
97					   only present when Version > 2.1 */
98} PACKED pxenv_t;
99
100/* !PXE */
101typedef struct {
102	uint8_t		Signature[4];
103	uint8_t		StructLength;
104	uint8_t		StructCksum;
105	uint8_t		StructRev;
106	uint8_t		reserved_1;
107	SEGOFF16_t	UNDIROMID;
108	SEGOFF16_t	BaseROMID;
109	SEGOFF16_t	EntryPointSP;
110	SEGOFF16_t	EntryPointESP;
111	SEGOFF16_t	StatusCallout;
112	uint8_t		reserved_2;
113	uint8_t		SegDescCn;
114	SEGSEL_t	FirstSelector;
115	SEGDESC_t	Stack;
116	SEGDESC_t	UNDIData;
117	SEGDESC_t	UNDICode;
118	SEGDESC_t	UNDICodeWrite;
119	SEGDESC_t	BC_Data;
120	SEGDESC_t	BC_Code;
121	SEGDESC_t	BC_CodeWrite;
122} PACKED pxe_t;
123
124#define	PXENV_START_UNDI		0x0000
125typedef struct {
126	PXENV_STATUS_t	Status;
127	uint16_t	ax;
128	uint16_t	bx;
129	uint16_t	dx;
130	uint16_t	di;
131	uint16_t	es;
132} PACKED t_PXENV_START_UNDI;
133
134#define	PXENV_UNDI_STARTUP		0x0001
135typedef struct {
136	PXENV_STATUS_t	Status;
137} PACKED t_PXENV_UNDI_STARTUP;
138
139#define	PXENV_UNDI_CLEANUP		0x0002
140typedef struct {
141	PXENV_STATUS_t	Status;
142} PACKED t_PXENV_UNDI_CLEANUP;
143
144#define	PXENV_UNDI_INITIALIZE		0x0003
145typedef struct {
146	PXENV_STATUS_t	Status;
147	ADDR32_t	ProtocolIni;	/* Phys addr of a copy of the driver module */
148	uint8_t		reserved[8];
149} PACKED t_PXENV_UNDI_INITIALIZE;
150
151
152#define	MAXNUM_MCADDR		8
153typedef struct {
154	PXENV_STATUS_t	Status;
155	uint16_t	MCastAddrCount;
156	MAC_ADDR	McastAddr[MAXNUM_MCADDR];
157} PACKED t_PXENV_UNDI_MCAST_ADDRESS;
158
159#define	PXENV_UNDI_RESET_ADAPTER	0x0004
160typedef struct {
161	PXENV_STATUS_t	Status;
162	t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
163} PACKED t_PXENV_UNDI_RESET;
164
165#define	PXENV_UNDI_SHUTDOWN		0x0005
166typedef struct {
167	PXENV_STATUS_t	Status;
168} PACKED t_PXENV_UNDI_SHUTDOWN;
169
170#define	PXENV_UNDI_OPEN			0x0006
171typedef struct {
172	PXENV_STATUS_t	Status;
173	uint16_t	OpenFlag;
174	uint16_t	PktFilter;
175#	define FLTR_DIRECTED	0x0001
176#	define FLTR_BRDCST	0x0002
177#	define FLTR_PRMSCS	0x0004
178#	define FLTR_SRC_RTG	0x0008
179
180	t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
181} PACKED t_PXENV_UNDI_OPEN;
182
183#define	PXENV_UNDI_CLOSE		0x0007
184typedef struct {
185	PXENV_STATUS_t	Status;
186} PACKED t_PXENV_UNDI_CLOSE;
187
188#define	PXENV_UNDI_TRANSMIT		0x0008
189typedef struct {
190	PXENV_STATUS_t	Status;
191	uint8_t		Protocol;
192#	define P_UNKNOWN	0
193#	define P_IP		1
194#	define P_ARP		2
195#	define P_RARP		3
196
197	uint8_t		XmitFlag;
198#	define XMT_DESTADDR	0x0000
199#	define XMT_BROADCAST	0x0001
200
201	SEGOFF16_t	DestAddr;
202	SEGOFF16_t	TBD;
203	uint32_t	Reserved[2];
204} PACKED t_PXENV_UNDI_TRANSMIT;
205
206#define	MAX_DATA_BLKS		8
207typedef struct {
208	uint16_t	ImmedLength;
209	SEGOFF16_t	Xmit;
210	uint16_t	DataBlkCount;
211	struct	DataBlk {
212		uint8_t		TDPtrType;
213		uint8_t		TDRsvdByte;
214		uint16_t	TDDataLen;
215		SEGOFF16_t	TDDataPtr;
216	} DataBlock[MAX_DATA_BLKS];
217} PACKED t_PXENV_UNDI_TBD;
218
219#define	PXENV_UNDI_SET_MCAST_ADDRESS	0x0009
220typedef struct {
221	PXENV_STATUS_t	Status;
222	t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
223} PACKED t_PXENV_UNDI_SET_MCAST_ADDR;
224
225#define	PXENV_UNDI_SET_STATION_ADDRESS	0x000A
226typedef struct {
227	PXENV_STATUS_t	Status;
228	MAC_ADDR	StationAddress;		/* Temp MAC address to use */
229} PACKED t_PXENV_UNDI_SET_STATION_ADDR;
230
231#define	PXENV_UNDI_SET_PACKET_FILTER	0x000B
232typedef struct {
233	PXENV_STATUS_t	Status;
234	uint8_t		filter;			/* see UNDI_OPEN (0x0006) */
235} PACKED t_PXENV_UNDI_SET_PACKET_FILTER;
236
237#define	PXENV_UNDI_GET_INFORMATION	0x000C
238typedef struct {
239	PXENV_STATUS_t	Status;
240	uint16_t	BaseIo;			/* Adapter base I/O address */
241	uint16_t	IntNumber;		/* Adapter IRQ number */
242	uint16_t	MaxTranUnit;		/* Adapter maximum transmit unit */
243	uint16_t	HwType;			/* Type of protocol at the hardware addr */
244#	define ETHER_TYPE	1
245#	define EXP_ETHER_TYPE	2
246#	define IEEE_TYPE	6
247#	define ARCNET_TYPE	7
248
249	uint16_t	HwAddrLen;		/* Length of hardware address */
250	MAC_ADDR	CurrentNodeAddress;	/* Current hardware address */
251	MAC_ADDR	PermNodeAddress;	/* Permanent hardware address */
252	SEGSEL_t	ROMAddress;		/* Real mode ROM segment address */
253	uint16_t	RxBufCt;		/* Receive queue length */
254	uint16_t	TxBufCt;		/* Transmit queue length */
255} PACKED t_PXENV_UNDI_GET_INFORMATION;
256
257#define	PXENV_UNDI_GET_STATISTICS	0x000D
258typedef struct {
259	PXENV_STATUS_t	Status;
260	uint32_t	XmitGoodFrames;		/* Number of successful transmissions */
261	uint32_t	RcvGoodFrames;		/* Number of good frames received */
262	uint32_t	RcvCRCErrors;		/* Number of frames with CRC errors */
263	uint32_t	RcvResourceErrors;	/* Number of frames dropped */
264} PACKED t_PXENV_UNDI_GET_STATISTICS;
265
266#define	PXENV_UNDI_CLEAR_STATISTICS	0x000E
267typedef struct {
268	PXENV_STATUS_t	Status;
269} PACKED t_PXENV_UNDI_CLEAR_STATISTICS;
270
271#define	PXENV_UNDI_INITIATE_DIAGS	0x000F
272typedef struct {
273	PXENV_STATUS_t	Status;
274} PACKED t_PXENV_UNDI_INITIATE_DIAGS;
275
276#define	PXENV_UNDI_FORCE_INTERRUPT	0x0010
277typedef struct {
278	PXENV_STATUS_t	Status;
279} PACKED t_PXENV_UNDI_FORCE_INTERRUPT;
280
281#define	PXENV_UNDI_GET_MCAST_ADDRESS	0x0011
282typedef struct {
283	PXENV_STATUS_t	Status;
284	IP4_t		InetAddr;		/* IP mulicast address */
285	MAC_ADDR	MediaAddr;		/* MAC multicast address */
286} PACKED t_PXENV_UNDI_GET_MCAST_ADDR;
287
288#define	PXENV_UNDI_GET_NIC_TYPE		0x0012
289typedef struct {
290	PXENV_STATUS_t	Status;
291	uint8_t		NicType;		/* Type of NIC */
292#	define PCI_NIC		2
293#	define PnP_NIC		3
294#	define CardBus_NIC	4
295
296	union {
297		struct {
298			uint16_t	Vendor_ID;
299			uint16_t	Dev_ID;
300			uint8_t		Base_Class;
301			uint8_t		Sub_Class;
302			uint8_t		Prog_Intf;
303			uint8_t		Rev;
304			uint16_t	BusDevFunc;
305			uint16_t	SubVendor_ID;
306			uint16_t	SubDevice_ID;
307		} pci, cardbus;
308		struct {
309			uint32_t	EISA_Dev_ID;
310			uint8_t		Base_Class;
311			uint8_t		Sub_Class;
312			uint8_t		Prog_Intf;
313			uint16_t	CardSelNum;
314		} pnp;
315	} info;
316} PACKED t_PXENV_UNDI_GET_NIC_TYPE;
317
318#define	PXENV_UNDI_GET_IFACE_INFO	0x0013
319typedef struct {
320	PXENV_STATUS_t	Status;
321	uint8_t		IfaceType[16];		/* Name of MAC type in ASCII. */
322	uint32_t	LinkSpeed;		/* Defined in NDIS 2.0 spec */
323	uint32_t	ServiceFlags;		/* Defined in NDIS 2.0 spec */
324	uint32_t	Reserved[4];		/* must be 0 */
325} PACKED t_PXENV_UNDI_GET_NDIS_INFO;
326
327#define	PXENV_UNDI_ISR			0x0014
328typedef struct {
329	PXENV_STATUS_t	Status;
330	uint16_t	FuncFlag;		/* PXENV_UNDI_ISR_OUT_xxx */
331	uint16_t	BufferLength;		/* Length of Frame */
332	uint16_t	FrameLength;		/* Total length of receiver frame */
333	uint16_t	FrameHeaderLength;	/* Length of the media header in Frame */
334	SEGOFF16_t	Frame;			/* receive buffer */
335	uint8_t		ProtType;		/* Protocol type */
336	uint8_t		PktType;		/* Packet Type */
337#	define PXENV_UNDI_ISR_IN_START		1
338#	define PXENV_UNDI_ISR_IN_PROCESS	2
339#	define PXENV_UNDI_ISR_IN_GET_NEXT	3
340
341	/* one of these will be returned for PXENV_UNDI_ISR_IN_START */
342#	define PXENV_UNDI_ISR_OUT_OURS		0
343#	define PXENV_UNDI_ISR_OUT_NOT_OUTS	1
344
345	/*
346	 * one of these will bre returned for PXEND_UNDI_ISR_IN_PROCESS
347	 * and PXENV_UNDI_ISR_IN_GET_NEXT
348	 */
349#	define PXENV_UNDI_ISR_OUT_DONE		0
350#	define PXENV_UNDI_ISR_OUT_TRANSMIT	2
351#	define PXENV_UNDI_ISR_OUT_RECEIVE	3
352#	define PXENV_UNDI_ISR_OUT_BUSY		4
353} PACKED t_PXENV_UNDI_ISR;
354
355#define	PXENV_STOP_UNDI			0x0015
356typedef struct {
357	PXENV_STATUS_t	Status;
358} PACKED t_PXENV_STOP_UNDI;
359
360#define	PXENV_TFTP_OPEN			0x0020
361typedef struct {
362	PXENV_STATUS_t	Status;
363	IP4_t		ServerIPAddress;
364	IP4_t		GatewayIPAddress;
365	uint8_t		FileName[128];
366	UDP_PORT_t	TFTPPort;
367	uint16_t	PacketSize;
368} PACKED t_PXENV_TFTP_OPEN;
369
370#define	PXENV_TFTP_CLOSE		0x0021
371typedef struct {
372	PXENV_STATUS_t	Status;
373} PACKED t_PXENV_TFTP_CLOSE;
374
375#define	PXENV_TFTP_READ			0x0022
376typedef struct {
377	PXENV_STATUS_t	Status;
378	uint16_t	PacketNumber;
379	uint16_t	BufferSize;
380	SEGOFF16_t	Buffer;
381} PACKED t_PXENV_TFTP_READ;
382
383#define	PXENV_TFTP_READ_FILE		0x0023
384typedef struct {
385	PXENV_STATUS_t	Status;
386	uint8_t		FileName[128];
387	uint32_t	BufferSize;
388	ADDR32_t	Buffer;
389	IP4_t		ServerIPAddress;
390	IP4_t		GatewayIPAdress;
391	IP4_t		McastIPAdress;
392	UDP_PORT_t	TFTPClntPort;
393	UDP_PORT_t	TFTPSrvPort;
394	uint16_t	TFTPOpenTimeOut;
395	uint16_t	TFTPReopenDelay;
396} PACKED t_PXENV_TFTP_READ_FILE;
397
398#define	PXENV_TFTP_GET_FSIZE		0x0025
399typedef struct {
400	PXENV_STATUS_t	Status;
401	IP4_t		ServerIPAddress;
402	IP4_t		GatewayIPAdress;
403	uint8_t		FileName[128];
404	uint32_t	FileSize;
405} PACKED t_PXENV_TFTP_GET_FSIZE;
406
407#define	PXENV_UDP_OPEN			0x0030
408typedef struct {
409	PXENV_STATUS_t	status;
410	IP4_t		src_ip;		/* IP address of this station */
411} PACKED t_PXENV_UDP_OPEN;
412
413#define	PXENV_UDP_CLOSE			0x0031
414typedef struct {
415	PXENV_STATUS_t	status;
416} PACKED t_PXENV_UDP_CLOSE;
417
418#define	PXENV_UDP_READ			0x0032
419typedef struct {
420	PXENV_STATUS_t	status;
421	IP4_t		src_ip;		/* IP of sender */
422	IP4_t		dest_ip;	/* Only accept packets sent to this IP */
423	UDP_PORT_t	s_port;		/* UDP source port of sender */
424	UDP_PORT_t	d_port;		/* Only accept packets sent to this port */
425	uint16_t	buffer_size;	/* Size of the packet buffer */
426	SEGOFF16_t	buffer;		/* SEG:OFF to the packet buffer */
427} PACKED t_PXENV_UDP_READ;
428
429#define	PXENV_UDP_WRITE			0x0033
430typedef struct {
431	PXENV_STATUS_t	status;
432	IP4_t		ip;		/* dest ip addr */
433	IP4_t		gw;		/* ip gateway */
434	UDP_PORT_t	src_port;	/* source udp port */
435	UDP_PORT_t	dst_port;	/* destination udp port */
436	uint16_t	buffer_size;	/* Size of the packet buffer */
437	SEGOFF16_t	buffer;		/* SEG:OFF to the packet buffer */
438} PACKED t_PXENV_UDP_WRITE;
439
440#define	PXENV_UNLOAD_STACK		0x0070
441typedef struct {
442	PXENV_STATUS_t	Status;
443	uint8_t		reserved[10];
444} PACKED t_PXENV_UNLOAD_STACK;
445
446
447#define	PXENV_GET_CACHED_INFO		0x0071
448typedef struct {
449	PXENV_STATUS_t	Status;
450	uint16_t	PacketType;	/* type (defined right here) */
451#	define PXENV_PACKET_TYPE_DHCP_DISCOVER  1
452#	define PXENV_PACKET_TYPE_DHCP_ACK       2
453#	define PXENV_PACKET_TYPE_BINL_REPLY     3
454	uint16_t	BufferSize;	/* max to copy, leave at 0 for pointer */
455	SEGOFF16_t	Buffer;		/* copy to, leave at 0 for pointer */
456	uint16_t	BufferLimit;	/* max size of buffer in BC dataseg ? */
457} PACKED t_PXENV_GET_CACHED_INFO;
458
459
460/* structure filled in by PXENV_GET_CACHED_INFO
461 * (how we determine which IP we downloaded the initial bootstrap from)
462 * words can't describe...
463 */
464typedef struct {
465	uint8_t		opcode;
466#	define BOOTP_REQ	1
467#	define BOOTP_REP	2
468	uint8_t		Hardware;	/* hardware type */
469	uint8_t		Hardlen;	/* hardware addr len */
470	uint8_t		Gatehops;	/* zero it */
471	uint32_t	ident;		/* random number chosen by client */
472	uint16_t	seconds;	/* seconds since did initial bootstrap */
473	uint16_t	Flags;		/* seconds since did initial bootstrap */
474#	define BOOTP_BCAST	0x8000		/* ? */
475	IP4_t		cip;		/* Client IP */
476	IP4_t		yip;		/* Your IP */
477	IP4_t		sip;		/* IP to use for next boot stage */
478	IP4_t		gip;		/* Relay IP ? */
479	MAC_ADDR	CAddr;		/* Client hardware address */
480	uint8_t		Sname[64];	/* Server's hostname (Optional) */
481	uint8_t		bootfile[128];	/* boot filename */
482	union {
483#		if 1
484#		define BOOTP_DHCPVEND  1024    /* DHCP extended vendor field size */
485#		else
486#		define BOOTP_DHCPVEND  312	/* DHCP standard vendor field size */
487#		endif
488		uint8_t		d[BOOTP_DHCPVEND];	/* raw array of vendor/dhcp options */
489		struct {
490			uint8_t		magic[4];	/* DHCP magic cookie */
491#			ifndef		VM_RFC1048
492#			define		VM_RFC1048	0x63825363L	/* ? */
493#			endif
494			uint32_t	flags;		/* bootp flags/opcodes */
495			uint8_t		pad[56];	/* I don't think intel knows what a
496							   union does... */
497		} v;
498	} vendor;
499} PACKED BOOTPLAYER;
500
501#define	PXENV_RESTART_TFTP		0x0073
502#define	t_PXENV_RESTART_TFTP		t_PXENV_TFTP_READ_FILE
503
504#define	PXENV_START_BASE		0x0075
505typedef struct {
506	PXENV_STATUS_t	Status;
507} PACKED t_PXENV_START_BASE;
508
509#define	PXENV_STOP_BASE			0x0076
510typedef struct {
511	PXENV_STATUS_t	Status;
512} PACKED t_PXENV_STOP_BASE;
513