Browse Source

Merge branch 'pxerom-pmm'

tags/v0.9.4
Michael Brown 16 years ago
parent
commit
08b19abf94

+ 265
- 136
src/arch/i386/prefix/libprefix.S View File

@@ -17,6 +17,10 @@
17 17
  *
18 18
  */
19 19
 
20
+	.arch i386
21
+	.section ".prefix.lib", "awx", @progbits
22
+	.section ".data16", "aw", @progbits
23
+
20 24
 /**
21 25
  * High memory temporary load address
22 26
  *
@@ -27,24 +31,125 @@
27 31
  * We use the start of an even megabyte so that we don't have to worry
28 32
  * about the current state of the A20 line.
29 33
  *
30
- * We use 4MB rather than 2MB because there is at least one commercial
31
- * PXE ROM ("Broadcom UNDI, PXE-2.1 (build 082) v2.0.4") which stores
32
- * data required by the UNDI ROM loader (yes, the ROM loader; that's
33
- * the component which should be impossible to damage short of
34
- * screwing with the MMU) around the 2MB mark.  Sadly, this is not a
35
- * joke.
36
- *
34
+ * We use 4MB rather than 2MB because some PXE stack / PMM BIOS
35
+ * combinations are known to place data required by other UNDI ROMs
36
+ * loader around the 2MB mark.
37 37
  */
38
-#define HIGHMEM_LOADPOINT ( 4 << 20 )
38
+	.globl	HIGHMEM_LOADPOINT
39
+	.equ	HIGHMEM_LOADPOINT, ( 4 << 20 )
39 40
 
40 41
 /* Image compression enabled */
41 42
 #define COMPRESS 1
42 43
 
43 44
 #define CR0_PE 1
44 45
 
45
-	.arch i386
46
-	.section ".prefix.lib", "awx", @progbits
47
-	.section ".data16", "aw", @progbits
46
+/*****************************************************************************
47
+ * Utility function: print character (with LF -> LF,CR translation)
48
+ *
49
+ * Parameters:
50
+ *   %al : character to print
51
+ * Returns:
52
+ *   Nothing
53
+ * Corrupts:
54
+ *   %ax
55
+ *****************************************************************************
56
+ */
57
+	.section ".prefix.lib"
58
+	.code16
59
+	.globl	print_character
60
+print_character:
61
+	/* Preserve registers */
62
+	pushw	%bx
63
+	pushw	%bp
64
+	/* Print character */
65
+	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */
66
+	movb	$0x0e, %ah		/* write char, tty mode */
67
+	cmpb	$0x0a, %al		/* '\n'? */
68
+	jne	1f
69
+	int	$0x10
70
+	movb	$0x0d, %al
71
+1:	int	$0x10
72
+	/* Restore registers and return */
73
+	popw	%bp
74
+	popw	%bx
75
+	ret
76
+	.size	print_character, . - print_character
77
+
78
+/*****************************************************************************
79
+ * Utility function: print a NUL-terminated string
80
+ *
81
+ * Parameters:
82
+ *   %ds:si : string to print
83
+ * Returns:
84
+ *   %ds:si : character after terminating NUL
85
+ *****************************************************************************
86
+ */
87
+	.section ".prefix.lib"
88
+	.code16
89
+	.globl	print_message
90
+print_message:
91
+	/* Preserve registers */
92
+	pushw	%ax
93
+	/* Print string */
94
+1: 	lodsb
95
+	testb	%al, %al
96
+	je	2f
97
+	call	print_character
98
+	jmp	1b
99
+2:	/* Restore registers and return */
100
+	popw	%ax
101
+	ret
102
+	.size	print_message, . - print_message
103
+
104
+/*****************************************************************************
105
+ * Utility functions: print hex digit/byte/word/dword
106
+ *
107
+ * Parameters:
108
+ *   %al (low nibble) : digit to print
109
+ *   %al : byte to print
110
+ *   %ax : word to print
111
+ *   %eax : dword to print
112
+ * Returns:
113
+ *   Nothing
114
+ *****************************************************************************
115
+ */
116
+	.section ".prefix.lib"
117
+	.code16
118
+	.globl	print_hex_dword
119
+print_hex_dword:
120
+	rorl	$16, %eax
121
+	call	print_hex_word
122
+	rorl	$16, %eax
123
+	/* Fall through */
124
+	.size	print_hex_dword, . - print_hex_dword
125
+	.globl	print_hex_word
126
+print_hex_word:
127
+	xchgb	%al, %ah
128
+	call	print_hex_byte
129
+	xchgb	%al, %ah
130
+	/* Fall through */
131
+	.size	print_hex_word, . - print_hex_word
132
+	.globl	print_hex_byte
133
+print_hex_byte:
134
+	rorb	$4, %al
135
+	call	print_hex_nibble
136
+	rorb	$4, %al
137
+	/* Fall through */
138
+	.size	print_hex_byte, . - print_hex_byte
139
+	.globl	print_hex_nibble
140
+print_hex_nibble:
141
+	/* Preserve registers */
142
+	pushw	%ax
143
+	/* Print digit (technique by Norbert Juffa <norbert.juffa@amd.com> */
144
+	andb	$0x0f, %al
145
+	cmpb	$10, %al
146
+	sbbb	$0x69, %al
147
+	das
148
+	call	print_character
149
+	/* Restore registers and return */
150
+	popw	%ax
151
+	ret
152
+	.size	print_hex_nibble, . - print_hex_nibble
48 153
 
