summaryrefslogtreecommitdiffstats
path: root/src/arch/i386/transitions/librm.S
diff options
context:
space:
mode:
authorMichael Brown2005-04-09 15:56:33 +0200
committerMichael Brown2005-04-09 15:56:33 +0200
commita800e9657d69c524cb12570a2391e3803cbafab5 (patch)
tree2feafa9b19d301a6cb8d529753937f6fc2d26b51 /src/arch/i386/transitions/librm.S
parentAdd relocate.h (diff)
downloadipxe-a800e9657d69c524cb12570a2391e3803cbafab5.tar.gz
ipxe-a800e9657d69c524cb12570a2391e3803cbafab5.tar.xz
ipxe-a800e9657d69c524cb12570a2391e3803cbafab5.zip
PM function called by prot_call() should be allowed to modifying
registers returned to RM code.
Diffstat (limited to 'src/arch/i386/transitions/librm.S')
-rw-r--r--src/arch/i386/transitions/librm.S17
1 files changed, 15 insertions, 2 deletions
diff --git a/src/arch/i386/transitions/librm.S b/src/arch/i386/transitions/librm.S
index 6dc6b4fd..5299841c 100644
--- a/src/arch/i386/transitions/librm.S
+++ b/src/arch/i386/transitions/librm.S
@@ -496,8 +496,10 @@ EXPORT(prot_call):
movl $SIZEOF_REAL_MODE_REGS, %ecx
subl %ecx, %esp
movl %esp, %edi
+ pushl %esi
cld
- rep movsb
+ rep movsb
+ popl %edi /* %edi = phys addr of RM copy of rm_regs */
/* Switch to virtual addresses. */
call 1f
@@ -522,7 +524,18 @@ EXPORT(prot_call):
/* Switch to physical addresses, discard PM register store */
lcall $VIRTUAL_CS, $_virt_to_phys
- addl $SIZEOF_REAL_MODE_REGS+4, %esp /* also discard lcall seg */
+ popl %eax /* discard */
+
+ /* Copy rm_regs from PM stack to RM stack, and remove rm_regs
+ * from PM stack. (%edi still contains physical address of
+ * rm_regs on RM stack from earlier, since C code preserves
+ * %edi).
+ */
+ movl %esp, %esi
+ movl $SIZEOF_REAL_MODE_REGS, %ecx
+ cld
+ rep movsb
+ movl %esi, %esp /* remove rm_regs from PM stack */
/* Switch to real mode */
call prot_to_real