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