Index: sys/boot/i386/libi386/i386_module.c =================================================================== --- sys/boot/i386/libi386/i386_module.c +++ sys/boot/i386/libi386/i386_module.c @@ -32,12 +32,54 @@ * */ +#include +#include +#include + +static char hv_vendor[16]; + +/* + * See Section 3.2 Hypervisor Discovery of Hyper-V's Hypervisor Top Level + * Functional Specification or the kernel's function identify_hypervisor(). + */ +static int +running_on_hyperv(void) +{ + unsigned int regs[4]; + + do_cpuid(1, regs); + if (!(regs[2] & 0x80000000)) + return (0); + + do_cpuid(0x40000000, regs); + if (regs[0] < 0x40000000) + return (0); + + ((unsigned int *)&hv_vendor)[0] = regs[1]; + ((unsigned int *)&hv_vendor)[1] = regs[2]; + ((unsigned int *)&hv_vendor)[2] = regs[3]; + hv_vendor[12] = '\0'; + + if (strcmp(hv_vendor, "Microsoft Hv") != 0) + return (0); + + return (1); +} + /* * Use voodoo to load modules required by current hardware. */ int i386_autoload(void) { + if (running_on_hyperv()) { + /* + * vt(4) is pretty slow in graphics mode when FreeBSD guest runs on + * Hyper-V, but luckily it is fast enough in text mode. + */ + if (getenv("hw.vga.textmode") == NULL) + setenv("hw.vga.textmode", "1", 1); + } /* XXX use PnP to locate stuff here */ return(0);