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