Browse Source

[prefix] Move flatten_real_mode to .text16.early

The flatten_real_mode routine is not needed until after decompressing
.text16.early, and currently performs various contortions to
compensate for the fact that .prefix may not be writable.  Move
flatten_real_mode to .text16.early to save on (compressed) binary size
and simplify the code.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 14 years ago
parent
commit
d931d4bd9c
1 changed files with 31 additions and 41 deletions
  1. 31
    41
      src/arch/i386/prefix/libprefix.S

+ 31
- 41
src/arch/i386/prefix/libprefix.S View File

@@ -233,7 +233,7 @@ print_kill_line:
233 233
 	.size	print_kill_line, . - print_kill_line
234 234
 
235 235
 /****************************************************************************
236
- * flatten_real_mode
236
+ * flatten_real_mode (real-mode far call)
237 237
  *
238 238
  * Set up 4GB segment limits
239 239
  *
@@ -248,9 +248,8 @@ print_kill_line:
248 248
 #ifndef KEEP_IT_REAL
249 249
 
250 250
 	/* GDT for protected-mode calls */
251
-	.section ".prefix.lib", "awx", @progbits
251
+	.section ".text16.early.data", "aw", @progbits
252 252
 	.align 16
253
-flatten_vars:
254 253
 flatten_gdt:
255 254
 flatten_gdt_limit:	.word flatten_gdt_length - 1
256 255
 flatten_gdt_base:	.long 0
@@ -267,62 +266,50 @@ flatten_gdt_end:
267 266
 	.equ	flatten_gdt_length, . - flatten_gdt
268 267
 	.size	flatten_gdt, . - flatten_gdt
269 268
 
270
-	.section ".prefix.lib", "awx", @progbits
269
+	.section ".text16.early.data", "aw", @progbits
271 270
 	.align 16
272 271
 flatten_saved_gdt:
273 272
 	.long	0, 0
274 273
 	.size	flatten_saved_gdt, . - flatten_saved_gdt
275 274
 
276
-	.equ	flatten_vars_size, . - flatten_vars
277
-#define FLATTEN_VAR(x) ( -flatten_vars_size + ( (x) - flatten_vars ) )
278
-
279
-	.section ".prefix.lib", "awx", @progbits
275
+	.section ".text16.early", "awx", @progbits
280 276
 	.code16
281 277
 flatten_real_mode:
282
-	/* Preserve registers and flags, allocate local variable block */
283
-	pushw	%bp
284
-	movw	%sp, %bp
285
-	subw	$flatten_vars_size, %sp
286
-	andw	$0xfff0, %sp
278
+	/* Preserve registers and flags */
287 279
 	pushfl
288 280
 	pushl	%eax
289
-	pushl	%edi
290 281
 	pushw	%si
291
-	pushw	%cx
292 282
 	pushw	%gs
293 283
 	pushw	%fs
294 284
 	pushw	%es
295 285
 	pushw	%ds
296 286
 	pushw	%ss
297 287
 
298
-	/* Fill local variable block and preserve GDT */
299
-	pushw	%ss
300
-	popw	%es
301
-	movw	$flatten_vars, %si
302
-	leaw	FLATTEN_VAR(flatten_vars)(%bp), %di
303
-	movw	$flatten_vars_size, %cx
304
-	cs rep movsb
305
-	sgdt	FLATTEN_VAR(flatten_saved_gdt)(%bp)
288
+	/* Set %ds for access to .text16.early.data variables */
289
+	pushw	%cs
290
+	popw	%ds
291
+
292
+	/* Preserve original GDT */
293
+	sgdt flatten_saved_gdt
306 294
 
307 295
 	/* Set up GDT bases */
308 296
 	xorl	%eax, %eax
309
-	movw	%ss, %ax
297
+	movw	%cs, %ax
310 298
 	shll	$4, %eax
311
-	movzwl	%bp, %edi
312
-	addr32 leal FLATTEN_VAR(flatten_gdt)(%eax, %edi), %eax
313
-	movl	%eax, FLATTEN_VAR(flatten_gdt_base)(%bp)
299
+	addl	$flatten_gdt, %eax
300
+	movl	%eax, flatten_gdt_base
314 301
 	movw	%cs, %ax
315
-	movw	$FLATTEN_VAR(flatten_cs), %di
302
+	movw	$flatten_cs, %si
316 303
 	call	set_seg_base
317 304
 	movw	%ss, %ax
318
-	movw	$FLATTEN_VAR(flatten_ss), %di
305
+	movw	$flatten_ss, %si
319 306
 	call	set_seg_base
320 307
 
321 308
 	/* Switch temporarily to protected mode and set segment registers */
322 309
 	pushw	%cs
323 310
 	pushw	$2f
324 311
 	cli
325
-	data32 lgdt FLATTEN_VAR(flatten_gdt)(%bp)
312
+	data32 lgdt flatten_gdt
326 313
 	movl	%cr0, %eax
327 314
 	orb	$CR0_PE, %al
328 315
 	movl	%eax, %cr0
@@ -340,28 +327,26 @@ flatten_real_mode:
340 327
 2:	/* lret will ljmp to here */
341 328
 
342 329
 	/* Restore GDT, registers and flags */
343
-	data32 lgdt FLATTEN_VAR(flatten_saved_gdt)(%bp)
330
+	data32 lgdt flatten_saved_gdt
344 331
 	popw	%ss
345 332
 	popw	%ds
346 333
 	popw	%es
347 334
 	popw	%fs
348 335
 	popw	%gs
349
-	popw	%cx
350 336
 	popw	%si
351
-	popl	%edi
352 337
 	popl	%eax
353 338
 	popfl
354
-	movw	%bp, %sp
355
-	popw	%bp
356
-	ret
339
+	lret
357 340
 	.size flatten_real_mode, . - flatten_real_mode
358 341
 
342
+	.section ".text16.early", "awx", @progbits
343
+	.code16
359 344
 set_seg_base:
360 345
 	rolw	$4, %ax
361
-	movw	%ax, 2(%bp,%di)
362
-	andw	$0xfff0, 2(%bp,%di)
363
-	movb	%al, 4(%bp,%di)
364
-	andb	$0x0f, 4(%bp,%di)
346
+	movw	%ax, 2(%si)
347
+	andw	$0xfff0, 2(%si)
348
+	movb	%al, 4(%si)
349
+	andb	$0x0f, 4(%si)
365 350
 	ret
366 351
 	.size set_seg_base, . - set_seg_base
367 352
 
@@ -650,7 +635,12 @@ install_prealloc:
650 635
 	/* Open up access to payload */
651 636
 #ifndef KEEP_IT_REAL
652 637
 	/* Flatten real mode */
653
-	call	flatten_real_mode
638
+	pushw	%cs
639
+	pushw	$1f
640
+	pushw	%ax
641
+	pushw	$flatten_real_mode
642
+	lret
643
+1:
654 644
 #endif
655 645
 
656 646
 	/* Calculate physical address of payload (i.e. first source) */

Loading…
Cancel
Save