lkml.org 
[lkml]   [2000]   [Nov]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
SubjectRe: setup.S: A20 enable sequence (once again)
Date
Followup to:  <00110621255000.12156@rob>
By author: Robert Kaiser <rob@sysgo.de>
In newsgroup: linux.dev.kernel
>
> On Mon, 06 Nov 2000 you wrote:
> H. Peter Anvin wrote
> > I just looked at the code, and it's worse than I first thought: if
> > memory location 0x200 happens to contain 0x0001 when the kernel is
> > entered, this code with loop indefinitely.
>
> Ooops, you're right !
>

As I already discussed with you in email, I think the patch I sent you
is better. I have attached it below for the benefit of other people,
I would very much like it if as many people as possible tested it out,
since the A20 stuff is mostly black magic; especially on systems that
are known to be troublesome, such as Toshiba laptops.

-hpa

--- setup.S.old Mon Oct 30 14:44:29 2000
+++ setup.S Mon Nov 6 12:13:50 2000
@@ -631,39 +631,45 @@
# appropriate

# that was painless, now we enable a20
+
+#
+# First, try the "fast A20 gate".
+#
+ inb $0x92,%al
+ orb $0x02,%al # Fast A20 on
+ andb $0xfe,%al # Don't reset CPU!
+ outb %al,$0x92
+
+#
+# Now comes the tricky part: some machines don't have a KBC and thus
+# would end up looping almost indefinitely here. HOWEVER, once we
+# have done the first command write, we must not stop the sequence.
+# Therefore, the first empty_8042 should check to see if the fast A20
+# did the trick and stop its probing at that stage; but subsequent ones
+# must not do so.
+#
+ movb $0x01,%dl # A20-sensitive
call empty_8042
+ jnz a20_wait # A20 already on?

movb $0xD1, %al # command write
outb %al, $0x64
+ xorb %dl,%dl # Not A20-sensitive
call empty_8042

movb $0xDF, %al # A20 on
outb %al, $0x60
+ xorb %dl,%dl # Not A20-sensitive
call empty_8042

-#
-# You must preserve the other bits here. Otherwise embarrasing things
-# like laptops powering off on boot happen. Corrected version by Kira
-# Brown from Linux 2.2
-#
- inb $0x92, %al #
- orb $02, %al # "fast A20" version
- outb %al, $0x92 # some chips have only this
-
# wait until a20 really *is* enabled; it can take a fair amount of
# time on certain systems; Toshiba Tecras are known to have this
# problem. The memory location used here (0x200) is the int 0x80
# vector, which should be safe to use.

- xorw %ax, %ax # segment 0x0000
- movw %ax, %fs
- decw %ax # segment 0xffff (HMA)
- movw %ax, %gs
a20_wait:
- incw %ax # unused memory location <0xfff0
- movw %ax, %fs:(0x200) # we use the "int 0x80" vector
- cmpw %gs:(0x210), %ax # and its corresponding HMA addr
- je a20_wait # loop until no longer aliased
+ call a20_test
+ jz a20_wait

# make sure any possible coprocessor is properly reset..
xorw %ax, %ax
@@ -825,14 +831,24 @@
#
# Some machines have delusions that the keyboard buffer is always full
# with no keyboard attached...
+#
+# If %dl is nonzero on entry, terminate with ZF=0 if A20 becomes alive,
+# otherwise terminate with ZF=1.

empty_8042:
pushl %ecx
- movl $0x00FFFFFF, %ecx
+ movl $0x000FFFFF, %ecx

empty_8042_loop:
decl %ecx
- jz empty_8042_end_loop
+ jz empty_8042_end_loop # ZF=1
+
+ # Always call the test routine to keep delays constant
+ call a20_test
+ jz ignore_a20
+ and %dl,%dl
+ jnz empty_8042_end_loop # ZF=0
+ignore_a20:

call delay

@@ -847,10 +863,38 @@
no_output:
testb $2, %al # is input buffer full?
jnz empty_8042_loop # yes - loop
+ # ZF=1
+
empty_8042_end_loop:
popl %ecx
ret

+a20_test:
+ pushw %ax
+ pushw %cx
+ pushw %fs
+ pushw %gs
+ xorw %ax, %ax # segment 0x0000
+ movw %ax, %fs
+ decw %ax # segment 0xffff (HMA)
+ movw %ax, %gs
+ movw 0x100,%cx
+ movw %fs:(0x200),%ax # So we keep cycling...
+ pushw %ax # Be extra paranoid...
+a20_loop:
+ incw %ax # unused memory location <0xfff0
+ movw %ax, %fs:(0x200) # we use the "int 0x80" vector
+ cmpw %gs:(0x210), %ax # and its corresponding HMA addr
+ jnz a20_ret # if ZF not set A20 is functional
+ loop a20_loop
+a20_ret:
+ popw %fs:(0x200)
+ popw %gs
+ popw %fs
+ popw %cx
+ popw %ax
+ ret # if ZF set A20 is not operational
+
# Read the cmos clock. Return the seconds in al
gettime:
pushw %cx
@@ -867,7 +911,8 @@

# Delay is needed after doing I/O
delay:
- jmp .+2 # jmp $+2
+ outb %al,$0x80 # What the main kernel uses
+ outb %al,$0x80
ret

# Descriptor tables
--
<hpa@transmeta.com> at work, <hpa@zytor.com> in private!
"Unix gives you enough rope to shoot yourself in the foot."
http://www.zytor.com/~hpa/puzzle.txt
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/
\
 
 \ /
  Last update: 2005-03-22 12:45    [W:0.039 / U:2.416 seconds]
©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site