qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] extboot: properly set int 0x13 return value


From: Glauber Costa
Subject: [Qemu-devel] [PATCH] extboot: properly set int 0x13 return value
Date: Mon, 1 Dec 2008 14:41:10 -0500

Callers of int 0x13 usually rely on the carry flag being
clear/set to indicate the status of the interrupt execution.

However, our current code clear or set the flags register,
which is totally useless. Whichever value it has, will
be overwritten by the flags value _before_ the interrupt, due to
the iret instruction.

This fixes a bug that prevents slackware (and possibly win2k, untested)
to boot.

Signed-off-by: Glauber Costa <address@hidden>
---
 extboot/extboot.S |   52 ++++++++++++++++++++++++++--------------------------
 1 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/extboot/extboot.S b/extboot/extboot.S
index 2630abb..4cbfe11 100644
--- a/extboot/extboot.S
+++ b/extboot/extboot.S
@@ -99,24 +99,24 @@ int19_handler:
 
 #define FLAGS_CF       0x01
 
-.macro clc
-       push %ax
-       pushf
-       pop %ax
-       and $(~FLAGS_CF), %ax
-       push %ax
-       popf
-       pop %ax
+/* The two macro below clear/set the carry flag to indicate the status
+ * of the interrupt execution. It is not enough to issue a clc/stc 
instruction, 
+ * since the value of the flags register will be overwritten by whatever is
+ * in the stack frame
+ */
+.macro clc_stack
+       push %bp
+       mov %sp, %bp
+       /* 8 = 2 (bp, just pushed) + 2 (ip) + 3 (real mode interrupt frame)
+       and $(~FLAGS_CF), 8(%bp)
+       pop %bp
 .endm
 
-.macro stc
-       push %ax
-       pushf
-       pop %ax
-       or $(FLAGS_CF), %ax
-       push %ax
-       popf
-       pop %ax
+.macro stc_stack
+       push %bp
+       /* 8 = 2 (bp, just pushed) + 2 (ip) + 3 (real mode interrupt frame)
+       or $(FLAGS_CF), 8(%bp)
+       pop %bp
 .endm
 
 /* we clobber %bx */
@@ -292,7 +292,7 @@ mul32:  /* lo,      hi,     lo,     hi */
 
 disk_reset:
        movb $0, %ah
-       clc
+       clc_stack
        ret
 
 /* this really should be a function, not a macro but i'm lazy */
@@ -395,7 +395,7 @@ disk_reset:
        pop %ax
 
        mov $0, %ah
-       clc
+       clc_stack
        ret
 .endm
 
@@ -454,12 +454,12 @@ read_disk_drive_parameters:
        pop %bx
 
        /* do this last since it's the most sensitive */
-       clc
+       clc_stack
        ret
 
 alternate_disk_reset:
        movb $0, %ah
-       clc
+       clc_stack
        ret
 
 read_disk_drive_size:
@@ -498,21 +498,21 @@ read_disk_drive_size:
        freea
        pop %bx
 
-       clc
+       clc_stack
        ret
 
 check_if_extensions_present:
        mov $0x30, %ah
        mov $0xAA55, %bx
        mov $0x07, %cx
-       clc
+       clc_stack
        ret
 
 .macro extended_read_write_sectors cmd
        cmpb $10, 0(%si)
        jg 1f
        mov $1, %ah
-       stc
+       stc_stack
        ret
 1:
        push %ax
@@ -544,7 +544,7 @@ check_if_extensions_present:
        pop %ax
 
        mov $0, %ah
-       clc
+       clc_stack
        ret
 .endm
 
@@ -612,12 +612,12 @@ get_extended_drive_parameters:
        pop %ax
 
        mov $0, %ah
-       clc
+       clc_stack
        ret
 
 terminate_disk_emulation:
        mov $1, %ah
-       stc
+       stc_stack
        ret
 
 int13_handler:
-- 
1.5.6.5





reply via email to

[Prev in Thread] Current Thread [Next in Thread]