Browse Source

Updated to work with libprefix.

tags/v0.9.3
Michael Brown 18 years ago
parent
commit
9f86754f90
1 changed files with 179 additions and 186 deletions
  1. 179
    186
      src/arch/i386/prefix/pxeprefix.S

+ 179
- 186
src/arch/i386/prefix/pxeprefix.S View File

@@ -1,16 +1,9 @@
1
-/* Offsets of words containing ROM's CS and size (in 512 byte blocks)
2
- * from start of floppy boot block at 0x7c00
3
- * Offsets must match those in etherboot.h
4
- */
5
-#define FLOPPY_SEGMENT	0x7c0
6
-
7 1
 #define PXENV_UNDI_CLEANUP	0x02
8 2
 #define PXENV_UNDI_SHUTDOWN	0x05
9 3
 #define	PXENV_STOP_UNDI		0x15
10 4
 #define PXENV_UNLOAD_STACK	0x70
11 5
 #define PXENV_STOP_BASE		0x76
12 6
 
13
-#define PUSHA_SIZE		16
14 7
 #define PXE_STACK_MAGIC		0x57ac	/* 'STac' */
15 8
 
16 9
 	.text
@@ -22,21 +15,35 @@
22 15
  * Entry point:	set cs, ds, bp, print welcome message
23 16
  *****************************************************************************
24 17
  */	
25
-_prefix:
26
-	jmp	$FLOPPY_SEGMENT, $code_start-_prefix
18
+	jmp	$0x7c0, $code_start
27 19
 10:	.asciz	"PXE->EB "
28 20
 code_start:
29
-	pusha				/* Preserve all registers */
30
-	push	%ds
31
-	movw	%sp, %bp		/* %bp must be preserved, hence do
32
-					 * this after the pusha */
33
-	push	$PXE_STACK_MAGIC	/* PXE stack magic marker */
34
-
35
-	push	%cs			/* Set up data segment */
36
-	pop	%ds
37
-	mov	$0x40, %cx		/* Set up %fs for access to 40:13 */
38
-	mov	%cx, %fs
39
-	movw	$10b-_prefix, %si	/* Print welcome message */
21
+	/* Preserve registers for return to PXE stack */
22
+	pushfl
23
+	pushal
24
+	pushw	%gs
25
+	pushw	%fs
26
+	pushw	%es
27
+	pushw	%ds
28
+	pushw	%ss
29
+	pushw	%cs
30
+	pushw	$PXE_STACK_MAGIC	/* PXE stack magic marker */
31
+	/* Set up stack just below 0x7c00 */
32
+	pushw	%ss
33
+	popw	%es
34
+	movw	%sp, %di
35
+	xorw	%ax, %ax
36
+	movw	%ax, %ss
37
+	movw	$0x7c00, %sp
38
+	pushw	%es			/* Save old PXE stack pointer */
39
+	pushw	%di
40
+	/* Set up our other segment registers */
41
+	pushw	%cs
42
+	popw	%ds
43
+	movw	$0x40, %ax		/* BIOS data segment access */
44
+	movw	%ax, %fs
45
+	/* Print welcome message */
46
+	movw	$10b, %si
40 47
 	call	print_message
41 48
 
42 49
 /*****************************************************************************
@@ -44,12 +51,12 @@ code_start:
44 51
  *****************************************************************************
45 52
  */
46 53
 detect_pxe:
47
-	les	4+PUSHA_SIZE+2(%bp), %di /* !PXE structure */
54
+	les	%es:54(%di), %di /* !PXE structure */
48 55
 	cmpl	$0x45585021, %es:(%di)	/* '!PXE' signature */
49 56
 	je	detected_pxe
50
-	mov	$0x5650, %ax
57
+	movw	$0x5650, %ax
51 58
 	int	$0x1a
52
-	cmp	$0x564e, %ax
59
+	cmpw	$0x564e, %ax
53 60
 	jne	detected_nothing
