Explorar el Código

Avoid draining the keyboard buffer during gateA20_set(). It shouldn't

technically be necessary, because the "enable A20" command requires
only that the keyboard controller is ready to accept input (i.e. that
its input buffer is empty), and shouldn't also require that the
keyboard is ready to send output (i.e. that its output buffer is also
empty).  See http://www.smsc.com/main/tools/io-bios/42i.pdf section
3.1 ("Command Invocation") for a justification.

gateA20_set() is called on every real-mode transition (in case some
idiot piece of external code such as Intel's PXE stack decided it
would be fun to re-disable A20), so draining the keyboard buffer means
that we end up losing keypresses on some systems.  In particular, this
makes typing at the command line almost impossible, and causes
Etherboot to ignore Ctrl-Alt-Del.

We should really implement a gateA20_test() function to verify that
gate A20 has been correctly enabled, and think about adding other
commonly-used methods such as Fast Gate A20.
tags/v0.9.3
Michael Brown hace 17 años
padre
commit
8bff0f0619
Se han modificado 1 ficheros con 10 adiciones y 8 borrados
  1. 10
    8
      src/arch/i386/firmware/pcbios/gateA20.c

+ 10
- 8
src/arch/i386/firmware/pcbios/gateA20.c Ver fichero

@@ -27,16 +27,17 @@ enum { Disable_A20 = 0x2400, Enable_A20 = 0x2401, Query_A20_Status = 0x2402,
27 27
 #define CF ( 1 << 0 )
28 28
 
29 29
 #ifndef IBM_L40
30
-static void empty_8042 ( void )
31
-{
30
+static void empty_8042 ( void ) {
32 31
 	unsigned long time;
33
-	char st;
34 32
 
35 33
 	time = currticks() + TICKS_PER_SEC;	/* max wait of 1 second */
36
-	while ((((st = inb(K_CMD)) & K_OBUF_FUL) ||
37
-	       (st & K_IBUF_FUL)) &&
38
-	       currticks() < time)
39
-		inb(K_RDWR);
34
+	while ( ( inb ( K_CMD ) & K_IBUF_FUL ) &&
35
+		currticks() < time ) {
36
+		/* Do nothing.  In particular, do *not* read from
37
+		 * K_RDWR, because that will drain the keyboard buffer
38
+		 * and lose keypresses.
39
+		 */
40
+	}
40 41
 }
41 42
 #endif	/* IBM_L40 */
42 43
 
@@ -66,6 +67,7 @@ void gateA20_set ( void ) {
66 67
 			       : "=r" ( flags ), "=a" ( discard_a )
67 68
 			       : "a" ( Enable_A20 ) );
68 69
 
70
+
69 71
 	if ( flags & CF ) {
70 72
 		/* INT 15 method failed, try alternatives */
71 73
 #ifdef	IBM_L40
@@ -78,7 +80,7 @@ void gateA20_set ( void ) {
78 80
 		empty_8042();
79 81
 #endif	/* IBM_L40 */
80 82
 	}
81
-	
83
+
82 84
 	reentry_guard = 0;
83 85
 }
84 86
 

Loading…
Cancelar
Guardar