49 154
 /****************************************************************************
50 155
  * pm_call (real-mode near call)
@@ -70,13 +175,14 @@
70 175
 #ifndef KEEP_IT_REAL
71 176
 
72 177
 	/* GDT for protected-mode calls */
73
-	.section ".data16"
178
+	.section ".prefix.lib"
74 179
 	.align 16
180
+pm_call_vars:
75 181
 gdt:
76 182
 gdt_limit:		.word gdt_length - 1
77 183
 gdt_base:		.long 0
78 184
 			.word 0 /* padding */
79
-pm_cs:		/* 16-bit protected-mode code segment */
185
+pm_cs:		/* 16-bit protected-mode code segment */	
80 186
 	.equ    PM_CS, pm_cs - gdt
81 187
 	.word   0xffff, 0
82 188
 	.byte   0, 0x9b, 0x00, 0
@@ -92,18 +198,24 @@ gdt_end:
92 198
 	.equ	gdt_length, . - gdt
93 199
 	.size	gdt, . - gdt
94 200
 
95
-	.section ".data16"
201
+	.section ".prefix.lib"
96 202
 	.align 16
97 203
 pm_saved_gdt:	
98 204
 	.long	0, 0
99 205
 	.size	pm_saved_gdt, . - pm_saved_gdt
100 206
 
207
+	.equ	pm_call_vars_size, . - pm_call_vars
208
+#define PM_CALL_VAR(x) ( -pm_call_vars_size + ( (x) - pm_call_vars ) )
209
+
101 210
 	.section ".prefix.lib"
102 211
 	.code16
103 212
 pm_call:
104
-	/* Preserve registers, flags, GDT, and RM return point */
213
+	/* Preserve registers, flags, and RM return point */
214
+	pushw	%bp
215
+	movw	%sp, %bp
216
+	subw	$pm_call_vars_size, %sp
217
+	andw	$0xfff0, %sp
105 218
 	pushfl
106
-	sgdt	pm_saved_gdt
107 219
 	pushw	%gs
108 220
 	pushw	%fs
109 221
 	pushw	%es
@@ -112,27 +224,43 @@ pm_call:
112 224
 	pushw	%cs
113 225
 	pushw	$99f
114 226
 
227
+	/* Set up local variable block, and preserve GDT */
228
+	pushw	%cx
229
+	pushw	%si
230
+	pushw	%di
231
+	pushw	%ss
232
+	popw	%es
233
+	movw	$pm_call_vars, %si
234
+	leaw	PM_CALL_VAR(pm_call_vars)(%bp), %di
235
+	movw	$pm_call_vars_size, %cx
236
+	cs rep movsb
237
+	popw	%di
238
+	popw	%si
239
+	popw	%cx
240
+	sgdt	PM_CALL_VAR(pm_saved_gdt)(%bp)
241
+
115 242
 	/* Set up GDT bases */
116 243
 	pushl	%eax
117
-	pushw	%bx
244
+	pushl	%edi
118 245
 	xorl	%eax, %eax
119
-	movw	%ds, %ax
246
+	movw	%ss, %ax
120 247
 	shll	$4, %eax
121
-	addl	$gdt, %eax
122
-	movl	%eax, gdt_base
248
+	movzwl	%bp, %edi
249
+	leal	PM_CALL_VAR(gdt)(%eax, %edi), %eax
250
+	movl	%eax, PM_CALL_VAR(gdt_base)(%bp)
123 251
 	movw	%cs, %ax
124
-	movw	$pm_cs, %bx
252
+	movw	$PM_CALL_VAR(pm_cs), %di
125 253
 	call	set_seg_base
126 254
 	movw	%ss, %ax
127
-	movw	$pm_ss, %bx
255
+	movw	$PM_CALL_VAR(pm_ss), %di
128 256
 	call	set_seg_base
129
-	popw	%bx
257
+	popl	%edi
130 258
 	popl	%eax
131 259
 
132 260
 	/* Switch CPU to protected mode and load up segment registers */
133 261
 	pushl	%eax
134 262
 	cli
135
-	lgdt	gdt
263
+	lgdt	PM_CALL_VAR(gdt)(%bp)
136 264
 	movl	%cr0, %eax
137 265
 	orb	$CR0_PE, %al
138 266
 	movl	%eax, %cr0
@@ -168,18 +296,19 @@ pm_call:
168 296
 	popw	%es
169 297
 	popw	%fs
170 298
 	popw	%gs
171
-	lgdt	pm_saved_gdt
299
+	lgdt	PM_CALL_VAR(pm_saved_gdt)(%bp)
172 300
 	popfl