54 61
 	cmpl	$0x4e455850, %es:(%bx)	/* 'PXEN' signature */
55 62
 	jne	detected_nothing
@@ -57,49 +64,45 @@ detect_pxe:
57 64
 	je	detected_pxenv
58 65
 
59 66
 detected_nothing:
60
-	movw	$10f-_prefix, %si
67
+	movw	$10f, %si
61 68
 	call	print_message
62 69
 	jmp	finished_with_error
63 70
 10:	.asciz	"No PXE "
64 71
 
65 72
 detected_pxenv: /* es:bx points to PXENV+ structure */
66
-	push	%es
67
-	push	%bx
68
-	push	%es:0x24(%bx)		/* UNDI code segment */
69
-	push	%es:0x26(%bx)		/* UNDI code size */
70
-	push	%es:0x20(%bx)		/* UNDI data segment */
71
-	push	%es:0x22(%bx)		/* UNDI data size */
73
+	pushw	%es
74
+	pushw	%bx
75
+	pushw	%es:0x24(%bx)		/* UNDI code segment */
76
+	pushw	%es:0x26(%bx)		/* UNDI code size */
77
+	pushw	%es:0x20(%bx)		/* UNDI data segment */
78
+	pushw	%es:0x22(%bx)		/* UNDI data size */
72 79
 	les	%es:0x0a(%bx), %di	/* Entry point to %es:%di */
73
-	movw	$10f-_prefix, %si
80
+	movw	$10f, %si
74 81
 	jmp	pxe_setup_done
75 82
 10:	.asciz	"PXENV+ "
76 83
 
77 84
 detected_pxe:	/* es:di points to !PXE structure */
78
-	push	%es
79
-	push	%di
80
-	push	%es:0x30(%di)		/* UNDI code segment */
81
-	push	%es:0x36(%di)		/* UNDI code size */
82
-	push	%es:0x28(%di)		/* UNDI data segment */
83
-	push	%es:0x2e(%di)		/* UNDI data size */
85
+	pushw	%es
86
+	pushw	%di
87
+	pushw	%es:0x30(%di)		/* UNDI code segment */
88
+	pushw	%es:0x36(%di)		/* UNDI code size */
89
+	pushw	%es:0x28(%di)		/* UNDI data segment */
90
+	pushw	%es:0x2e(%di)		/* UNDI data size */
84 91
 	les	%es:0x10(%di), %di	/* Entry point to %es:%di */
85
-	movw	$10f-_prefix, %si
92
+	movw	$10f, %si
86 93
 	jmp	pxe_setup_done
87 94
 10:	.asciz	"!PXE "
88 95
 
89 96
 pxe_setup_done:
90
-	mov	%es, pxe_entry_segment - _prefix
91
-	mov	%di, pxe_entry_offset - _prefix
92
-	pop	%ax
93
-	mov	%ax, undi_data_size - _prefix
94
-	pop	%ax
95
-	mov	%ax, undi_data_segment - _prefix
96
-	pop	%ax
97
-	mov	%ax, undi_code_size - _prefix
98
-	pop	%ax
99
-	mov	%ax, undi_code_segment - _prefix
97
+	movw	%es, pxe_entry_segment
98
+	movw	%di, pxe_entry_offset
99
+	popw	undi_data_size
100
+	popw	undi_data_segment
101
+	popw	undi_code_size
102
+	popw	undi_code_segment
100 103
 	call	print_message
101
-	pop	%di
102
-	pop	%es	/* Exit with %es:%di containing structure address */
104
+	popw	%di
105
+	popw	%es	/* Exit with %es:%di containing structure address */
103 106
 
104 107
 /*****************************************************************************
105 108
  * Print information about located structure
@@ -107,11 +110,11 @@ pxe_setup_done:
107 110
  */
108 111
 print_structure_information:
109 112
 	call	print_segoff	/* %es:%di contains address of structure */
