boot2 keyboard probing problem (with patch)

Jung-uk Kim jkim at niksun.com
Fri May 9 12:13:10 PDT 2003


It seems the attachment was removed by Mailman. Grrr...

Jung-uk Kim

--- src/sys/boot/i386/boot2/boot2.c.old	Thu Oct 10 11:53:24 2002
+++ src/sys/boot/i386/boot2/boot2.c	Fri May  9 03:45:46 2003
@@ -414,7 +414,64 @@
 		opts ^= 1 << flags[i];
 	    }
 	    if (opts & 1 << RBX_PROBEKBD) {
-		i = *(uint8_t *)PTOV(0x496) & 0x10;
+		__asm __volatile (
+		    "\n\tmovb $2, %%ah\n\t" /* Wait for empty input buffer */
+		    "call wait\n\t"	    /* if %ah is 2 */
+		    "jmp flush\n"
+		    "wait:\n\t"		    /* Wait for a buffer status */
+		    "xorw %%cx, %%cx\n"	    /* Initialize retry */
+		    "loop1:\n\t"
+		    "decw %%cx\n\t"	    /* retry = 0xffff and retry-- */
+		    "jz exit1\n\t"	    /* Exit if retry is 0 */
+		    "inb $0x64, %%al\n\t"   /* Check controller status */
+		    "testb $1, %%ah\n\t"    /* Check output buffer status */
+		    "jnz output\n\t"	    /* if %ah is 1 */
+		    "testb %%ah, %%al\n\t"  /* Input buffer empty? */
+		    "jz exit1\n\t"	    /* Exit if input buffer empty */
+		    "jmp delay\n"	    /* else delay */
+		    "output:\n\t"
+		    "testb %%ah, %%al\n\t"  /* Output buffer full? */
+		    "jnz exit1\n"	    /* Exit if output buffer full */
+		    "delay:\n\t"
+		    "xorb %%al, %%al\n\t"   /* XXX delay hack */
+		    "outb %%al, $0x80\n\t"  /* Send 0 to port 0x80 (POST) */
+		    "jmp loop1\n"	    /* Retry */
+		    "exit1:\n\t"
+		    "ret\n"
+		    "flush:\n\t"
+		    "movw $2001, %%cx\n"    /* Initialize retry */
+		    "loop2:\n\t"
+		    "decw %%cx\n\t"	    /* retry = 2000 and retry-- */
+		    "jz exit2\n\t"	    /* Exit if retry is 0 */
+		    "xorb %%al, %%al\n\t"   /* XXX delay hack */
+		    "outb %%al, $0x80\n\t"  /* Send 0 to port 0x80 (POST) */
+		    "inb $0x64, %%al\n\t"   /* Check controller status */
+		    "testb $1, %%al\n\t"    /* Any character to flush? */
+		    "jz loop2\n\t"	    /* Retry if buffer is empty */
+		    "inb $0x60, %%al\n\t"   /* Flush a character from buffer */
+		    "movw $2001, %%cx\n\t"  /* Reinitialize retry */
+		    "jmp loop2\n"	    /* Retry */
+		    "exit2:\n\t"
+		    "movb $0xee, %%al\n\t"  /* Set echo command */
+		    "outb %%al, $0x60\n\t"  /* Send it! */
+		    "movb $2, %%ah\n\t"	    /* Wait for echo to be sent */
+		    "call wait\n\t"
+		    "andw %%cx, %%cx\n\t"   /* Is retry 0? */
+		    "jz fail\n\t"	    /* Echo not sent */
+		    "movb $1, %%ah\n\t"	    /* Wait for a character */
+		    "call wait\n\t"
+		    "andw %%cx, %%cx\n\t"   /* Is retry 0? */
+		    "jz fail\n\t"	    /* A character not received */
+		    "inb $0x60, %%al\n\t"   /* Receive a character */
+		    "cmpb $0xee, %%al\n\t"  /* Is this an echo? */
+		    "jne fail\n\t"	    /* Fail if echo not received */
+		    "movl $1, %0\n\t"	    /* Set return code = 1 */
+		    "jmp fine\n"	    /* and exit */
+		    "fail:\n\t"
+		    "movl $0, %0\n"	    /* Set return code = 0 */
+		    "fine:\n"		    /* and exit */
+		    : "=r" (i) : : "ah", "al", "cx"
+		);
 		printf("Keyboard: %s\n", i ? "yes" : "no");
 		if (!i)
 		    opts |= 1 << RBX_DUAL | 1 << RBX_SERIAL;



More information about the freebsd-hackers mailing list