Browse Source

Obsoleted by arch/i386/interface/pxe/pxe_call.c

tags/v0.9.3
Michael Brown 18 years ago
parent
commit
2e088d9afc
1 changed files with 0 additions and 391 deletions
  1. 0
    391
      src/arch/i386/core/pxe_callbacks.c

+ 0
- 391
src/arch/i386/core/pxe_callbacks.c View File

@@ -1,391 +0,0 @@
1
-/* PXE callback mechanisms.  This file contains only the portions
2
- * specific to i386: i.e. the low-level mechanisms for calling in from
3
- * an NBP to the PXE stack and for starting an NBP from the PXE stack.
4
- */
5
-
6
-#warning "pxe_callbacks.c is temporarily broken"
7
-
8
-void xstartpxe ( void ) {
9
-}
10
-
11
-void install_pxe_stack ( void ) {
12
-}
13
-
14
-void remove_pxe_stack ( void ) {
15
-}
16
-
17
-void hook_pxe_stack ( void ) {
18
-}
19
-
20
-void unhook_pxe_stack ( void ) {
21
-}
22
-
23
-void pxe_in_call ( void ) {
24
-}
25
-
26
-void use_undi_ds_for_rm_stack ( void ) {
27
-}
28
-
29
-#if 0
30
-
31
-#ifdef PXE_EXPORT
32
-
33
-#include "etherboot.h"
34
-#include "callbacks.h"
35
-#include "realmode.h"
36
-#include "pxe.h"
37
-#include "pxe_callbacks.h"
38
-#include "pxe_export.h"
39
-#include "hidemem.h"
40
-#include <stdarg.h>
41
-
42
-#define INSTALLED(x) ( (typeof(&x)) ( (void*)(&x) \
43
-				      - &pxe_callback_interface \
44
-				      + (void*)&pxe_stack->arch_data ) )
45
-#define pxe_intercept_int1a	INSTALLED(_pxe_intercept_int1a)
46
-#define pxe_intercepted_int1a	INSTALLED(_pxe_intercepted_int1a)
47
-#define pxe_pxenv_location	INSTALLED(_pxe_pxenv_location)
48
-#define INT1A_VECTOR ( (segoff_t*) ( phys_to_virt( 4 * 0x1a ) ) )
49
-
50
-/* The overall size of the PXE stack is ( sizeof(pxe_stack_t) +
51
- * pxe_callback_interface_size + rm_callback_interface_size ).
52
- * Unfortunately, this isn't a compile-time constant, since
53
- * {pxe,rm}_callback_interface_size depend on the length of the
54
- * assembly code in these interfaces.
55
- *
56
- * We used to have a function pxe_stack_size() which returned this
57
- * value.  However, it actually needs to be a link-time constant, so
58
- * that it can appear in the UNDIROMID structure in romprefix.S.  We
59
- * therefore export the three component sizes as absolute linker
60
- * symbols, get the linker to add them together and generate a new
61
- * absolute symbol _pxe_stack_size.  We then import this value into a
62
- * C variable pxe_stack_size, for access from C code.
63
- */
64
-
65
-/* gcc won't let us use extended asm outside a function (compiler
66
- * bug), ao we have to put these asm statements inside a dummy
67
- * function.
68
- */
69
-static void work_around_gcc_bug ( void ) __attribute__ ((used));
70
-static void work_around_gcc_bug ( void ) {
71
-	/* Export sizeof(pxe_stack_t) as absolute linker symbol */
72
-	__asm__ ( ".globl _pxe_stack_t_size" );
73
-	__asm__ ( ".equ _pxe_stack_t_size, %c0"
74
-		  : : "i" (sizeof(pxe_stack_t)) );
75
-}
76
-/* Import _pxe_stack_size absolute linker symbol into C variable */
77
-extern int pxe_stack_size;
78
-__asm__ ( "pxe_stack_size: .long _pxe_stack_size" );
79
-
80
-/* Utility routine: byte checksum
81
- */
82
-uint8_t byte_checksum ( void *address, size_t size ) {
83
-	unsigned int i, sum = 0;
84
-
85
-	for ( i = 0; i < size; i++ ) {
86
-		sum += ((uint8_t*)address)[i];
87
-	}
88
-	return (uint8_t)sum;
89
-}
90
-
91
-/* install_pxe_stack(): install PXE stack.
92
- * 
93
- * Use base = NULL for auto-allocation of base memory
94
- *
95
- * IMPORTANT: no further allocation of base memory should take place
96
- * before the PXE stack is removed.  This is to work around a small
97
- * but important deficiency in the PXE specification.
98
- */
99
-pxe_stack_t * install_pxe_stack ( void *base ) {
100
-	pxe_t *pxe;
101
-	pxenv_t *pxenv;
102
-	void *pxe_callback_code;
103
-	void (*pxe_in_call_far)(void);
104
-	void (*pxenv_in_call_far)(void);
105
-	void *rm_callback_code;
106
-	void *e820mangler_code;
107
-	void *end;
108
-
109
-	/* If already installed, just return */
110
-	if ( pxe_stack != NULL ) return pxe_stack;
111
-
112
-	/* Allocate base memory if requested to do so
113
-	 */
114
-	if ( base == NULL ) {
115
-		base = allot_base_memory ( pxe_stack_size );
116
-		if ( base == NULL ) return NULL;
117
-	}
118
-
119
-	/* Round address up to 16-byte physical alignment */
120
-	pxe_stack = (pxe_stack_t *)
121
-		( phys_to_virt ( ( virt_to_phys(base) + 0xf ) & ~0xf ) );
122
-	/* Zero out allocated stack */
123
-	memset ( pxe_stack, 0, sizeof(*pxe_stack) );
124
-	
125
-	/* Calculate addresses for portions of the stack */
126
-	pxe = &(pxe_stack->pxe);
127
-	pxenv = &(pxe_stack->pxenv);
128
-	pxe_callback_code = &(pxe_stack->arch_data);
129
-	pxe_in_call_far = _pxe_in_call_far +  
130
-		( pxe_callback_code - &pxe_callback_interface );
131
-	pxenv_in_call_far = _pxenv_in_call_far +
132
-		( pxe_callback_code - &pxe_callback_interface );
133
-	rm_callback_code = pxe_callback_code + pxe_callback_interface_size;
134
-	
135
-	e820mangler_code = (void*)(((int)rm_callback_code +
136
-				    rm_callback_interface_size + 0xf ) & ~0xf);
137
-	end = e820mangler_code + e820mangler_size;
138
-
139
-	/* Initialise !PXE data structures */
140
-	memcpy ( pxe->Signature, "!PXE", 4 );
141
-	pxe->StructLength = sizeof(*pxe);
142
-	pxe->StructRev = 0;
143
-	pxe->reserved_1 = 0;
144
-	/* We don't yet have an UNDI ROM ID structure */
145
-	pxe->UNDIROMID.segment = 0;
146
-	pxe->UNDIROMID.offset = 0;
147
-	/* or a BC ROM ID structure */
148
-	pxe->BaseROMID.segment = 0;
149
-	pxe->BaseROMID.offset = 0;
150
-	pxe->EntryPointSP.segment = SEGMENT(pxe_stack);
151
-	pxe->EntryPointSP.offset = (void*)pxe_in_call_far - (void*)pxe_stack;
152
-	/* No %esp-compatible entry point yet */
153
-	pxe->EntryPointESP.segment = 0;
154
-	pxe->EntryPointESP.offset = 0;
155
-	pxe->StatusCallout.segment = -1;
156
-	pxe->StatusCallout.offset = -1;
157
-	pxe->reserved_2 = 0;
158
-	pxe->SegDescCn = 7;
159
-	pxe->FirstSelector = 0;
160
-	/* PXE specification doesn't say anything about when the stack
161
-	 * space should get freed.  We work around this by claiming it
162
-	 * as our data segment as well.
163
-	 */
164
-	pxe->Stack.Seg_Addr = pxe->UNDIData.Seg_Addr = real_mode_stack >> 4;
165
-	pxe->Stack.Phy_Addr = pxe->UNDIData.Phy_Addr = real_mode_stack;
166
-	pxe->Stack.Seg_Size = pxe->UNDIData.Seg_Size = real_mode_stack_size;
167
-	/* Code segment has to be the one containing the data structures... */
168
-	pxe->UNDICode.Seg_Addr = SEGMENT(pxe_stack);
169
-	pxe->UNDICode.Phy_Addr = virt_to_phys(pxe_stack);
170
-	pxe->UNDICode.Seg_Size = end - (void*)pxe_stack;
171
-	/* No base code loaded */
172
-	pxe->BC_Data.Seg_Addr = 0;
173
-	pxe->BC_Data.Phy_Addr = 0;
174
-	pxe->BC_Data.Seg_Size = 0;
175
-	pxe->BC_Code.Seg_Addr = 0;
176
-	pxe->BC_Code.Phy_Addr = 0;
177
-	pxe->BC_Code.Seg_Size = 0;
178
-	pxe->BC_CodeWrite.Seg_Addr = 0;
179
-	pxe->BC_CodeWrite.Phy_Addr = 0;
180
-	pxe->BC_CodeWrite.Seg_Size = 0;
181
-	pxe->StructCksum -= byte_checksum ( pxe, sizeof(*pxe) );
182
-
183
-	/* Initialise PXENV+ data structures */
184
-	memcpy ( pxenv->Signature, "PXENV+", 6 );
185
-	pxenv->Version = 0x201;
186
-	pxenv->Length = sizeof(*pxenv);
187
-	pxenv->RMEntry.segment = SEGMENT(pxe_stack);
188
-	pxenv->RMEntry.offset = (void*)pxenv_in_call_far - (void*)pxe_stack;
189
-	pxenv->PMOffset = 0; /* "Do not use" says the PXE spec */
190
-	pxenv->PMSelector = 0; /* "Do not use" says the PXE spec */
191
-	pxenv->StackSeg = pxenv->UNDIDataSeg = real_mode_stack >> 4;
192
-	pxenv->StackSize = pxenv->UNDIDataSize = real_mode_stack_size;
193
-	pxenv->BC_CodeSeg = 0;
194
-	pxenv->BC_CodeSize = 0;
195
-	pxenv->BC_DataSeg = 0;
196
-	pxenv->BC_DataSize = 0;
197
-	/* UNDIData{Seg,Size} set above */
198
-	pxenv->UNDICodeSeg = SEGMENT(pxe_stack);
199
-	pxenv->UNDICodeSize = end - (void*)pxe_stack;
200
-	pxenv->PXEPtr.segment = SEGMENT(pxe);
201
-	pxenv->PXEPtr.offset = OFFSET(pxe);
202
-	pxenv->Checksum -= byte_checksum ( pxenv, sizeof(*pxenv) );
203
-
204
-	/* Mark stack as inactive */
205
-	pxe_stack->state = CAN_UNLOAD;
206
-
207
-	/* Install PXE and RM callback code and E820 mangler */
208
-	memcpy ( pxe_callback_code, &pxe_callback_interface,
209
-		 pxe_callback_interface_size );
210
-	install_rm_callback_interface ( rm_callback_code, 0 );
211
-	install_e820mangler ( e820mangler_code );
212
-
213
-	return pxe_stack;
214
-}
215
-
216
-/* Use the UNDI data segment as our real-mode stack.  This is for when
217
- * we have been loaded via the UNDI loader
218
- */
219
-void use_undi_ds_for_rm_stack ( uint16_t ds ) {
220
-	forget_real_mode_stack();
221
-	real_mode_stack = virt_to_phys ( VIRTUAL ( ds, 0 ) );
222
-	lock_real_mode_stack = 1;
223
-}
224
-
225
-/* Activate PXE stack (i.e. hook interrupt vectors).  The PXE stack
226
- * *can* be used before it is activated, but it really shoudln't.
227
- */
228
-int hook_pxe_stack ( void ) {
229
-	if ( pxe_stack == NULL ) return 0;
230
-	if ( pxe_stack->state >= MIDWAY ) return 1;
231
-
232
-	/* Hook INT15 handler */
233
-	hide_etherboot();
234
-
235
-	/* Hook INT1A handler */
236
-	*pxe_intercepted_int1a = *INT1A_VECTOR;
237
-	pxe_pxenv_location->segment = SEGMENT(pxe_stack);
238
-	pxe_pxenv_location->offset = (void*)&pxe_stack->pxenv
239
-		- (void*)pxe_stack;
240
-	INT1A_VECTOR->segment = SEGMENT(&pxe_stack->arch_data);
241
-	INT1A_VECTOR->offset = (void*)pxe_intercept_int1a
242
-		- (void*)&pxe_stack->arch_data;
243
-
244
-	/* Mark stack as active */
245
-	pxe_stack->state = MIDWAY;
246
-	return 1;
247
-}
248
-
249
-/* Deactivate the PXE stack (i.e. unhook interrupt vectors).
250
- */
251
-int unhook_pxe_stack ( void ) {
252
-	if ( pxe_stack == NULL ) return 0;
253
-	if ( pxe_stack->state <= CAN_UNLOAD ) return 1;
254
-
255
-	/* Restore original INT15 and INT1A handlers */
256
-	*INT1A_VECTOR = *pxe_intercepted_int1a;
257
-	if ( !unhide_etherboot() ) {
258
-		/* Cannot unhook INT15.  We're up the creek without
259
-		 * even a suitable log out of which to fashion a
260
-		 * paddle.  There are some very badly behaved NBPs
261
-		 * that will ignore plaintive pleas such as
262
-		 * PXENV_KEEP_UNDI and just zero out our code anyway.
263
-		 * This means they end up vapourising an active INT15
264
-		 * handler, which is generally not a good thing to do.
265
-		 */
266
-		return 0;
267
-	}
268
-
269
-	/* Mark stack as inactive */
270
-	pxe_stack->state = CAN_UNLOAD;
271
-	return 1;
272
-}
273
-
274
-/* remove_pxe_stack(): remove PXE stack installed by install_pxe_stack()
275
- */
276
-void remove_pxe_stack ( void ) {
277
-	/* Ensure stack is deactivated, then free up the memory */
278
-	if ( ensure_pxe_state ( CAN_UNLOAD ) ) {
279
-		forget_base_memory ( pxe_stack, pxe_stack_size );
280
-		pxe_stack = NULL;
281
-	} else {
282
-		printf ( "Cannot remove PXE stack!\n" );
283
-	}
284
-}
285
-
286
-/* xstartpxe(): start up a PXE image
287
- */
288
-int xstartpxe ( void ) {
289
-	int nbp_exit;
290
-	struct {
291
-		reg16_t bx;
292
-		reg16_t es;
293
-		segoff_t pxe;
294
-	} PACKED in_stack;
295
-	
296
-	/* Set up registers and stack parameters to pass to PXE NBP */
297
-	in_stack.es.word = SEGMENT(&(pxe_stack->pxenv));
298
-	in_stack.bx.word = OFFSET(&(pxe_stack->pxenv));
299
-	in_stack.pxe.segment = SEGMENT(&(pxe_stack->pxe));
300
-	in_stack.pxe.offset = OFFSET(&(pxe_stack->pxe));
301
-
302
-	/* Real-mode trampoline fragment used to jump to PXE NBP
303
-	 */
304
-	RM_FRAGMENT(jump_to_pxe_nbp, 
305
-		"popw %bx\n\t"
306
-		"popw %es\n\t"
307
-		"lcall $" RM_STR(PXE_LOAD_SEGMENT) ", $" RM_STR(PXE_LOAD_OFFSET) "\n\t"
308
-	);
309
-
310
-	/* Call to PXE image */
311
-	gateA20_unset();
312
-	nbp_exit = real_call ( jump_to_pxe_nbp, &in_stack, NULL );
313
-	gateA20_set();
314
-
315
-	return nbp_exit;
316
-}
317
-
318
-int pxe_in_call ( in_call_data_t *in_call_data, va_list params ) {
319
-	/* i386 calling conventions; the only two defined by Intel's
320
-	 * PXE spec.
321
-	 *
322
-	 * Assembly code must pass a long containing the PXE version
323
-	 * code (i.e. 0x201 for !PXE, 0x200 for PXENV+) as the first
324
-	 * parameter after the in_call opcode.  This is used to decide
325
-	 * whether to take parameters from the stack (!PXE) or from
326
-	 * registers (PXENV+).
327
-	 */
328
-	uint32_t api_version = va_arg ( params, typeof(api_version) );
329
-	uint16_t opcode;
330
-	segoff_t segoff;
331
-	t_PXENV_ANY *structure;
332
-		
333
-	if ( api_version >= 0x201 ) {
334
-		/* !PXE calling convention */
335
-		pxe_call_params_t pxe_params
336
-			= va_arg ( params, typeof(pxe_params) );
337
-		opcode = pxe_params.opcode;
338
-		segoff = pxe_params.segoff;
339
-	} else {
340
-		/* PXENV+ calling convention */
341
-		opcode = in_call_data->pm->regs.bx;
342
-		segoff.segment = in_call_data->rm->seg_regs.es;
343
-		segoff.offset = in_call_data->pm->regs.di;
344
-	}
345
-	structure = VIRTUAL ( segoff.segment, segoff.offset );
346
-	return pxe_api_call ( opcode, structure );
347
-}
348
-
349
-#ifdef TEST_EXCLUDE_ALGORITHM
350
-/* This code retained because it's a difficult algorithm to tweak with
351
- * confidence
352
- */
353
-int ___test_exclude ( int start, int len, int estart, int elen, int fixbase );
354
-void __test_exclude ( int start, int len, int estart, int elen, int fixbase ) {
355
-	int newrange = ___test_exclude ( start, len, estart, elen, fixbase );
356
-	int newstart = ( newrange >> 16 ) & 0xffff;
357
-	int newlen = ( newrange & 0xffff );
358
-
359
-	printf ( "[%x,%x): excluding [%x,%x) %s gives [%x,%x)\n",
360
-		 start, start + len,
361
-		 estart, estart + elen,
362
-		 ( fixbase == 0 ) ? "  " : "fb",
363
-		 newstart, newstart + newlen );
364
-}
365
-void _test_exclude ( int start, int len, int estart, int elen ) {
366
-	__test_exclude ( start, len, estart, elen, 0 );
367
-	__test_exclude ( start, len, estart, elen, 1 );
368
-}
369
-void test_exclude ( void ) {
370
-	_test_exclude ( 0x8000, 0x1000, 0x0400, 0x200 ); /* before */
371
-	_test_exclude ( 0x8000, 0x1000, 0x9000, 0x200 ); /* after */
372
-	_test_exclude ( 0x8000, 0x1000, 0x7f00, 0x200 ); /* before overlap */
373
-	_test_exclude ( 0x8000, 0x1000, 0x8f00, 0x200 ); /* after overlap */
374
-	_test_exclude ( 0x8000, 0x1000, 0x8000, 0x200 ); /* align start */
375
-	_test_exclude ( 0x8000, 0x1000, 0x8e00, 0x200 ); /* align end */
376
-	_test_exclude ( 0x8000, 0x1000, 0x8100, 0x200 ); /* early overlap */
377
-	_test_exclude ( 0x8000, 0x1000, 0x8d00, 0x200 ); /* late overlap */
378
-	_test_exclude ( 0x8000, 0x1000, 0x7000, 0x3000 ); /* total overlap */
379
-	_test_exclude ( 0x8000, 0x1000, 0x8000, 0x1000 ); /* exact overlap */
380
-}
381
-#endif /* TEST_EXCLUDE_ALGORITHM */
382
-
383
-#else /* PXE_EXPORT */
384
-
385
-/* Define symbols used by the linker scripts, to prevent link errors */
386
-__asm__ ( ".globl _pxe_stack_t_size" );
387
-__asm__ ( ".equ _pxe_stack_t_size, 0" );
388
-
389
-#endif /* PXE_EXPORT */
390
-
391
-#endif /* 0 */

Loading…
Cancel
Save