summaryrefslogtreecommitdiffstats
path: root/src/arch/i386/transitions/librm.S
diff options
context:
space:
mode:
authorMichael Brown2007-09-25 21:14:20 +0200
committerMichael Brown2007-09-25 21:14:20 +0200
commit42d96bcb07025ae68a7646d7d45b228937021d75 (patch)
tree15a06dd826334d374e1a96a78c90d5f6db1c474e /src/arch/i386/transitions/librm.S
parentrm_ss, rm_sp, and pm_esp don't need to be accessed from anywhere (diff)
downloadipxe-42d96bcb07025ae68a7646d7d45b228937021d75.tar.gz
ipxe-42d96bcb07025ae68a7646d7d45b228937021d75.tar.xz
ipxe-42d96bcb07025ae68a7646d7d45b228937021d75.zip
Don't use the "rep ss movsb" trick to copy the RM stack to the PM
stack; it breaks vmxassist.
Diffstat (limited to 'src/arch/i386/transitions/librm.S')
-rw-r--r--src/arch/i386/transitions/librm.S65
1 files changed, 34 insertions, 31 deletions
diff --git a/src/arch/i386/transitions/librm.S b/src/arch/i386/transitions/librm.S
index 56b9f363..d9c6d72d 100644
--- a/src/arch/i386/transitions/librm.S
+++ b/src/arch/i386/transitions/librm.S
@@ -186,9 +186,14 @@ real_to_prot:
pushl _data16
addw $16, %cx /* %ecx must be less than 64kB anyway */
- /* Real-mode %ss:%sp => %bp:%esi */
+ /* Real-mode %ss:%sp => %ebp:%edx and virtual address => %esi */
+ xorl %ebp, %ebp
movw %ss, %bp
- movzwl %sp, %esi
+ movzwl %sp, %edx
+ movl %ebp, %eax
+ shll $4, %eax
+ leal (%eax,%edx), %esi
+ subl _virt_offset, %esi
/* Switch to protected mode */
cli
@@ -200,23 +205,24 @@ real_to_prot:
.section ".text"
.code32
1:
- /* Set up protected-mode data segments */
+ /* Set up protected-mode data segments and stack pointer */
movw $VIRTUAL_DS, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
-
- /* Move data from RM stack to PM stack and set up PM stack */
- movl pm_esp, %esp
- subl %ecx, %esp
- movl %esp, %edi
- rep ss movsb
movw %ax, %ss
+ movl pm_esp, %esp
/* Record real-mode %ss:sp (after removal of data) */
- movw %bp, rm_ss
- movw %si, rm_sp
+ movl %ebp, rm_ss
+ addl %ecx, %edx
+ movl %edx, rm_sp
+
+ /* Move data from RM stack to PM stack */
+ subl %ecx, %esp
+ movl %esp, %edi
+ rep movsb
/* Publish virt_offset, text16 and data16 for PM code to use */
popl data16
@@ -251,16 +257,16 @@ prot_to_real:
/* Add return address to data to be moved to RM stack */
addl $4, %ecx
- /* Real-mode %ss:sp => %ebp:edx */
- movzwl rm_ss, %ebp
- movzwl rm_sp, %edx
+ /* Real-mode %ss:sp => %ebp:edx and virtual address => %edi */
+ movl rm_ss, %ebp
+ movl rm_sp, %edx
subl %ecx, %edx
-
- /* Move data from PM stack to RM stack */
movl %ebp, %eax
shll $4, %eax
leal (%eax,%edx), %edi
subl virt_offset, %edi
+
+ /* Move data from PM stack to RM stack */
movl %esp, %esi
rep movsb
@@ -285,16 +291,14 @@ prot_to_real:
ljmp *p2r_jump_vector
p2r_jump_target:
- /* Set up real-mode stack */
- movw %bp, %ss
- movl %edx, %esp
-
- /* Set up real-mode data segments */
+ /* Set up real-mode data segments and stack pointer */
movw %cs:rm_ds, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %fs
movw %ax, %gs
+ movw %bp, %ss
+ movl %edx, %esp
/* Return to real-mode address */
data32 ret
@@ -398,9 +402,7 @@ prot_call:
.section ".text16"
.code16
1:
- /* Reload GDT, restore registers and flags and return. Note
- * that %esp is restored manually, since popal discards it.
- */
+ /* Reload GDT, restore registers and flags and return */
movw %sp, %bp
lgdt (%bp)
addw $12, %sp /* also skip %cs and %ss */
@@ -409,11 +411,12 @@ prot_call:
popw %fs
popw %gs
popal
- addr32 movl -20(%esp), %esp /* -20(%sp) is not a valid 80386
- * expression. -20(%esp) is safe
- * because prot_to_real zeroes the
- * high word of %esp, and interrupts
- * are still disabled at this point. */
+ /* popal skips %esp. We therefore want to do "movl -20(%sp),
+ * %esp", but -20(%sp) is not a valid 80386 expression.
+ * Fortunately, pot_to_real() zeroes the high word of %esp, so
+ * we can just use -20(%esp) instead.
+ */
+ addr32 movl -20(%esp), %esp
popfl
lret
@@ -528,8 +531,8 @@ rc_function: .word 0, 0
****************************************************************************
*/
.section ".data"
-rm_sp: .word 0
-rm_ss: .word 0
+rm_sp: .long 0
+rm_ss: .long 0
pm_esp: .long _estack
/****************************************************************************