173
-
301
+	movw	%bp, %sp
302
+	popw	%bp
174 303
 	ret
175 304
 	.size pm_call, . - pm_call
176 305
 
177 306
 set_seg_base:
178 307
 	rolw	$4, %ax
179
-	movw	%ax, 2(%bx)
180
-	andw	$0xfff0, 2(%bx)
181
-	movb	%al, 4(%bx)
182
-	andb	$0x0f, 4(%bx)
308
+	movw	%ax, 2(%bp,%di)
309
+	andw	$0xfff0, 2(%bp,%di)
310
+	movb	%al, 4(%bp,%di)
311
+	andb	$0x0f, 4(%bp,%di)
183 312
 	ret
184 313
 	.size set_seg_base, . - set_seg_base
185 314
 
@@ -196,7 +325,7 @@ set_seg_base:
196 325
  *   %ecx : length
197 326
  * Returns:
198 327
  *   %ds:esi : next source address
199
- *   %ds:esi : next destination address
328
+ *   %es:edi : next destination address
200 329
  * Corrupts:
201 330
  *   None
202 331
  ****************************************************************************
@@ -211,24 +340,57 @@ copy_bytes:
211 340
 	.size copy_bytes, . - copy_bytes
212 341
 
213 342
 /****************************************************************************
214
- * install_block (real-mode or 16-bit protected-mode near call)
343
+ * install_block (real-mode near call)
215 344
  *
216 345
  * Install block to specified address
217 346
  *
218 347
  * Parameters:
219
- *   %ds:esi : source address (must be a multiple of 16)
220
- *   %es:edi : destination address
348
+ *   %esi : source physical address (must be a multiple of 16)
349
+ *   %edi : destination physical address (must be a multiple of 16)
221 350
  *   %ecx : length of (decompressed) data
222 351
  *   %edx : total length of block (including any uninitialised data portion)
223 352
  * Returns:
224
- *   %ds:esi : next source address (will be a multiple of 16)
353
+ *   %esi : next source physical address (will be a multiple of 16)
225 354
  * Corrupts:
226
- *   %edi, %ecx, %edx
355
+ *   none
227 356
  ****************************************************************************
228 357
  */
229 358
 	.section ".prefix.lib"
230 359
 	.code16
231 360
 install_block:
361
+	
362
+#ifdef KEEP_IT_REAL
363
+
364
+	/* Preserve registers */
365
+	pushw	%ds
366
+	pushw	%es
367
+	pushl	%ecx
368
+	pushl	%edi
369
+	
370
+	/* Convert %esi and %edi to segment registers */
371
+	shrl	$4, %esi
372
+	movw	%si, %ds
373
+	xorw	%si, %si
374
+	shrl	$4, %edi
375
+	movw	%di, %es
376
+	xorw	%di, %di
377
+
378
+#else /* KEEP_IT_REAL */
379
+
380
+	/* Call self in protected mode */
381
+	pushw	%ax
382
+	movw	$1f, %ax
383
+	call	pm_call
384
+	popw	%ax
385
+	ret
386
+1:
387
+	/* Preserve registers */
388
+	pushl	%ecx
389
+	pushl	%edi
390
+	
391
+#endif /* KEEP_IT_REAL */
392
+
393
+	
232 394
 #if COMPRESS
233 395
 	/* Decompress source to destination */
234 396
 	call	decompress16
@@ -249,6 +411,28 @@ install_block:
249 411
 	addl	$0xf, %esi
250 412
 	andl	$~0xf, %esi
251 413
 
414
+
415
+#ifdef KEEP_IT_REAL
416
+
417
+	/* Convert %ds:esi back to a physical address */
418
+	movzwl	%ds, %cx
419
+	shll	$4, %ecx
420
+	addl	%ecx, %esi
421
+
422
+	/* Restore registers */
423
+	popl	%edi
424
+	popl	%ecx
425
+	popw	%es
426
+	popw	%ds
427
+
428
+#else /* KEEP_IT_REAL */
429
+
430
+	/* Restore registers */
431
+	popl	%edi
432
+	popl	%ecx
433
+
434
+#endif
435
+
252 436
 	ret
253 437
 	.size install_block, . - install_block
254 438
 	
@@ -270,6 +454,7 @@ install_block:
270 454
  */
271 455
 	.section ".prefix.lib"
272 456
 	.code16
457
+	.globl	alloc_basemem
273 458
 alloc_basemem:
274 459
 	/* FBMS => %ax as segment address */
275 460
 	movw	$0x40, %ax
@@ -296,137 +481,86 @@ alloc_basemem:
296 481
 	.size alloc_basemem, . - alloc_basemem
297 482
 
298 483
 /****************************************************************************
299
- * install_basemem (real-mode near call)
484
+ * install (real-mode near call)
300 485
  *
301
- * Install source block into base memory
486
+ * Install all text and data segments.
302 487
  *
303 488
  * Parameters:
304
- *   %esi : source physical address (must be a multiple of 16)
305
- *   %es : destination segment address
306
- *   %cx : length of (decompressed) data
307
- *   %dx : total length of block (including any uninitialised data portion)
489
+ *   none
308 490
  * Returns:
309
- *   %esi : next source physical address (will be a multiple of 16)
491
+ *   %ax  : .text16 segment address
492
+ *   %bx  : .data16 segment address
310 493
  * Corrupts:
311
- *   %edi, %ecx, %edx
494
+ *   none
312 495
  ****************************************************************************
313 496
  */
