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

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)