110
-	les	%ds:(pxe_entry_segoff - _prefix), %di
113
+	les	pxe_entry_segoff, %di
111 114
 	call	print_segoff
112
-	les	%ds:(undi_code_segoff - _prefix), %di
115
+	les	undi_code_segoff, %di
113 116
 	call	print_segoff
114
-	les	%ds:(undi_data_segoff - _prefix), %di
117
+	les	undi_data_segoff, %di
115 118
 	call	print_segoff
116 119
 
117 120
 /*****************************************************************************
@@ -119,17 +122,17 @@ print_structure_information:
119 122
  *****************************************************************************
120 123
  */
121 124
 #ifdef PXELOADER_KEEP_ALL
122
-	xor	%ax, %ax		/* Force zero flag to show success */
125
+	xorw	%ax, %ax		/* Force zero flag to show success */
123 126
 	jmp	do_not_free_base_mem	/* Skip the unloading */
124 127
 #endif /* PXELOADER_KEEP_ALL */
125 128
 	
126 129
 unload_pxe:
127
-	mov	$PXENV_UNLOAD_STACK, %bx
130
+	movw	$PXENV_UNLOAD_STACK, %bx
128 131
 	call	pxe_call
129
-	mov	$PXENV_STOP_UNDI, %bx
132
+	movw	$PXENV_STOP_UNDI, %bx
130 133
 	call	pxe_call
131 134
 	pushfw				/* Ignore PXENV_UNDI_CLEANUP errors */
132
-	mov	$PXENV_UNDI_CLEANUP, %bx
135
+	movw	$PXENV_UNDI_CLEANUP, %bx
133 136
 	call	pxe_call
134 137
 	popfw
135 138
 	/* On exit, zero flag is set iff all calls were successful */
@@ -141,45 +144,45 @@ unload_pxe:
141 144
 free_base_mem:
142 145
 	jnz	do_not_free_base_mem	/* Using zero flag from unload_pxe */
143 146
 
144
-	mov	undi_code_segment - _prefix, %bx
145
-	mov	undi_data_segment - _prefix, %cx
146
-	mov	undi_code_size - _prefix, %ax
147
-	cmp	%bx, %cx
147
+	movw	undi_code_segment, %bx
148
+	movw	undi_data_segment, %cx
149
+	movw	undi_code_size, %ax
150
+	cmpw	%bx, %cx
148 151
 	jb	1f
149
-	mov	%cx, %bx
150
-	mov	undi_data_size - _prefix, %ax
151
-1:	add	$0x0f, %ax		/* Round up to next segment */
152
-	shr	$4, %ax
153
-	add	%bx, %ax		/* Highest segment address into %ax */
154
-	add	$(1024 / 16 - 1), %ax	/* Round up to next kb */
155
-	shr	$6, %ax			/* New free basemem size in %ax */
156
-	mov	%fs:(0x13), %bx		/* Old free base memory in %bx */
157
-	mov	%ax, %fs:(0x13)		/* Store new free base memory size */
152
+	movw	%cx, %bx
153
+	movw	undi_data_size, %ax
154
+1:	addw	$0x0f, %ax		/* Round up to next segment */
155
+	shrw	$4, %ax
156
+	addw	%bx, %ax		/* Highest segment address into %ax */
157
+	addw	$(1024 / 16 - 1), %ax	/* Round up to next kb */
158
+	shrw	$6, %ax			/* New free basemem size in %ax */
159
+	movw	%fs:(0x13), %bx		/* Old free base memory in %bx */
160
+	movw	%ax, %fs:(0x13)		/* Store new free base memory size */
158 161
 
159 162
 	/* Note that zero_mem_loop will also zero out our stack, so make
160 163
 	 * sure the stack is empty at this point.
161 164
 	 */