314 497
 	.section ".prefix.lib"
315 498
 	.code16
316
-install_basemem:
499
+	.globl install
500
+install:
317 501
 	/* Preserve registers */
318
-	pushw	%ds
319
-
320
-	/* Preserve original %esi */
321 502
 	pushl	%esi
322
-
323
-	/* Install to specified address */
324
-	shrl	$4, %esi
325
-	movw	%si, %ds
326
-	xorw	%si, %si
327
-	xorl	%edi, %edi
328
-	movzwl	%cx, %ecx
329
-	movzwl	%dx, %edx
330
-	call	install_block
331
-
332
-	/* Fix up %esi for return */
333
-	popl	%ecx
334
-	addl	%ecx, %esi
335
-
336
-	/* Restore registers */
337
-	popw	%ds
503
+	pushl	%edi
504
+	/* Allocate space for .text16 and .data16 */
505
+	call	alloc_basemem
506
+	/* Image source = %cs:0000 */
507
+	xorl	%esi, %esi
508
+	/* Image destination = HIGHMEM_LOADPOINT */
509
+	movl	$HIGHMEM_LOADPOINT, %edi
510
+	/* Install text and data segments */
511
+	call	install_prealloc
512
+	/* Restore registers and return */
513
+	popl	%edi
514
+	popl	%esi
338 515
 	ret
339
-	.size install_basemem, . - install_basemem
340
-
341
-/****************************************************************************
342
- * install_highmem (real-mode near call)
343
- *
344
- * Install source block into high memory
345
- *
346
- * Parameters:
347
- *   %esi : source physical address (must be a multiple of 16)
348
- *   %edi : destination physical address
349
- *   %ecx : length of (decompressed) data
350
- *   %edx : total length of block (including any uninitialised data portion)
351
- * Returns:
352
- *   %esi : next source physical address (will be a multiple of 16)
353
- * Corrupts:
354
- *   %edi, %ecx, %edx
355
- ****************************************************************************
356
- */
357
-
358
-#ifndef KEEP_IT_REAL
359
-
360
-	.section ".prefix.lib"
361
-	.code16
362
-install_highmem:
363
-	/* Preserve registers */
364
-	pushw	%ax
365
-
366
-	/* Install to specified address */
367
-	movw	$install_block, %ax
368
-	call	pm_call
516
+	.size install, . - install
369 517
 
370
-	/* Restore registers */
371
-	popw	%ax
372
-	ret
373
-	.size install_highmem, . - install_highmem
374
-	
375
-#endif /* KEEP_IT_REAL */
376
-	
377 518
 /****************************************************************************
378
- * install (real-mode near call)
379 519
  * install_prealloc (real-mode near call)
380 520
  *
381 521
  * Install all text and data segments.
382 522
  *
383 523
  * Parameters:
384
- *   %ax : .text16 segment address (install_prealloc only)
385
- *   %bx : .data16 segment address (install_prealloc only)
386
- * Returns:
387
- *   %ax : .text16 segment address
388
- *   %bx : .data16 segment address
389
- *   %edi : .text physical address (if applicable)
524
+ *   %ax  : .text16 segment address
525
+ *   %bx  : .data16 segment address
526
+ *   %esi : Image source physical address (or zero for %cs:0000)
527
+ *   %edi : Decompression temporary area physical address
390 528
  * Corrupts:
391 529
  *   none
392 530
  ****************************************************************************
393 531
  */
394 532
 	.section ".prefix.lib"
395 533
 	.code16
396
-	.globl install
397
-install:
398
-	/* Allocate space for .text16 and .data16 */
399
-	call	alloc_basemem
400
-	.size install, . - install
401 534
 	.globl install_prealloc
402 535
 install_prealloc:
403 536
 	/* Save registers */
537
+	pushal
404 538
 	pushw	%ds
405 539
 	pushw	%es
406
-	pushl	%esi
407
-	pushl	%ecx
408
-	pushl	%edx
409 540
 
410 541
 	/* Sanity: clear the direction flag asap */
411 542
 	cld
412 543
 
413 544
 	/* Calculate physical address of payload (i.e. first source) */
414
-	xorl	%esi, %esi
545
+	testl	%esi, %esi
546
+	jnz	1f
415 547
 	movw	%cs, %si
416 548
 	shll	$4, %esi
417
-	addl	$_payload_offset, %esi
418
-
419
-	/* Install .text16 */
420
-	movw	%ax, %es
421
-	movw	$_text16_size, %cx
422
-	movw	%cx, %dx
423
-	call	install_basemem
549
+1:	addl	$_payload_offset, %esi
424 550
 
