summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2009-04-21 16:08:07 -0700
committerH. Peter Anvin <hpa@linux.intel.com>2009-04-21 16:08:07 -0700
commit8e1b32e8f5f28e49eff7a0cf39e7d2d31e379b1c (patch)
tree16733882e862aa806c94952e6b8f9223b6e823bc
parent31937531087fb47aa4a3a218e8114b32176f8683 (diff)
downloadsyslinux-8e1b32e8f5f28e49eff7a0cf39e7d2d31e379b1c.tar.gz
a20: try to avoid io_delay if A20 is already enabled
We have at least the possibility to avoid io_delay if A20 is already enabled. Thus, give it a try. Furthermore, when calling enable_a20, always try the zero-work case first, since we may have been enabled by a previous call. This should improve performance of the rm/pm ping-pong. Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
-rw-r--r--core/bcopy32.inc44
1 files changed, 19 insertions, 25 deletions
diff --git a/core/bcopy32.inc b/core/bcopy32.inc
index c4edc715..f2cc6cab 100644
--- a/core/bcopy32.inc
+++ b/core/bcopy32.inc
@@ -193,13 +193,6 @@ simple_pm_call:
%define IO_DELAY_PORT 80h ; Invalid port (we hope!)
%define disable_wait 32 ; How long to wait for a disable
-; Note the skip of 2 here
-%define A20_DUNNO 0 ; A20 type unknown
-%define A20_NONE 2 ; A20 always on?
-%define A20_BIOS 4 ; A20 BIOS enable
-%define A20_KBC 6 ; A20 through KBC
-%define A20_FAST 8 ; A20 through port 92h
-
slow_out: out dx, al ; Fall through
_io_delay: out IO_DELAY_PORT,al
@@ -228,22 +221,19 @@ try_enable_a20:
%endif
;
-; If the A20 type is known, jump straight to type
-;
- jmp word [cs:A20Ptr]
-
-;
-; First, see if we are on a system with no A20 gate
+; First, see if we are on a system with no A20 gate, or the A20 gate
+; is already enabled for us...
;
-a20_dunno:
a20_none:
- mov word [cs:A20Ptr], a20_none
call a20_test
jnz a20_done
+ ; Otherwise, see if we had something memorized...
+ jmp word [cs:A20Ptr]
;
; Next, try the BIOS (INT 15h AX=2401h)
;
+a20_dunno:
a20_bios:
mov word [cs:A20Ptr], a20_bios
mov ax,2401h
@@ -337,20 +327,24 @@ a20_done: popad
; This routine tests if A20 is enabled (ZF = 0). This routine
; must not destroy any register contents.
;
+; The no-write early out avoids the io_delay in the (presumably common)
+; case of A20 already enabled (e.g. from a previous call.)
+;
a20_test:
push es
push cx
- push ax
- mov cx,0FFFFh ; HMA = segment 0FFFFh
+ push eax
+ mov cx,0FFFFh ; HMA = segment 0FFFFh
mov es,cx
- mov cx,32 ; Loop count
- mov ax,[cs:A20Test]
-.a20_wait: inc ax
- mov [cs:A20Test],ax
- io_delay ; Serialize, and fix delay
- cmp ax,[es:A20Test+10h]
- loopz .a20_wait
-.a20_done: pop ax
+ mov eax,[cs:A20Test]
+ mov cx,32 ; Loop count
+ jmp .test ; First iteration = early out
+.wait: inc eax
+ mov [cs:A20Test],eax
+ io_delay ; Serialize, and fix delay
+.test: cmp eax,[es:A20Test+10h]
+ loopz .wait
+.done: pop eax
pop cx
pop es
ret