david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

Don't use the "rep ss movsb" trick to copy the RM stack to the PM

stack; it breaks vmxassist.
This commit is contained in:
Michael Brown 2007-09-25 20:14:20 +01:00
parent 0ed066bc50
commit 42d96bcb07
1 changed files with 34 additions and 31 deletions

View File

@ -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
/****************************************************************************