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