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(®s); regs.R_AH = 0xc0; x86bios_intr(®s, 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(®s); regs.R_AH = 0x09; x86bios_intr(®s, 0x16); if ((regs.R_AL & 0x08) == 0) return (ENODEV); x86bios_init_regs(®s); regs.R_AX = 0x0306; x86bios_intr(®s, 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__ */ }
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(®s); regs.R_AH = 0xc0; x86bios_intr(®s, 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(®s); regs.R_AH = 0x09; x86bios_intr(®s, 0x16); if ((regs.R_AL & 0x08) == 0) return (ENODEV); x86bios_init_regs(®s); regs.R_AX = 0x0306; x86bios_intr(®s, 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__ */ }
static int dpms_call_bios(int subfunction, int *bh) { x86regs_t regs; if (x86bios_get_intr(0x10) == 0) return (ENXIO); x86bios_init_regs(®s); regs.R_AX = VBE_DPMS_FUNCTION; regs.R_BL = subfunction; regs.R_BH = *bh; x86bios_intr(®s, 0x10); if (regs.R_AX != 0x004f) return (ENXIO); *bh = regs.R_BH; return (0); }