blob: 511de98b8aae1ae9a680e11af0df5984bc3421ba (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
|
/**************************************************************************
Etherboot - BOOTP/TFTP Bootstrap Program
UNDI NIC driver for Etherboot - header file
This file Copyright (C) 2003 Michael Brown <mbrown@fensystems.co.uk>
of Fen Systems Ltd. (http://www.fensystems.co.uk/). All rights
reserved.
$Id: undi.h,v 1.5 2003/10/24 10:05:06 mcb30 Exp $
***************************************************************************/
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2, or (at
* your option) any later version.
*/
/* Include pxe.h from FreeBSD.
* pxe.h defines PACKED, which etherboot.h has already defined.
*/
#undef PACKED
#include "pxe.h"
#include "pic8259.h"
/* __undi_call is the assembler wrapper to the real-mode UNDI calls.
* Pass it the real-mode segment:offset address of an undi_call_info_t
* structure. The parameters are only uint16_t, but GCC will push
* them on the stack as uint32_t anyway for the sake of alignment. We
* specify them here as uint32_t to remove ambiguity.
*/
typedef struct undi_call_info {
SEGOFF16_t routine;
uint16_t stack[3];
} undi_call_info_t;
typedef uint16_t PXENV_EXIT_t;
#define PXENV_EXIT_SUCCESS 0x0000
#define PXENV_EXIT_FAILURE 0x0001
PXENV_EXIT_t __undi_call ( uint32_t, uint32_t );
/* The UNDI loader parameter structure is not defined in pxe.h
*/
typedef struct undi_loader {
PXENV_STATUS_t status;
uint16_t ax;
uint16_t bx;
uint16_t dx;
uint16_t di;
uint16_t es;
uint16_t undi_ds;
uint16_t undi_cs;
uint16_t pxe_off;
uint16_t pxenv_off;
} undi_loader_t;
/* A union that can function as the parameter block for any UNDI API call.
*/
typedef union pxenv_structure {
PXENV_STATUS_t Status; /* Make it easy to read status
for any operation */
undi_loader_t loader;
t_PXENV_START_UNDI start_undi;
t_PXENV_UNDI_STARTUP undi_startup;
t_PXENV_UNDI_CLEANUP undi_cleanup;
t_PXENV_UNDI_INITIALIZE undi_initialize;
t_PXENV_UNDI_SHUTDOWN undi_shutdown;
t_PXENV_UNDI_OPEN undi_open;
t_PXENV_UNDI_CLOSE undi_close;
t_PXENV_UNDI_TRANSMIT undi_transmit;
t_PXENV_UNDI_SET_STATION_ADDRESS undi_set_station_address;
t_PXENV_UNDI_GET_INFORMATION undi_get_information;
t_PXENV_UNDI_GET_IFACE_INFO undi_get_iface_info;
t_PXENV_UNDI_ISR undi_isr;
t_PXENV_STOP_UNDI stop_undi;
t_PXENV_UNLOAD_STACK unload_stack;
t_PXENV_GET_CACHED_INFO get_cached_info;
t_PXENV_UDP_OPEN udp_open;
t_PXENV_UDP_CLOSE udp_close;
t_PXENV_UDP_READ udp_read;
t_PXENV_UDP_WRITE udp_write;
t_PXENV_TFTP_OPEN tftp_open;
t_PXENV_TFTP_CLOSE tftp_close;
t_PXENV_TFTP_READ tftp_read;
t_PXENV_TFTP_GET_FSIZE tftp_get_fsize;
} pxenv_structure_t;
/* UNDI status codes
*/
#define PXENV_STATUS_SUCCESS 0x0000
#define PXENV_STATUS_FAILURE 0x0001
#define PXENV_STATUS_KEEP_UNDI 0x0004
#define PXENV_STATUS_KEEP_ALL 0x0005
#define PXENV_STATUS_UNDI_MEDIATEST_FAILED 0x0061
/* BIOS PnP parameter block. We scan for this so that we can pass it
* to the UNDI driver.
*/
#define PNP_BIOS_SIGNATURE ( ('$'<<0) + ('P'<<8) + ('n'<<16) + ('P'<<24) )
typedef struct pnp_bios {
uint32_t signature;
uint8_t version;
uint8_t length;
uint16_t control;
uint8_t checksum;
uint8_t dontcare[24];
} PACKED pnp_bios_t;
/* Structures within the PXE ROM.
*/
#define ROM_SIGNATURE 0xaa55
typedef struct rom {
uint16_t signature;
uint8_t unused[0x14];
uint16_t undi_rom_id_off;
uint16_t pcir_off;
uint16_t pnp_off;
} PACKED rom_t;
#define PCIR_SIGNATURE ( ('P'<<0) + ('C'<<8) + ('I'<<16) + ('R'<<24) )
typedef struct pcir_header {
uint32_t signature;
uint16_t vendor_id;
uint16_t device_id;
} PACKED pcir_header_t;
#define PNP_SIGNATURE ( ('$'<<0) + ('P'<<8) + ('n'<<16) + ('P'<<24) )
typedef struct pnp_header {
uint32_t signature;
uint8_t struct_revision;
uint8_t length;
uint16_t next;
uint8_t reserved;
uint8_t checksum;
uint16_t id[2];
uint16_t manuf_str_off;
uint16_t product_str_off;
uint8_t base_type;
uint8_t sub_type;
uint8_t interface_type;
uint8_t indicator;
uint16_t boot_connect_off;
uint16_t disconnect_off;
uint16_t initialise_off;
uint16_t reserved2;
uint16_t info;
} PACKED pnp_header_t;
#define UNDI_SIGNATURE ( ('U'<<0) + ('N'<<8) + ('D'<<16) + ('I'<<24) )
typedef struct undi_rom_id {
uint32_t signature;
uint8_t struct_length;
uint8_t struct_cksum;
uint8_t struct_rev;
uint8_t undi_rev[3];
uint16_t undi_loader_off;
uint16_t stack_size;
uint16_t data_size;
uint16_t code_size;
} PACKED undi_rom_id_t;
/* Storage buffers that we need in base memory. We collect these into
* a single structure to make allocation simpler.
*/
typedef struct undi_base_mem_xmit_data {
MAC_ADDR destaddr;
t_PXENV_UNDI_TBD tbd;
} undi_base_mem_xmit_data_t;
typedef struct undi_base_mem_data {
undi_call_info_t undi_call_info;
pxenv_structure_t pxs;
undi_base_mem_xmit_data_t xmit_data;
char xmit_buffer[ETH_FRAME_LEN];
char irq_handler[0]; /* Must be last in structure */
} undi_base_mem_data_t;
/* Macros and data structures used when freeing bits of base memory
* used by the UNDI driver.
*/
#define FIRING_SQUAD_TARGET_SIZE 8
#define FIRING_SQUAD_TARGET_INDEX(x) ( (x) / FIRING_SQUAD_TARGET_SIZE )
#define FIRING_SQUAD_TARGET_BIT(x) ( (x) % FIRING_SQUAD_TARGET_SIZE )
typedef struct firing_squad_lineup {
uint8_t targets[ 640 / FIRING_SQUAD_TARGET_SIZE ];
} firing_squad_lineup_t;
typedef enum firing_squad_shoot {
DONTSHOOT = 0,
SHOOT = 1
} firing_squad_shoot_t;
/* Driver private data structure.
*/
typedef struct undi {
/* Pointers to various data structures */
pnp_bios_t *pnp_bios;
rom_t *rom;
undi_rom_id_t *undi_rom_id;
pxe_t *pxe;
undi_call_info_t *undi_call_info;
pxenv_structure_t *pxs;
undi_base_mem_xmit_data_t *xmit_data;
/* Pointers and sizes to keep track of allocated base memory */
undi_base_mem_data_t *base_mem_data;
void *driver_code;
size_t driver_code_size;
void *driver_data;
size_t driver_data_size;
char *xmit_buffer;
/* Flags. We keep our own instead of trusting the UNDI driver
* to have implemented PXENV_UNDI_GET_STATE correctly. Plus
* there's the small issue of PXENV_UNDI_GET_STATE being the
* same API call as PXENV_STOP_UNDI...
*/
uint8_t prestarted; /* pxenv_start_undi() has been called */
uint8_t started; /* pxenv_undi_startup() has been called */
uint8_t initialized; /* pxenv_undi_initialize() has been called */
uint8_t opened; /* pxenv_undi_open() has been called */
/* Parameters that we need to store for future reference
*/
struct pci_device pci;
irq_t irq;
} undi_t;
/* Constants
*/
#define HUNT_FOR_PIXIES 0
#define HUNT_FOR_UNDI_ROMS 1
|