162
-	mov	%ax, %dx
163
-	sub	%bx, %dx		/* numberof kb to zero in %dx */
164
-	shl	$6, %bx			/* Segment address into %bx */
165
+	movw	%ax, %dx
166
+	subw	%bx, %dx		/* numberof kb to zero in %dx */
167
+	shlw	$6, %bx			/* Segment address into %bx */
165 168
 zero_mem_loop:
166
-	mov	%bx, %es		/* kB boundary into %es:00 */
167
-	xor	%ax, %ax
168
-	xor	%di, %di
169
-	mov	$0x400, %cx
169
+	movw	%bx, %es		/* kB boundary into %es:00 */
170
+	xorw	%ax, %ax
171
+	xorw	%di, %di
172
+	movw	$0x400, %cx
170 173
 	rep	stosb			/* fill kB with zeroes */
171
-	add	$(1024 / 16), %bx
172
-	dec	%dx
174
+	addw	$(1024 / 16), %bx
175
+	decw	%dx
173 176
 	jnz	zero_mem_loop
174 177
 	/* Will exit here with zero flag set, so no need to set it explicitly
175 178
 	 * in order to indicate success.
176 179
 	 */
177 180
 	
178 181
 do_not_free_base_mem:
179
-	pushf				/* Save success (zero) flag status */
180
-	mov	%fs:(0x13), %ax		/* Free base memory in %ax */
182
+	pushfw				/* Save success (zero) flag status */
183
+	movw	%fs:(0x13), %ax		/* Free base memory in %ax */
181 184
 	call	print_hex_word		/* Print free base memory */
182
-	popf				/* Restore success (zero) flag */
185
+	popfw				/* Restore success (zero) flag */
183 186
 
184 187
 /*****************************************************************************
185 188
  * Exit point
@@ -188,92 +191,16 @@ do_not_free_base_mem:
188 191
  *****************************************************************************
189 192
  */	
190 193
 finished:
191
-	movw	$10f-_prefix, %si
194
+	movw	$10f, %si
192 195
 	jz	1f
193 196
 finished_with_error:
194
-	movw	$20f-_prefix, %si
197
+	movw	$20f, %si
195 198
 1:
196 199
 	call	print_message
197
-	jmp	99f
200
+	jmp	run_etherboot
198 201
 10:	.asciz " ok\n"
199 202
 20:	.asciz " err\n"
200 203
 