425
-	/* Install .data16 */
426
-	movw	%bx, %es
427
-	movw	$_data16_progbits_size, %cx
428
-	movw	$_data16_size, %dx
429
-	call	install_basemem
551
+	/* Install .text16 and .data16 */
552
+	pushl	%edi
553
+	movzwl	%ax, %edi
554
+	shll	$4, %edi
555
+	movl	$_text16_size, %ecx
556
+	movl	%ecx, %edx
557
+	call	install_block		/* .text16 */
558
+	movzwl	%bx, %edi
559
+	shll	$4, %edi
560
+	movl	$_data16_progbits_size, %ecx
561
+	movl	$_data16_size, %edx
562
+	call	install_block		/* .data16 */
563
+	popl	%edi
430 564
 
431 565
 	/* Set up %ds for access to .data16 */
432 566
 	movw	%bx, %ds
@@ -440,12 +574,9 @@ install_prealloc:
440 574
 	 * prior to reading the E820 memory map and relocating
441 575
 	 * properly.
442 576
 	 */
443
-	movl	$HIGHMEM_LOADPOINT, %edi
444 577
 	movl	$_textdata_progbits_size, %ecx
445 578
 	movl	$_textdata_size, %edx
446
-	pushl	%edi
447
-	call	install_highmem
448
-	popl	%edi
579
+	call	install_block
449 580
 
450 581
 	/* Initialise librm at current location */
451 582
 	movw	%ax, (init_librm_vector+2)
@@ -473,11 +604,9 @@ install_prealloc:
473 604
 
474 605
 #endif
475 606
 	/* Restore registers */
476
-	popl	%edx
477
-	popl	%ecx
478
-	popl	%esi
479 607
 	popw	%es
480 608
 	popw	%ds
609
+	popal
481 610
 	ret
482 611
 	.size install_prealloc, . - install_prealloc
483 612
 

+ 0
- 106
src/arch/i386/prefix/pxeprefix.S View File

@@ -320,112 +320,6 @@ print_free_basemem:
320 320
 finished:
321 321
 	jmp	run_etherboot
322 322
 
323
-/*****************************************************************************
324
- * Subroutine: print character (with LF -> LF,CR translation)
325
- *
326
- * Parameters:
327
- *   %al : character to print
328
- * Returns:
329
- *   Nothing
330
- *****************************************************************************
331
- */
332
-print_character:
333
-	/* Preserve registers */
334
-	pushw	%ax
335
-	pushw	%bx
336
-	pushw	%bp
337
-	/* Print character */
338
-	movw	$0x0007, %bx		/* page 0, attribute 7 (normal) */
339
-	movb	$0x0e, %ah		/* write char, tty mode */
340
-	cmpb	$0x0a, %al		/* '\n'? */
341
-	jne	1f
342
-	int	$0x10
343
-	movb	$0x0d, %al
344
-1:	int	$0x10
345
-	/* Restore registers and return */
346
-	popw	%bp
347
-	popw	%bx
348
-	popw	%ax
349
-	ret
350
-	
351
-/*****************************************************************************
352
- * Subroutine: print a NUL-terminated string
353
- *
354
- * Parameters:
355
- *   %ds:%si : string to print
356
- * Returns:
357
- *   Nothing
358
- *****************************************************************************
359
- */	
360
-print_message:
361
-	/* Preserve registers */
362
-	pushw	%ax
363
-	pushw	%si
364
-	/* Print string */
365
-1: 	lodsb
366
-	testb	%al, %al
367
-	je	2f
368
-	call	print_character
369
-	jmp	1b
370
-2:	/* Restore registers and return */
371
-	popw	%si
372
-	popw	%ax
373
-	ret
374
-
375
-/*****************************************************************************
376
- * Subroutine: print hex digit
377
- *
378
- * Parameters:
379
- *   %al (low nibble) : digit to print
380
- * Returns:
381
- *   Nothing
382
- *****************************************************************************
383
- */
384
-print_hex_nibble:
385
-	/* Preserve registers */
386
-	pushw	%ax
387
-	/* Print digit (technique by Norbert Juffa <norbert.juffa@amd.com> */
388
-	andb	$0x0f, %al
389
-	cmpb	$10, %al
390
-	sbbb	$0x69, %al
391
-	das
392
-	call	print_character
393
-	/* Restore registers and return */
394
-	popw	%ax
395
-	ret	
396
-
397
-/*****************************************************************************
398
- * Subroutine: print hex byte
399
- *
400
- * Parameters:
401
- *   %al : byte to print
402
- * Returns:
403
- *   Nothing
404
- *****************************************************************************
405
- */
406
-print_hex_byte:
407
-	rorb	$4, %al
408
-	call	print_hex_nibble
409
-	rorb	$4, %al
410
-	call	print_hex_nibble
411
-	ret
412
-
413
-/*****************************************************************************
414
- * Subroutine: print hex word
415
- *
416
- * Parameters:
417
- *   %ax : word to print
418
- * Returns:
419
- *   Nothing
420
- *****************************************************************************
421
- */
422
-print_hex_word:
423
-	xchgb	%al, %ah
424
-	call	print_hex_byte
425
-	xchgb	%al, %ah
426
-	call	print_hex_byte
427
-	ret
428
-
429 323
 /*****************************************************************************
430 324
  * Subroutine: print segment:offset address
431 325
  *

+ 215
- 63
src/arch/i386/prefix/romprefix.S View File

@@ -6,6 +6,11 @@
6 6
  * table so using a noticeable amount of stack space is a no-no.
7 7
  */
