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