static int get_typematic(keyboard_t *kbd) { #ifdef __i386__ /* * Only some systems allow us to retrieve the keyboard repeat * rate previously set via the BIOS... */ struct vm86frame vmf; u_int32_t p; bzero(&vmf, sizeof(vmf)); vmf.vmf_ax = 0xc000; vm86_intcall(0x15, &vmf); if ((vmf.vmf_eflags & PSL_C) || vmf.vmf_ah) return ENODEV; p = BIOS_PADDRTOVADDR(((u_int32_t)vmf.vmf_es << 4) + vmf.vmf_bx); if ((readb(p + 6) & 0x40) == 0) /* int 16, function 0x09 supported? */ return ENODEV; vmf.vmf_ax = 0x0900; vm86_intcall(0x16, &vmf); if ((vmf.vmf_al & 0x08) == 0) /* int 16, function 0x0306 supported? */ return ENODEV; vmf.vmf_ax = 0x0306; vm86_intcall(0x16, &vmf); kbd->kb_delay1 = typematic_delay(vmf.vmf_bh << 5); kbd->kb_delay2 = typematic_rate(vmf.vmf_bl); return 0; #else return ENODEV; #endif /* __i386__ */ }
/* Functions */ static void bios_mcabus_present(void * dummy) { struct vm86frame vmf; struct sys_config * scp; vm_offset_t paddr; bzero(&vmf, sizeof(struct vm86frame)); vmf.vmf_ah = 0xc0; if (vm86_intcall(0x15, &vmf)) { if (bootverbose) { printf("BIOS SDT: INT call failed.\n"); } return; } if ((vmf.vmf_ah != 0) && (vmf.vmf_flags & 0x01)) { if (bootverbose) { printf("BIOS SDT: Not supported. Not PS/2?\n"); printf("BIOS SDT: AH 0x%02x, Flags 0x%04x\n", vmf.vmf_ah, vmf.vmf_flags); } return; } paddr = vmf.vmf_es; paddr = (paddr << 4) + vmf.vmf_bx; scp = (struct sys_config *)BIOS_PADDRTOVADDR(paddr); if (bootverbose) { printf("BIOS SDT: model 0x%02x, submodel 0x%02x, bios_rev 0x%02x\n", scp->model, scp->submodel, scp->bios_rev); printf("BIOS SDT: features 0x%b\n", scp->feature, "\20" "\01MCA+ISA" "\02MCA" "\03EBDA" "\04WAITEV" "\05KBDINT" "\06RTC" "\07IC2" "\08DMA3" "\n"); } MCA_system = ((scp->feature & FEATURE_MCABUS) ? 1 : 0); if (MCA_system) printf("MicroChannel Architecture System detected.\n"); return; }