8 8
 
9
+#define PNP_SIGNATURE ( '$' + ( 'P' << 8 ) + ( 'n' << 16 ) + ( 'P' << 24 ) )
10
+#define PMM_SIGNATURE ( '$' + ( 'P' << 8 ) + ( 'M' << 16 ) + ( 'M' << 24 ) )
11
+#define STACK_MAGIC ( 'L' + ( 'R' << 8 ) + ( 'E' << 16 ) + ( 'T' << 24 ) )
12
+#define PNP_GET_BBS_VERSION 0x60
13
+
9 14
 	.text
10 15
 	.code16
11 16
 	.arch i386
@@ -15,7 +20,9 @@
15 20
 romheader:
16 21
 	.word	0xAA55			/* BIOS extension signature */
17 22
 romheader_size:	.byte _load_size_sect	/* Size in 512-byte blocks */
18
-	jmp	init_vector		/* Initialisation vector */
23
+	jmp	init			/* Initialisation vector */
24
+checksum:
25
+	.byte	0
19 26
 	.org	0x16
20 27
 	.word	undiheader
21 28
 	.org	0x18
@@ -72,7 +79,7 @@ pnpheader:
72 79
 	.byte	0x54			/* Device indicator */
73 80
 	.word	0x0000			/* Boot connection vector */
74 81
 	.word	0x0000			/* Disconnect vector */
75
-	.word	exec_vector		/* Boot execution vector */
82
+	.word	bev_entry		/* Boot execution vector */
76 83
 	.word	0x0000			/* Reserved */
77 84
 	.word	0x0000			/* Static resource information vector*/
78 85
 	.equ pnpheader_len, . - pnpheader
@@ -98,60 +105,210 @@ undiheader:
98 105
 	.equ undiheader_len, . - undiheader
99 106
 	.size undiheader, . - undiheader
100 107
 
101
-/* Initialisation vector
108
+/* Initialisation (called once during POST)
102 109
  *
103 110
  * Determine whether or not this is a PnP system via a signature
104 111
  * check.  If it is PnP, return to the PnP BIOS indicating that we are
105 112
  * a boot-capable device; the BIOS will call our boot execution vector
106 113
  * if it wants to boot us.  If it is not PnP, hook INT 19.
107 114
  */
108
-init_vector:
109
-	pushw	%si
110
-	cmpw	$'$'+'P'*256, %es:0(%di)
111
-	jne	notpnp
112
-	cmpw	$'n'+'P'*256, %es:2(%di)
113
-	jne	notpnp
114
-ispnp:
115
-	movw	$ispnp_message, %si
116
-	jmp	99f
117
-notpnp:
115
+init:
116
+	/* Preserve registers, clear direction flag, set %ds=%cs */
117
+	pushaw
118 118
 	pushw	%ds
119
-	pushw	$0
120
-	popw	%ds
119
+	pushw	%es
120
+	cld
121 121
 	pushw	%cs
122
-	pushw	$exec_vector
123
-	popl	( 0x19 * 4 )
124 122
 	popw	%ds
125
-	movw	$notpnp_message, %si
126
-99:
123
+	/* Print message as early as possible */
124
+	movw	$init_message, %si
125
+	call	print_message
126
+	/* Check for PnP BIOS */
127
+	testw	$0x0f, %di	/* PnP signature must be aligned - bochs    */
128
+	jnz	hook_int19	/* uses unalignment to indicate 'fake' PnP. */
129
+	cmpl	$PNP_SIGNATURE, %es:0(%di)
130
+	jne	hook_int19
131
+	/* Is PnP: print PnP message */
132
+	movw	$init_message_pnp, %si
133
+	call	print_message
134
+	xchgw	%bx, %bx
135
+	/* Check for BBS */
136
+	pushw	%es:0x1b(%di)	/* Real-mode data segment */
137
+	pushw	%ds		/* &(bbs_version) */
138
+	pushw	$bbs_version
139
+	pushw	$PNP_GET_BBS_VERSION
140
+	lcall	*%es:0xd(%di)
141
+	addw	$8, %sp
142
+	testw	%ax, %ax
143
+	jne	hook_int19
144
+	movw	$init_message_bbs, %si
145
+	call	print_message
146
+	jmp	hook_bbs
147
+	/* Not BBS-compliant - must hook INT 19 */
148
+hook_int19:
149
+	movw	$init_message_int19, %si
150
+	call	print_message
151
+	xorw	%ax, %ax
152
+	movw	%ax, %es
153
+	pushw	%cs
154
+	pushw	$int19_entry
155
+	popl	%es:( 0x19 * 4 )
156
+hook_bbs:
157
+	/* Check for PMM */
158
+	movw	$( 0xe000 - 1 ), %di
159
+pmm_scan:
160
+	incw	%di
161
+	jz	no_pmm
162
+	movw	%di, %es
163
+	cmpl	$PMM_SIGNATURE, %es:0
164
+	jne	pmm_scan
165
+	xorw	%bx, %bx
166
+	xorw	%si, %si
167
+	movzbw	%es:5, %cx
168
+1:	es lodsb
169
+	addb	%al, %bl
170
+	loop	1b
171
+	jnz	pmm_scan
172
+	/* PMM found: print PMM message */
173
+	movw	$init_message_pmm, %si
127 174
 	call	print_message
