From owner-freebsd-hackers@FreeBSD.ORG Tue May 13 11:27:57 2003 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 28A8637B401; Tue, 13 May 2003 11:27:57 -0700 (PDT) Received: from anuket.mj.niksun.com (gwnew.niksun.com [65.115.46.162]) by mx1.FreeBSD.org (Postfix) with ESMTP id BD93B43F85; Tue, 13 May 2003 11:27:55 -0700 (PDT) (envelope-from jkim@niksun.com) Received: from daemon.mj.niksun.com (daemon.mj.niksun.com [10.70.0.244]) h4DIRL7F029079; Tue, 13 May 2003 14:27:21 -0400 (EDT) (envelope-from jkim@niksun.com) X-RAV-AntiVirus: This e-mail has been scanned for viruses. From: Jung-uk Kim Organization: Niksun, Inc. To: "M. Warner Losh" Date: Tue, 13 May 2003 14:27:20 -0400 User-Agent: KMail/1.5.1 References: <200305091456.40582.jkim@niksun.com> <200305121620.00049.jkim@niksun.com> <20030512.202637.104041634.imp@bsdimp.com> In-Reply-To: <20030512.202637.104041634.imp@bsdimp.com> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200305131427.20811.jkim@niksun.com> cc: freebsd-hackers@freebsd.org Subject: Re: boot2 keyboard probing problem (with patch) X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 May 2003 18:27:57 -0000 I made a patch for 5-CURRENT and it is little bit clearer than the previous version. (In fact, I haven't used x86 assembly for 10 years. It is funny that the last assembly project was MBR for something else. That said, please let me know if you see any weirdness.) Unfortunately, 5-CURRENT's boot2 is more tighter because of UFS2 support. You will have to do 'make BOOT2_UFS=UFS1_ONLY' or 'make BOOT2_UFS=UFS2_ONLY' to make the code usable. - - - >8 - - - >8 - - - 5-CURRENT patch - - - >8 - - - >8 - - - --- src/sys/boot/i386/boot2/boot2.c +++ src/sys/boot/i386/boot2/boot2.c @@ -371,7 +371,8 @@ char *arg = cmd; char *p, *q; unsigned int drv; - int c, i; + int i; + uint8_t c; while ((c = *arg++)) { if (c == ' ' || c == '\t' || c == '\n') @@ -387,7 +388,67 @@ opts ^= 1 << flags[i]; } if (opts & 1 << RBX_PROBEKBD) { +#ifdef UFS1_AND_UFS2 i = *(uint8_t *)PTOV(0x496) & 0x10; +#else + uint8_t func; + uint16_t retry; + __asm __volatile ( + "movb $2, %2\n\t" /* Wait for empty input buffer */ + "call wait\n\t" /* if func is 2 */ + "jmp flush\n" + "wait:\n\t" /* Wait for a buffer status */ + "movw $0xffff, %3\n" /* Initialize retry */ + "loop1:\n\t" + "inb $0x64, %1\n\t" /* Check controller status */ + "testb $1, %2\n\t" /* Check output buffer status */ + "jnz output\n\t" /* if func is 1 */ + "testb %2, %1\n\t" /* Input buffer empty? */ + "jz exit1\n\t" /* Exit if input buffer empty */ + "jmp delay\n" /* else delay */ + "output:\n\t" + "testb %2, %1\n\t" /* Output buffer full? */ + "jnz exit1\n" /* Exit if output buffer full */ + "delay:\n\t" + "xorb %1, %1\n\t" /* XXX delay hack */ + "outb %1, $0x80\n\t" /* Send 0 to port 0x80 (POST) */ + "loopw loop1\n" /* Retry */ + "exit1:\n\t" + "ret\n" + "flush:\n\t" + "movw $2000, %3\n" /* Initialize retry */ + "loop2:\n\t" + "xorb %1, %1\n\t" /* XXX delay hack */ + "outb %1, $0x80\n\t" /* Send 0 to port 0x80 (POST) */ + "inb $0x64, %1\n\t" /* Check controller status */ + "testb $1, %1\n\t" /* Any character to flush? */ + "jz again\n\t" /* Retry if buffer is empty */ + "inb $0x60, %1\n\t" /* Flush a character from buffer */ + "jmp flush\n" /* Reset counter and retry*/ + "again:\n\t" + "loopw loop2\n" /* Retry */ + "exit2:\n\t" + "movb $0xee, %1\n\t" /* Set echo command */ + "outb %1, $0x60\n\t" /* Send it! */ + "movb $2, %2\n\t" /* Wait for echo to be sent */ + "call wait\n\t" + "andw %3, %3\n\t" /* Is retry 0? */ + "jz fail\n\t" /* Echo not sent */ + "movb $1, %2\n\t" /* Wait for a character */ + "call wait\n\t" + "andw %3, %3\n\t" /* Is retry 0? */ + "jz fail\n\t" /* A character not received */ + "inb $0x60, %1\n\t" /* Receive a character */ + "cmpb $0xee, %1\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" + "xorl %0, %0\n" /* Set return code = 0 */ + "fine:" /* and exit */ + : "=r" (i), "=a" (c), "=r" (func), "=c" (retry) + ); +#endif printf("Keyboard: %s\n", i ? "yes" : "no"); if (!i) opts |= 1 << RBX_DUAL | 1 << RBX_SERIAL; - - - >8 - - - >8 - - - patch ends here - - - >8 - - - >8 - - - Following patch is for 4-STABLE. - - - >8 - - - >8 - - - 4-STABLE patch - - - >8 - - - >8 - - - --- src/sys/boot/i386/boot2/boot2.c +++ src/sys/boot/i386/boot2/boot2.c @@ -398,7 +398,8 @@ parse(char *arg) { char *p, *q; - int drv, c, i; + int drv, i; + uint8_t c; while ((c = *arg++)) { if (c == ' ' || c == '\t' || c == '\n') @@ -414,7 +415,63 @@ opts ^= 1 << flags[i]; } if (opts & 1 << RBX_PROBEKBD) { - i = *(uint8_t *)PTOV(0x496) & 0x10; + uint8_t func; + uint16_t retry; + __asm __volatile ( + "movb $2, %2\n\t" /* Wait for empty input buffer */ + "call wait\n\t" /* if func is 2 */ + "jmp flush\n" + "wait:\n\t" /* Wait for a buffer status */ + "movw $0xffff, %3\n" /* Initialize retry */ + "loop1:\n\t" + "inb $0x64, %1\n\t" /* Check controller status */ + "testb $1, %2\n\t" /* Check output buffer status */ + "jnz output\n\t" /* if func is 1 */ + "testb %2, %1\n\t" /* Input buffer empty? */ + "jz exit1\n\t" /* Exit if input buffer empty */ + "jmp delay\n" /* else delay */ + "output:\n\t" + "testb %2, %1\n\t" /* Output buffer full? */ + "jnz exit1\n" /* Exit if output buffer full */ + "delay:\n\t" + "xorb %1, %1\n\t" /* XXX delay hack */ + "outb %1, $0x80\n\t" /* Send 0 to port 0x80 (POST) */ + "loopw loop1\n" /* Retry */ + "exit1:\n\t" + "ret\n" + "flush:\n\t" + "movw $2000, %3\n" /* Initialize retry */ + "loop2:\n\t" + "xorb %1, %1\n\t" /* XXX delay hack */ + "outb %1, $0x80\n\t" /* Send 0 to port 0x80 (POST) */ + "inb $0x64, %1\n\t" /* Check controller status */ + "testb $1, %1\n\t" /* Any character to flush? */ + "jz again\n\t" /* Retry if buffer is empty */ + "inb $0x60, %1\n\t" /* Flush a character from buffer */ + "jmp flush\n" /* Reset counter and retry*/ + "again:\n\t" + "loopw loop2\n" /* Retry */ + "exit2:\n\t" + "movb $0xee, %1\n\t" /* Set echo command */ + "outb %1, $0x60\n\t" /* Send it! */ + "movb $2, %2\n\t" /* Wait for echo to be sent */ + "call wait\n\t" + "andw %3, %3\n\t" /* Is retry 0? */ + "jz fail\n\t" /* Echo not sent */ + "movb $1, %2\n\t" /* Wait for a character */ + "call wait\n\t" + "andw %3, %3\n\t" /* Is retry 0? */ + "jz fail\n\t" /* A character not received */ + "inb $0x60, %1\n\t" /* Receive a character */ + "cmpb $0xee, %1\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" + "xorl %0, %0\n" /* Set return code = 0 */ + "fine:" /* and exit */ + : "=r" (i), "=a" (c), "=r" (func), "=c" (retry) + ); printf("Keyboard: %s\n", i ? "yes" : "no"); if (!i) opts |= 1 << RBX_DUAL | 1 << RBX_SERIAL; - - - >8 - - - >8 - - - patch ends here - - - >8 - - - >8 - - - On Monday 12 May 2003 10:26 pm, M. Warner Losh wrote: > I am away at a funeral with limited IP connectivity. reviewing > assembler isn't something that I can do while travelling:-( I am sorry to hear it. Just let me know when you find copious free time. Thanks, Jung-uk Kim > Warner