201
-	
202
-	/* We place a stack here.  It doesn't get used until after all
203
-	 * the above code is finished, so we can happily write all
204
-	 * over it.  Putting the stack here ensures that it doesn't
205
-	 * accidentally go over the 512 byte threshold, which would
206
-	 * cause problems when returning via start32's prefix
207
-	 * relocation mechanism.
208
-	 */
209
-_estack:	
210
-99:
211
-
212
-/*****************************************************************************
213
- * Run Etherboot main code
214
- *****************************************************************************
215
- */	
216
-run_etherboot:
217
-	/* Very temporarily switch stacks to one internal to the
218
-	 * prefix.  Do this because the stack provided by the PXE ROM
219
-	 * could be absolutely anywhere, including in an area of
220
-	 * memory that the call to prelocate will vapourise...
221
-	 */
222
-	pushw	%ss			/* PXE stack pointer to ES:DI */
223
-	popw	%es
224
-	movw	%sp, %di
225
-	pushw	%ds			/* Set up stack in "safe" area */
226
-	popw	%ss
227
-	movw	$_estack-_prefix, %sp
228
-	pushw	%es			/* Record PXE stack pointer */
229
-	pushw	%di
230
-	/* Relocate payload and stack to claimed base memory */
231
-	pushw	$4			/* Preserve old PXE stack pointer */
232
-	call	prelocate
233
-	popw	%ax			/* Remove parameter */
234
-	pushl	$4			/* Preserve old PXE stack pointer */
235
-	pushw	$0			/* Indicate prefix exit mechanism */
236
-	jmp	_start			/* Run Etherboot */
237
-
238
-	.section ".text16", "ax", @progbits
239
-prefix_exit:
240
-	pushw	%cs			/* Set %ds, %bp for access to text */
241
-	popw	%ds
242
-	call	1f
243
-1:	popw	%bp
244
-	popw	%di			/* Old PXE stack to %es:di */
245
-	popw	%es
246
-	cmpw	$PXE_STACK_MAGIC, %es:0(%di)  /* See if PXE stack intact */
247
-	jne	exit_via_int18
248
-exit_via_pxe:				/* Stack OK, return to PXE */
249
-	push	%es			/* Restore PXE stack pointer */
250
-	pop	%ss
251
-	mov	%di, %sp
252
-	pop	%ax			/* Discard PXE_STACK_MAGIC marker */
253
-	leaw	(10f-1b)(%bp), %si
254
-	call	print_exit_message
255
-	pop	%ds			/* Restore PXE's DS */
256
-	popa				/* Restore PXE's other registers */
257
-	movw	$0, %ax			/* Return PXENV_STATUS_SUCCESS */
258
-	lret				/* Return control to PXE ROM */
259
-10:	.asciz	"EB->PXE\r\n"
260
-exit_via_int18:				/* Stack damaged, do int 18 */
261
-	leaw	(10f-1b)(%bp), %si
262
-	call	print_exit_message
263
-	int	$0x18
264
-10:	.asciz	"EB->BIOS\r\n"
265
-print_exit_message:	
266
-	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */
267
-	movb	$0x0e, %ah		/* write char, tty mode */
268
-1: 	lodsb
269
-	testb	%al, %al
270
-	je	2f
271
-	int	$0x10
272
-	jmp	1b
273
-2:	ret
274
-prefix_exit_end:
275
-	.previous
276
-
277 204
 /*****************************************************************************
278 205
  * Subroutine: print character in %al (with LF -> LF,CR translation)
279 206
  *****************************************************************************
@@ -305,17 +232,17 @@ print_message:
305 232
  *****************************************************************************
306 233
  */
307 234
 print_hex_word:
308
-	mov	$4, %cx
235
+	movw	$4, %cx
309 236
 1:
310
-	push	%ax
311
-	shr	$12, %ax
237
+	pushw	%ax
238
+	shrw	$12, %ax
312 239
 	/* Courtesy of Norbert Juffa <norbert.juffa@amd.com> */
313
-	cmp	$10, %al	
314
-	sbb	$0x69, %al
240
+	cmpb	$10, %al	
241
+	sbbb	$0x69, %al
315 242
 	das
316 243
 	call	print_character
317
-	pop	%ax
318
-	shl	$4, %ax
244
+	popw	%ax
245
+	shlw	$4, %ax
319 246
 	loop	1b
320 247
 	ret
321 248
 	
@@ -324,15 +251,15 @@ print_hex_word:
324 251
  *****************************************************************************
325 252
  */
326 253
 print_segoff:
327
-	push	%di
328
-	push	%es
329
-	pop	%ax
254
+	pushw	%di
255
+	pushw	%es
256
+	popw	%ax
330 257
 	call	print_hex_word
331 258
 	movb	$0x3a,%al			/* ':' */
332 259
 	call	print_character
333
-	pop	%ax
260
+	popw	%ax
334 261
 	call	print_hex_word
335
-	mov	$0x20, %al			/* ' ' */
262
+	movb	$0x20, %al			/* ' ' */
336 263
 	call	print_character
337 264
 	ret
338 265
 	
@@ -346,24 +273,24 @@ print_segoff:
346 273
  */
347 274
 pxe_call:
348 275
 	/* Set up registers for PXENV+ API.  %bx already set up */
349
-	push	%ds
350
-	pop	%es
351
-	mov	$pxe_parameter_structure - _prefix, %di
276
+	pushw	%ds
277
+	popw	%es
278
+	movw	$pxe_parameter_structure, %di
352 279
 	/* Set up stack for !PXE API */