175
+	/* Try to allocate 2MB block via PMM */
176
+	pushw	$0x0006		/* Aligned, extended memory */
177
+	pushl	$0xffffffff	/* No handle */
178
+	pushl	$( 0x00200000 / 16 ) /* 2MB in paragraphs */
179
+	pushw	$0x0000		/* pmmAllocate */
180
+	lcall	*%es:7
181
+	addw	$12, %sp
182
+	testw	%dx, %dx	/* %ax==0 even on success, since align=2MB */
183
+	jnz	gotpmm
184
+	movw	$init_message_pmm_failed, %si
185
+	call	print_message
186
+	jmp	no_pmm
187
+gotpmm:	/* PMM allocation succeeded: copy ROM to PMM block */
188
+	pushal			/* PMM presence implies 1kB stack */
189
+	movw	%ax, %es	/* %ax=0 already - see above */
190
+	pushw	%dx
191
+	pushw	%ax
192
+	popl	%edi
193
+	movl	%edi, image_source
194
+	xorl	%esi, %esi
195
+	movzbl	romheader_size, %ecx
196
+	shll	$9, %ecx
197
+	addr32 rep movsb	/* PMM presence implies flat real mode */
198
+	movl	%edi, decompress_to
199
+	/* Shrink ROM and update checksum */
200
+	xorw	%bx, %bx
201
+	xorw	%si, %si
202
+	movw	$_prefix_size_sect, %cx
203
+	movb	%cl, romheader_size
204
+	shlw	$9, %cx
205
+1:	lodsb
206
+	addb	%al, %bl
207
+	loop	1b
208
+	subb	%bl, checksum
209
+	popal
210
+no_pmm:
211
+	/* Print CRLF to terminate messages */
212
+	movw	$'\n', %ax
213
+	call	print_character
214
+	/* Restore registers */
215
+	popw	%es
216
+	popw	%ds
217
+	popaw
218
+	/* Indicate boot capability to PnP BIOS, if present */
128 219
 	movw	$0x20, %ax
129
-	popw	%si
130 220
 	lret
131
-	.size init_vector, . - init_vector
132
-
133
-ispnp_message:
134
-	.asciz	"gPXE detected PnP BIOS\r\n"
135
-	.size ispnp_message, . - ispnp_message
136
-notpnp_message:
137
-	.asciz	"gPXE detected non-PnP BIOS\r\n"
138
-	.size notpnp_message, . - notpnp_message
139
-
140
-/* Boot execution vector
141
- *pciheader_size
142
- * Called by the PnP BIOS when it wants to boot us, or via the hooked
143
- * INT 19 if we detected a non-PnP BIOS.
144
- */	
145
-exec_vector:
146
-	/* Obtain a reasonably-sized stack */
221
+	.size init, . - init
222
+
223
+init_message:
224
+	.asciz	"gPXE (http://etherboot.org) -"
225
+	.size	init_message, . - init_message
226
+init_message_pnp:
227
+	.asciz	" PnP"
228
+	.size init_message_pnp, . - init_message_pnp
229
+init_message_bbs:
230
+	.asciz	" BBS"
231
+	.size init_message_bbs, . - init_message_bbs
232
+init_message_pmm:
233
+	.asciz	" PMM"
234
+	.size init_message_pmm, . - init_message_pmm
235
+init_message_pmm_failed:
236
+	.asciz	"(failed)"
237
+	.size init_message_pmm_failed, . - init_message_pmm_failed
238
+init_message_int19:
239
+	.asciz	" INT19"
240
+	.size init_message_int19, . - init_message_int19
241
+
242
+/* ROM image location
243
+ *
244
+ * May be either within option ROM space, or within PMM-allocated block.
245
+ */
246
+image_source:
247
+	.long	0
248
+	.size	image_source, . - image_source
249
+
250
+/* Temporary decompression area
251
+ *
252
+ * May be either at HIGHMEM_LOADPOINT, or within PMM-allocated block.
253
+ */
254
+decompress_to:
255
+	.long	HIGHMEM_LOADPOINT
256
+	.size	decompress_to, . - decompress_to
257
+
258
+/* BBS version
259
+ *
260
+ * Filled in by BBS BIOS.  We ignore the value.
261
+ */
262
+bbs_version:
263
+	.word	0
264
+
265
+/* Boot Execution Vector entry point
266
+ *
267
+ * Called by the PnP BIOS when it wants to boot us.
268
+ */
269
+bev_entry:
270
+	pushw	%cs
271
+	call	exec
272
+	lret
273
+	.size	bev_entry, . - bev_entry
274
+
275
+/* INT19 entry point
276
+ *
277
+ * Called via the hooked INT 19 if we detected a non-PnP BIOS.
278
+ */
279
+int19_entry:
280
+	pushw	%cs
281
+	call	exec
282
+	/* No real way to return from INT19 */
283
+	int	$0x18
284
+	.size	int19_entry, . - int19_entry
285
+
286
+/* Execute as a boot device
287
+ *
288
+ */
289
+exec:	/* Set %ds = %cs */
290
+	pushw	%cs
291
+	popw	%ds
292
+
293
+	/* Print message as soon as possible */
294
+	movw	$exec_message, %si
295
+	call	print_message
296
+
297
+	/* Store magic word on BIOS stack and remember BIOS %ss:sp */
298
+	pushl	$STACK_MAGIC
299
+	movw	%ss, %dx
300
+	movw	%sp, %bp
301
+
302
+	/* Obtain a reasonably-sized temporary stack */
147 303
 	xorw	%ax, %ax
