Example #1
0
static int
get_typematic(keyboard_t *kbd)
{
#if defined(__i386__) || defined(__amd64__)
	/*
	 * Only some systems allow us to retrieve the keyboard repeat
	 * rate previously set via the BIOS...
	 */
	x86regs_t regs;
	uint8_t *p;

	/*
	 * Traditional entry points of int 0x15 and 0x16 are fixed
	 * and later BIOSes follow them.  (U)EFI CSM specification
	 * also mandates these fixed entry points.
	 *
	 * Validate the entry points here before we proceed further.
	 * It's known that some recent laptops does not have the
	 * same entry point and hang on boot if we call it.
	 */
	if (x86bios_get_intr(0x15) != 0xf000f859 ||
	    x86bios_get_intr(0x16) != 0xf000e82e)
		return (ENODEV);

	/* Is BIOS system configuration table supported? */
	x86bios_init_regs(&regs);
	regs.R_AH = 0xc0;
	x86bios_intr(&regs, 0x15);
	if ((regs.R_FLG & PSL_C) != 0 || regs.R_AH != 0)
		return (ENODEV);

	/* Is int 0x16, function 0x09 supported? */
	p = x86bios_offset((regs.R_ES << 4) + regs.R_BX);
	if (readw(p) < 5 || (readb(p + 6) & 0x40) == 0)
		return (ENODEV);

	/* Is int 0x16, function 0x0306 supported? */
	x86bios_init_regs(&regs);
	regs.R_AH = 0x09;
	x86bios_intr(&regs, 0x16);
	if ((regs.R_AL & 0x08) == 0)
		return (ENODEV);

	x86bios_init_regs(&regs);
	regs.R_AX = 0x0306;
	x86bios_intr(&regs, 0x16);
	kbd->kb_delay1 = typematic_delay(regs.R_BH << 5);
	kbd->kb_delay2 = typematic_rate(regs.R_BL);
	return (0);
#else
	return (ENODEV);
#endif /* __i386__ || __amd64__ */
}
Example #2
0
static int
get_typematic(keyboard_t *kbd)
{
#if defined(__i386__) || defined(__amd64__)
    /*
     * Only some systems allow us to retrieve the keyboard repeat
     * rate previously set via the BIOS...
     */
    x86regs_t regs;
    uint8_t *p;

    if (x86bios_get_intr(0x15) == 0 || x86bios_get_intr(0x16) == 0)
        return (ENODEV);

    /* Is BIOS system configuration table supported? */
    x86bios_init_regs(&regs);
    regs.R_AH = 0xc0;
    x86bios_intr(&regs, 0x15);
    if ((regs.R_FLG & PSL_C) != 0 || regs.R_AH != 0)
        return (ENODEV);

    /* Is int 0x16, function 0x09 supported? */
    p = x86bios_offset((regs.R_ES << 4) + regs.R_BX);
    if (readw(p) < 5 || (readb(p + 6) & 0x40) == 0)
        return (ENODEV);

    /* Is int 0x16, function 0x0306 supported? */
    x86bios_init_regs(&regs);
    regs.R_AH = 0x09;
    x86bios_intr(&regs, 0x16);
    if ((regs.R_AL & 0x08) == 0)
        return (ENODEV);

    x86bios_init_regs(&regs);
    regs.R_AX = 0x0306;
    x86bios_intr(&regs, 0x16);
    kbd->kb_delay1 = typematic_delay(regs.R_BH << 5);
    kbd->kb_delay2 = typematic_rate(regs.R_BL);
    return (0);
#else
    return (ENODEV);
#endif /* __i386__ || __amd64__ */
}