When doing the i386-coreboot port I made this choice completely backwards.

I thought real_to_prot() was only useful on i386-pc, because we needed it
for returning from BIOS, and prot_to_real() was useful elsewhere, because
the Linux loader would use it.

Turns out we need real_to_prot() on i386-qemu for the initial transition
to i386 mode, AND we don't need prot_to_real() anywhere other than i386-pc,
because OSes that expect to be loaded in i8086 mode are going to rely on
BIOS calls.

So this patch swaps them.  real_to_prot() goes to realmode.S and
prot_to_real() back to startup.S.

-- 
Robert Millan

  The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
  how) you may access your data; but nobody's threatening your freedom: we
  still allow you to remove your data and not access it at all."
2009-06-21  Robert Millan  <rmh.g...@aybabtu.com>

	* kern/i386/pc/startup.S (real_to_prot): Move from here ...
	* kern/i386/realmode.S (real_to_prot): ... to here.

	* kern/i386/realmode.S (prot_to_real): Move from here ...
	* kern/i386/pc/startup.S (prot_to_real): ... to here.

Index: kern/i386/pc/startup.S
===================================================================
--- kern/i386/pc/startup.S	(revision 2353)
+++ kern/i386/pc/startup.S	(working copy)
@@ -302,62 +302,73 @@
 	.p2align	2	/* force 4-byte alignment */
 
 /*
- *  These next two routines, "real_to_prot" and "prot_to_real" are structured
- *  in a very specific way.  Be very careful when changing them.
+ *  This next routine, "prot_to_real" is structured in a very
+ *  specific way.  Be very careful when changing it.
  *
- *  NOTE:  Use of either one messes up %eax and %ebp.
+ *  NOTE:  Use of it messes up %eax and %ebp.
  */
 
-real_to_prot:
-	.code16
-	cli
+prot_to_real:
+	/* just in case, set GDT */
+	lgdt	gdtdesc
 
-	/* load the GDT register */
-#ifdef APPLE_CC
-	mov %cs, %ax
-	mov %ax, %ds
-	DATA32	ADDR32	lgdt	gdtdesc
-#else
-	DATA32	ADDR32	lgdt	%cs:gdtdesc
-#endif
+	/* save the protected mode stack */
+	movl	%esp, %eax
+	movl	%eax, protstack
 
-	/* turn on protected mode */
-	movl	%cr0, %eax
-	orl	$GRUB_MEMORY_MACHINE_CR0_PE_ON, %eax
-	movl	%eax, %cr0
+	/* get the return address */
+	movl	(%esp), %eax
+	movl	%eax, GRUB_MEMORY_MACHINE_REAL_STACK
 
-	/* jump to relocation, flush prefetch queue, and reload %cs */
-	DATA32	ljmp	$GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $protcseg
+	/* set up new stack */
+	movl	$GRUB_MEMORY_MACHINE_REAL_STACK, %eax
+	movl	%eax, %esp
+	movl	%eax, %ebp
 
-	.code32
-protcseg:
-	/* reload other segment registers */
-	movw	$GRUB_MEMORY_MACHINE_PROT_MODE_DSEG, %ax
+	/* set up segment limits */
+	movw	$GRUB_MEMORY_MACHINE_PSEUDO_REAL_DSEG, %ax
 	movw	%ax, %ds
 	movw	%ax, %es
 	movw	%ax, %fs
 	movw	%ax, %gs
 	movw	%ax, %ss
 
-	/* put the return address in a known safe location */
-	movl	(%esp), %eax
-	movl	%eax, GRUB_MEMORY_MACHINE_REAL_STACK
+	/* this might be an extra step */
+	/* jump to a 16 bit segment */
+	ljmp	$GRUB_MEMORY_MACHINE_PSEUDO_REAL_CSEG, $tmpcseg
 
-	/* get protected mode stack */
-	movl	protstack, %eax
-	movl	%eax, %esp
-	movl	%eax, %ebp
+tmpcseg:
+	.code16
 
-	/* get return address onto the right stack */
-	movl	GRUB_MEMORY_MACHINE_REAL_STACK, %eax
-	movl	%eax, (%esp)
+	/* clear the PE bit of CR0 */
+	movl	%cr0, %eax
+	andl 	$(~GRUB_MEMORY_MACHINE_CR0_PE_ON), %eax
+	movl	%eax, %cr0
 