148 304
 	movw	%ax, %ss
149 305
 	movw	$0x7c00, %sp
150
-	
151
-	movw	$exec_message, %si
152
-	call	print_message
153 306
 
154
-	call	install
307
+	/* Install gPXE */
308
+	movl	image_source, %esi
309
+	movl	decompress_to, %edi
310
+	call	alloc_basemem
311
+	call	install_prealloc
155 312
 
156 313
 	/* Set up real-mode stack */
157 314
 	movw	%bx, %ss
@@ -162,18 +319,28 @@ exec_vector:
162 319
 	pushw	$1f
163 320
 	lret
164 321
 	.section ".text16", "awx", @progbits
165
-1:
322
+1:	/* Call main() */
166 323
 	pushl	$main
167 324
 	pushw	%cs
168 325
 	call	prot_call
169
-	popl	%eax /* discard */
326
+	/* No need to clean up stack; we are about to reload %ss:sp */
327
+	
328
+	/* Restore BIOS stack */
329
+	movw	%dx, %ss
330
+	movw	%bp, %sp
170 331
 
171
-	/* Boot next device */
332
+	/* Check magic word on BIOS stack */
333
+	popl	%eax
334
+	cmpl	$STACK_MAGIC, %eax
335
+	jne	1f
336
+	/* BIOS stack OK: return to caller */
337
+	lret
338
+1:	/* BIOS stack corrupt: use INT 18 */
172 339
 	int	$0x18
173 340
 	.previous
174 341
 
175 342
 exec_message:
176
-	.asciz	"gPXE starting boot\r\n"
343
+	.asciz	"gPXE starting boot\n"
177 344
 	.size exec_message, . - exec_message
178 345
 
179 346
 /* UNDI loader
@@ -182,6 +349,7 @@ exec_message:
182 349
  */
183 350
 undiloader:
184 351
 	/* Save registers */
352
+	pushl	%esi
185 353
 	pushl	%edi
186 354
 	pushw	%es
187 355
 	pushw	%bx
@@ -193,6 +361,8 @@ undiloader:
193 361
 	pushw	%di
194 362
 	movw	%es:12(%di), %bx
195 363
 	movw	%es:14(%di), %ax
364
+	movl	%cs:image_source, %esi
365
+	movl	%cs:decompress_to, %edi
196 366
 	call	install_prealloc
197 367
 	popw	%di
198 368
 	/* Call UNDI loader C code */
@@ -208,24 +378,6 @@ undiloader:
208 378
 	popw	%bx
209 379
 	popw	%es
210 380
 	popl	%edi
381
+	popl	%esi
211 382
 	lret
212 383
 	.size undiloader, . - undiloader
213
-				
214
-/* Utility function: print string
215
- */
216
-print_message:
217
-	pushw	%ax
218
-	pushw	%bx
219
-	pushw	%bp
220
-	movw    $0x0007, %bx
221
-1:	cs lodsb
222
-	testb	%al, %al
223
-	je	2f
224
-	movb    $0x0e, %ah              /* write char, tty mode */
225
-	int     $0x10
226
-	jmp	1b
227
-2:	popw	%bp
228
-	popw	%bx
229
-	popw	%ax
230
-	ret
231
-	.size print_message, . - print_message

+ 2
- 0
src/arch/i386/scripts/i386.lds View File

@@ -257,6 +257,8 @@ SECTIONS {
257 257
     /*
258 258
      * Values calculated to save code from doing it
259 259
      */
260
+    _prefix_size_pgh	= ( ( _prefix_size + 15 ) / 16 );
261
+    _prefix_size_sect	= ( ( _prefix_size + 511 ) / 512 );
260 262
     _text16_size_pgh	= ( ( _text16_size + 15 ) / 16 );
261 263
     _data16_size_pgh	= ( ( _data16_size + 15 ) / 16 );
262 264
 

Loading…
Cancel
Save