|
@@ -229,10 +229,11 @@ real_to_prot:
|
229
|
229
|
*
|
230
|
230
|
* Switch from 32-bit protected mode with virtual addresses to 16-bit
|
231
|
231
|
* real mode. The protected-mode %esp is stored in pm_esp and the
|
232
|
|
- * real-mode %ss:sp is restored from the saved rm_ss and rm_sp. All
|
233
|
|
- * real-mode data segment registers are loaded from the saved rm_ds.
|
234
|
|
- * Interrupts are *not* enabled, since we want to be able to use
|
235
|
|
- * prot_to_real in an ISR. All other registers may be destroyed.
|
|
232
|
+ * real-mode %ss:sp is restored from the saved rm_ss and rm_sp. The
|
|
233
|
+ * high word of the real-mode %esp is set to zero. All real-mode data
|
|
234
|
+ * segment registers are loaded from the saved rm_ds. Interrupts are
|
|
235
|
+ * *not* enabled, since we want to be able to use prot_to_real in an
|
|
236
|
+ * ISR. All other registers may be destroyed.
|
236
|
237
|
*
|
237
|
238
|
* The return address for this function should be a 32-bit (sic)
|
238
|
239
|
* real-mode offset within .code16.
|
|
@@ -284,7 +285,7 @@ p2r_jump_target:
|
284
|
285
|
|
285
|
286
|
/* Set up real-mode stack */
|
286
|
287
|
movw %bp, %ss
|
287
|
|
- movw %dx, %sp
|
|
288
|
+ movl %edx, %esp
|
288
|
289
|
|
289
|
290
|
/* Set up real-mode data segments */
|
290
|
291
|
movw %cs:rm_ds, %ax
|
|
@@ -321,7 +322,7 @@ rm_ds: .word 0
|
321
|
322
|
*
|
322
|
323
|
* All registers will be preserved across prot_call(), unless the C
|
323
|
324
|
* function explicitly overwrites values in ix86. Interrupt status
|
324
|
|
- * will also be preserved. Gate A20 will be enabled.
|
|
325
|
+ * and GDT will also be preserved. Gate A20 will be enabled.
|
325
|
326
|
*
|
326
|
327
|
* Parameters:
|
327
|
328
|
* function : virtual address of protected-mode function to call
|
|
@@ -384,7 +385,9 @@ prot_call:
|
384
|
385
|
.section ".text16"
|
385
|
386
|
.code16
|
386
|
387
|
1:
|
387
|
|
- /* Reload GDT, restore registers and flags and return */
|
|
388
|
+ /* Reload GDT, restore registers and flags and return. Note
|
|
389
|
+ * that %esp is restored manually, since popal discards it.
|
|
390
|
+ */
|
388
|
391
|
movw %sp, %bp
|
389
|
392
|
lgdt (%bp)
|
390
|
393
|
addw $12, %sp /* also skip %cs and %ss */
|
|
@@ -393,6 +396,10 @@ prot_call:
|
393
|
396
|
popw %fs
|
394
|
397
|
popw %gs
|
395
|
398
|
popal
|
|
399
|
+ movl -20(%esp), %esp /* -20(%sp) is not a valid 80386 expression.
|
|
400
|
+ * -20(%esp) is safe because prot_to_real
|
|
401
|
+ * zeroes the high word of %esp, and interrupts
|
|
402
|
+ * are still disabled at this point. */
|
396
|
403
|
popfl
|
397
|
404
|
data32 ret
|
398
|
405
|
|