patch-2.2.19 linux/arch/i386/boot/setup.S
Next file: linux/arch/i386/config.in
Previous file: linux/arch/arm/vmlinux-armv.lds
Back to the patch index
Back to the overall index
- Lines: 202
- Date:
Sun Mar 25 11:37:29 2001
- Orig file:
v2.2.18/arch/i386/boot/setup.S
- Orig date:
Sun Mar 25 11:28:16 2001
diff -u --new-file --recursive --exclude-from /usr/src/exclude v2.2.18/arch/i386/boot/setup.S linux/arch/i386/boot/setup.S
@@ -18,7 +18,7 @@
! March 1993/June 1994 (Christoph.Niemann@linux.org)
!
! add APM BIOS checking by Stephen Rothwell, May 1994
-! (Stephen.Rothwell@canb.auug.org.au)
+! (sfr@canb.auug.org.au)
!
! High load stuff, initrd support and position independency
! by Hans Lermen & Werner Almesberger, February 1996
@@ -32,7 +32,7 @@
!
!
! A20 gating fiddled to work on AMD Elan AmSC4xx series by kira@linuxgrrls.org
-! july 1999
+! july 1999 - from a 2.0 patch by Christian Lademann <cal@zls.de>
!
#define __ASSEMBLY__
@@ -248,16 +248,46 @@
loader_ok:
! Get memory size (extended mem, kB)
-
+ xor eax, eax
+ mov [0x1e0], eax
#ifndef STANDARD_MEMORY_BIOS_CALL
- push ebx
+ mov [0x1e8], al
+meme820:
+ xor ebx, ebx
+ mov di,#0x2d0
+
+jmpe820:
+ mov eax,#0x0000e820
+ mov edx,#0x534d4150 ! Some biosen trash edx each call
+ mov ecx,#20
+ push ds
+ pop es
+ int 0x15
+ jc bail820
- xor ebx,ebx ! preload new memory slot with 0k
- mov [0x1e0], ebx
+ cmp eax,#0x534d4150
+ jne bail820
- mov ax,#0xe801
- int 0x15
- jc oldstylemem
+ cmp 16(di),#1
+ jne again820
+
+good820:
+ mov al,[0x1e8]
+ cmp al,#32
+ jnl bail820
+
+ incb [0x1e8]
+ mov ax,di
+ add ax,#20
+ mov di,ax
+again820:
+ cmp ebx,#0
+ jne jmpe820
+bail820:
+meme801:
+ mov ax,#0xe801
+ int 0x15
+ jc mem88
! Memory size is in 1 k chunksizes, to avoid confusing loadlin.
! We store the 0xe801 memory size in a completely different place,
@@ -266,23 +296,19 @@
! alternative new memory detection scheme, and it's sensible
! to write everything into the same place.)
- and ebx, #0xffff ! clear sign extend
- shl ebx, 6 ! and go from 64k to 1k chunks
- mov [0x1e0],ebx ! store extended memory size
-
- and eax, #0xffff ! clear sign extend
- add [0x1e0],eax ! and add lower memory into total size.
-
- ! and fall into the old memory detection code to populate the
- ! compatibility slot.
+ and ebx, #0xffff ! clear sign extend
+ shl ebx, 6 ! and go from 64k to 1k chunks
+ mov [0x1e0],ebx ! store extented memory size
+
+ and eax, #0xffff ! clear sign extend
+ add [0x1e0],eax ! and add lower memory into total size.
-oldstylemem:
- pop ebx
-#else
- mov dword ptr [0x1e0], #0
+ ! and fall into the old memory detection to populate the
+ ! compatibility slot.
+mem88:
#endif
- mov ah,#0x88
- int 0x15
+ mov ah,#0x88
+ int 0x15
mov [2],ax
! Set the keyboard repeat rate to the max
@@ -552,46 +578,44 @@
lgdt gdt_48 ! load gdt with whatever appropriate
! that was painless, now we enable A20
-
-! if this is SC410 or a few other bits we need to do it with the 'fast' method
-
- in al,#0x92 ! read "System Control Port A"
- or al,#0x02 ! Set "Alternate Gate A20" - Bit
- out #0x92,al ! write "System Control Port A"
+ call empty_8042
! do it the normal way too, so as not to upset normal machines
-
- call empty_8042
mov al,#0xD1 ! command write
out #0x64,al
call empty_8042
+
mov al,#0xDF ! A20 on
out #0x60,al
call empty_8042
+! if this is SC410 or a few other bits we need to do it with the 'fast' method
+!
+! 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
+
+ in al,#0x92 ! read "System Control Port A"
+ or al,#0x02 ! Set "Alternate Gate A20" - Bit
+ out #0x92,al ! write "System Control Port A"
+
! 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 is the int 0x1f vector,
-! which should be safe to use; any *unused* memory location < 0xfff0
-! should work here.
+! problem. The memory location used here (0x200) is the int 0x80
+! vector, which should be safe to use.
-#define TEST_ADDR 0x7c
-
- push ds
xor ax,ax ! segment 0x0000
- mov ds,ax
+ mov fs,ax
dec ax ! segment 0xffff (HMA)
mov gs,ax
- mov bx,[TEST_ADDR] ! we want to restore the value later
a20_wait:
- inc ax
- mov [TEST_ADDR],ax
+ inc ax ! unused memory location <0xfff0
+ seg fs
+ mov [0x200],ax ! we use the "int 0x80" vector
seg gs
- cmp ax,[TEST_ADDR+0x10]
+ cmp ax,[0x210] ! and its corresponding HMA addr
je a20_wait ! loop until no longer aliased
- mov [TEST_ADDR],bx ! restore original value
- pop ds
-
+
! make sure any possible coprocessor is properly reset..
xor ax,ax
@@ -771,10 +795,17 @@
!
! Some machines have delusions that the keyboard buffer is always full
! with no keyboard attached...
+!
+! If there is no keyboard controller, we will usually get 0xff
+! to all the reads. With each IO taking a microsecond and
+! a timeout of 100,000 iterations, this can take about half a
+! second ("delay" == outb to port 0x80). That should be ok,
+! and should also be plenty of time for a real keyboard controller
+! to empty.
empty_8042:
push ecx
- mov ecx,#0xFFFFFF
+ mov ecx,#100000
empty_8042_loop:
dec ecx
@@ -814,7 +845,7 @@
! Delay is needed after doing I/O
!
delay:
- .word 0x00eb ! jmp $+2
+ out #0x80,al
ret
!
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)