353 280
 	pushw   %cs
354 281
 	pushw	%di
355 282
 	pushw	%bx
356 283
 	/* Make the API call */
357
-	lcall	*(pxe_entry_segoff - _prefix)
284
+	lcall	*pxe_entry_segoff
358 285
 	/* Reset the stack */
359
-	add	$6, %sp
360
-	mov	pxe_parameter_structure - _prefix, %ax
361
-	push	%ax
286
+	addw	$6, %sp
287
+	movw	pxe_parameter_structure, %ax
288
+	pushw	%ax
362 289
 	call	print_hex_word
363
-	mov	$0x20, %ax		/* ' ' */
290
+	movw	$0x20, %ax		/* ' ' */
364 291
 	call	print_character
365
-	pop	%bx
366
-	or	%bx, pxe_overall_status - _prefix
292
+	popw	%bx
293
+	orw	%bx, pxe_overall_status
367 294
 	ret
368 295
 
369 296
 /*****************************************************************************
@@ -389,7 +316,73 @@ pxe_parameter_structure:
389 316
 	.word	0
390 317
 	.word	0,0,0,0,0
391 318
 
392
-end_of_pxeloader:
319
+/*****************************************************************************
320
+ * Run Etherboot main code
321
+ *****************************************************************************
322
+ */	
323
+run_etherboot:
324
+	/* Install Etherboot */
325
+	call	install
326
+
327
+	/* Jump to .text16 segment with %ds pointing to .data16*/
328
+	movw	%bx, %ds
329
+	pushw	%ax
330
+	pushw	$1f
331
+	lret
332
+	.section ".text16", "ax", @progbits
333
+1:
334
+	/* Original PXE stack pointer to es:di.  We must hold it in
335
+	 * registers, because our current stack may be vapourised by
336
+	 * the time main() returns.  (main() will still be able to
337
+	 * return, because prot_call() transfers the return address to
338
+	 * the internal stack and back again).
339
+	 */
340
+	popw	%di
341
+	popw	%es
342
+
343
+	/* Run main program */
344
+	pushl	$main
345
+	pushw	%cs
346
+	call	prot_call
347
+	popl	%eax /* discard */
348
+
349
+	/* If original PXE stack is intact, return via PXE, else via INT 18 */
350
+	cmpw	$PXE_STACK_MAGIC, %es:0(%di)
351
+	jne	exit_via_int18
352
+exit_via_pxe:				/* Stack OK, return to PXE */
353
+	movw	$exit_via_pxe_message, %si
354
+	call	print_exit_message
355
+	pushw	%es			/* Restore original PXE stack */
356
+	popw	%ss
357
+	movw	%di, %sp
358
+	popw	%ax /* discard PXE_STACK_MAGIC */
359
+	popw	%ax /* discard %cs */
360
+	popw	%ax /* discard %ss */
361
+	popw	%ds
362
+	popw	%es
363
+	popw	%fs
364
+	popw	%gs
365
+	popal
366
+	popfl
367
+	xorw	%ax, %ax		/* Return PXENV_STATUS_SUCCESS */
368
+	lret
369
+exit_via_int18:				/* Stack damaged, do int 18 */
370
+	movw	$exit_via_int18_message, %si
371
+	call	print_exit_message
372
+	int	$0x18
373
+
374
+print_exit_message:	
375
+	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */
376
+	movb	$0x0e, %ah		/* write char, tty mode */
377
+1: 	lodsb
378
+	testb	%al, %al
379
+	je	2f
380
+	int	$0x10
381
+	jmp	1b
382
+2:	ret
393 383
 
394
-	.balign 16, 0
395
-payload:
384
+	.section ".data16", "aw", @progbits
385
+exit_via_pxe_message:
386
+	.asciz	"EB->PXE\r\n"
387
+exit_via_int18_message:
388
+	.asciz	"EB->BIOS\r\n"

Loading…
Cancel
Save