|
@@ -335,7 +335,8 @@ rm_ds: .word 0
|
335
|
335
|
****************************************************************************
|
336
|
336
|
*/
|
337
|
337
|
|
338
|
|
-#define PC_OFFSET_IX86 ( 0 )
|
|
338
|
+#define PC_OFFSET_GDT ( 0 )
|
|
339
|
+#define PC_OFFSET_IX86 ( PC_OFFSET_GDT + 8 /* pad to 8 to keep alignment */ )
|
339
|
340
|
#define PC_OFFSET_RETADDR ( PC_OFFSET_IX86 + SIZEOF_I386_ALL_REGS )
|
340
|
341
|
#define PC_OFFSET_FUNCTION ( PC_OFFSET_RETADDR + 4 )
|
341
|
342
|
#define PC_OFFSET_END ( PC_OFFSET_FUNCTION + 4 )
|
|
@@ -344,7 +345,7 @@ rm_ds: .word 0
|
344
|
345
|
.code16
|
345
|
346
|
.globl prot_call
|
346
|
347
|
prot_call:
|
347
|
|
- /* Preserve registers and flags on external RM stack */
|
|
348
|
+ /* Preserve registers, flags and GDT on external RM stack */
|
348
|
349
|
pushfl
|
349
|
350
|
pushal
|
350
|
351
|
pushw %gs
|
|
@@ -353,6 +354,9 @@ prot_call:
|
353
|
354
|
pushw %ds
|
354
|
355
|
pushw %ss
|
355
|
356
|
pushw %cs
|
|
357
|
+ subw $8, %sp
|
|
358
|
+ movw %sp, %bp
|
|
359
|
+ sgdt (%bp)
|
356
|
360
|
|
357
|
361
|
/* For sanity's sake, clear the direction flag as soon as possible */
|
358
|
362
|
cld
|
|
@@ -368,7 +372,8 @@ prot_call:
|
368
|
372
|
call gateA20_set
|
369
|
373
|
|
370
|
374
|
/* Call function */
|
371
|
|
- pushl %esp
|
|
375
|
+ leal PC_OFFSET_IX86(%esp), %eax
|
|
376
|
+ pushl %eax
|
372
|
377
|
call *(PC_OFFSET_FUNCTION+4)(%esp)
|
373
|
378
|
popl %eax /* discard */
|
374
|
379
|
|
|
@@ -379,9 +384,10 @@ prot_call:
|
379
|
384
|
.section ".text16"
|
380
|
385
|
.code16
|
381
|
386
|
1:
|
382
|
|
- /* Restore registers and flags and return */
|
383
|
|
- popw %ax /* skip %cs - it is already set */
|
384
|
|
- popw %ax /* skip %ss - it is already set */
|
|
387
|
+ /* Reload GDT, restore registers and flags and return */
|
|
388
|
+ movw %sp, %bp
|
|
389
|
+ lgdt (%bp)
|
|
390
|
+ addw $12, %sp /* also skip %cs and %ss */
|
385
|
391
|
popw %ds
|
386
|
392
|
popw %es
|
387
|
393
|
popw %fs
|