+	/* flush prefetch queue, reload %cs */
+	DATA32	ljmp	$0, $realcseg
+
+realcseg:
+	/* we are in real mode now
+	 * set up the real mode segment registers : DS, SS, ES
+	 */
 	/* zero %eax */
 	xorl	%eax, %eax
 
-	/* return on the old (or initialized) stack! */
-	ret
+	movw	%ax, %ds
+	movw	%ax, %es
+	movw	%ax, %fs
+	movw	%ax, %gs
+	movw	%ax, %ss
 
+	/* restore interrupts */
+	sti
+
+	/* return on new stack! */
+	DATA32	ret
+
+	.code32
+
 /*
  * grub_gate_a20(int on)
  *
Index: kern/i386/realmode.S
===================================================================
--- kern/i386/realmode.S	(revision 2353)
+++ kern/i386/realmode.S	(working copy)
@@ -110,69 +110,59 @@
 	.long	gdt			/* addr */
 
 /*
- *  These next routine, "prot_to_real" is structured in a very
+ *  This next routine, "real_to_prot" is structured in a very
  *  specific way.  Be very careful when changing it.
  *
  *  NOTE:  Use of it messes up %eax and %ebp.
  */
 
-prot_to_real:
-	/* just in case, set GDT */
-	lgdt	gdtdesc
+real_to_prot:
+	.code16
+	cli
 
-	/* save the protected mode stack */
-	movl	%esp, %eax
-	movl	%eax, protstack
+	/* load the GDT register */
+#ifdef APPLE_CC
+	mov %cs, %ax
+	mov %ax, %ds
+	DATA32	ADDR32	lgdt	gdtdesc
+#else
+	DATA32	ADDR32	lgdt	%cs:gdtdesc
+#endif
 
-	/* get the return address */
-	movl	(%esp), %eax
-	movl	%eax, GRUB_MEMORY_MACHINE_REAL_STACK
+	/* turn on protected mode */
+	movl	%cr0, %eax
+	orl	$GRUB_MEMORY_MACHINE_CR0_PE_ON, %eax
+	movl	%eax, %cr0
 
-	/* set up new stack */
-	movl	$GRUB_MEMORY_MACHINE_REAL_STACK, %eax
-	movl	%eax, %esp
-	movl	%eax, %ebp
+	/* jump to relocation, flush prefetch queue, and reload %cs */
+	DATA32	ljmp	$GRUB_MEMORY_MACHINE_PROT_MODE_CSEG, $protcseg
 
-	/* set up segment limits */
-	movw	$GRUB_MEMORY_MACHINE_PSEUDO_REAL_DSEG, %ax
+	.code32
+protcseg:
+	/* reload other segment registers */
+	movw	$GRUB_MEMORY_MACHINE_PROT_MODE_DSEG, %ax
 	movw	%ax, %ds
 	movw	%ax, %es
 	movw	%ax, %fs
 	movw	%ax, %gs
 	movw	%ax, %ss
 
-	/* this might be an extra step */
-	/* jump to a 16 bit segment */
-	ljmp	$GRUB_MEMORY_MACHINE_PSEUDO_REAL_CSEG, $tmpcseg
+	/* put the return address in a known safe location */
+	movl	(%esp), %eax
+	movl	%eax, GRUB_MEMORY_MACHINE_REAL_STACK
 
-tmpcseg:
-	.code16
+	/* get protected mode stack */
+	movl	protstack, %eax
+	movl	%eax, %esp
+	movl	%eax, %ebp
 
-	/* clear the PE bit of CR0 */
-	movl	%cr0, %eax
-	andl 	$(~GRUB_MEMORY_MACHINE_CR0_PE_ON), %eax
-	movl	%eax, %cr0
+	/* get return address onto the right stack */
+	movl	GRUB_MEMORY_MACHINE_REAL_STACK, %eax
+	movl	%eax, (%esp)
 
-	/* flush prefetch queue, reload %cs */
-	DATA32	ljmp	$0, $realcseg
-
-realcseg:
-	/* we are in real mode now
-	 * set up the real mode segment registers : DS, SS, ES
-	 */
 	/* zero %eax */
 	xorl	%eax, %eax
 
-	movw	%ax, %ds
-	movw	%ax, %es
-	movw	%ax, %fs
-	movw	%ax, %gs
-	movw	%ax, %ss
-
-	/* restore interrupts */
-	sti
-
-	/* return on new stack! */
-	DATA32	ret
-
+	/* return on the old (or initialized) stack! */
+	ret
 	.code32
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to