]> xenbits.xensource.com Git - people/andrewcoop/seabios.git/commitdiff
stacks: Don't update the A20 settings if they haven't changed
authorKevin O'Connor <kevin@koconnor.net>
Tue, 16 May 2017 15:47:27 +0000 (11:47 -0400)
committerKevin O'Connor <kevin@koconnor.net>
Tue, 16 May 2017 16:13:32 +0000 (12:13 -0400)
The A20 setting is almost always enabled - only issue an outb() if the
A20 is actually changing.  This reduces the number of outb() calls.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
src/fw/smm.c
src/stacks.c
src/x86.h

index 178959c41391ca512effdc3721a8817c80c75c2f..d90e43a9ef65755bc2cd5f6c04267e4d001680c0 100644 (file)
@@ -109,7 +109,8 @@ handle_smi(u16 cs)
                 dprintf(9, "smm cpu ret %x esp=%x\n", regs[3], regs[4]);
                 memcpy(&smm->cpu, &smm->backup2, sizeof(smm->cpu));
                 memcpy(&smm->cpu.i32.eax, regs, sizeof(regs));
-                set_a20(smm->backup_a20);
+                if (!smm->backup_a20)
+                    set_a20(0);
                 smm->cpu.i32.eip = regs[3];
             }
         } else if (rev == SMM_REV_I64) {
@@ -125,7 +126,8 @@ handle_smi(u16 cs)
             } else if ((u32)smm->cpu.i64.rcx == CALL32SMM_RETURNID) {
                 memcpy(&smm->cpu, &smm->backup2, sizeof(smm->cpu));
                 memcpy(&smm->cpu.i64.rdi, regs, sizeof(regs));
-                set_a20(smm->backup_a20);
+                if (!smm->backup_a20)
+                    set_a20(0);
                 smm->cpu.i64.rip = (u32)regs[4];
             }
         }
index 9fec2fb7cffab469774728940a0d8c4711b9425d..f4d15ce991eee7a4339fd5d0b7c54c69a258c6a0 100644 (file)
@@ -84,7 +84,9 @@ call32_post(void)
 
     if (!CONFIG_CALL32_SMM || method != C16_SMM) {
         // Restore a20
-        set_a20(GET_LOW(Call16Data.a20));
+        u8 a20 = GET_LOW(Call16Data.a20);
+        if (!a20)
+            set_a20(0);
 
         // Restore gdt and fs/gs
         struct descloc_s gdt;
index a770e6f69b06b798b768fd27100c44621af506fb..4aea65cd81c3c3a9f1adf10bbf6f6ae1c78a9816 100644 (file)
--- a/src/x86.h
+++ b/src/x86.h
@@ -258,9 +258,10 @@ static inline u8 get_a20(void) {
 }
 
 static inline u8 set_a20(u8 cond) {
-    u8 val = inb(PORT_A20);
-    outb((val & ~A20_ENABLE_BIT) | (cond ? A20_ENABLE_BIT : 0), PORT_A20);
-    return (val & A20_ENABLE_BIT) != 0;
+    u8 val = inb(PORT_A20), a20_enabled = (val & A20_ENABLE_BIT) != 0;
+    if (a20_enabled != !!cond)
+        outb(val ^ A20_ENABLE_BIT, PORT_A20);
+    return a20_enabled;
 }
 
 // x86.c