Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/bhyve/bhyverun.c
Show First 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | |||||
#include "bhyverun.h" | #include "bhyverun.h" | ||||
#include "acpi.h" | #include "acpi.h" | ||||
#include "atkbdc.h" | #include "atkbdc.h" | ||||
#include "bootrom.h" | #include "bootrom.h" | ||||
#include "config.h" | #include "config.h" | ||||
#include "inout.h" | #include "inout.h" | ||||
#include "debug.h" | #include "debug.h" | ||||
#include "e820.h" | |||||
#include "fwctl.h" | #include "fwctl.h" | ||||
#include "gdb.h" | #include "gdb.h" | ||||
#include "ioapic.h" | #include "ioapic.h" | ||||
#include "kernemu_dev.h" | #include "kernemu_dev.h" | ||||
#include "mem.h" | #include "mem.h" | ||||
#include "mevent.h" | #include "mevent.h" | ||||
#include "mptbl.h" | #include "mptbl.h" | ||||
#include "pci_emul.h" | #include "pci_emul.h" | ||||
#include "pci_irq.h" | #include "pci_irq.h" | ||||
#include "pci_lpc.h" | #include "pci_lpc.h" | ||||
#include "qemu_fwcfg.h" | |||||
#include "smbiostbl.h" | #include "smbiostbl.h" | ||||
#ifdef BHYVE_SNAPSHOT | #ifdef BHYVE_SNAPSHOT | ||||
#include "snapshot.h" | #include "snapshot.h" | ||||
#endif | #endif | ||||
#include "xmsr.h" | #include "xmsr.h" | ||||
#include "spinup_ap.h" | #include "spinup_ap.h" | ||||
#include "rtc.h" | #include "rtc.h" | ||||
#include "vmgenc.h" | #include "vmgenc.h" | ||||
▲ Show 20 Lines • Show All 1,133 Lines • ▼ Show 20 Lines | #ifdef BHYVE_SNAPSHOT | ||||
restore_file = NULL; | restore_file = NULL; | ||||
#endif | #endif | ||||
init_config(); | init_config(); | ||||
set_defaults(); | set_defaults(); | ||||
progname = basename(argv[0]); | progname = basename(argv[0]); | ||||
#ifdef BHYVE_SNAPSHOT | #ifdef BHYVE_SNAPSHOT | ||||
optstr = "aehuwxACDHIPSWYk:o:p:G:c:s:m:l:U:r:"; | optstr = "aehuwxACDHIPSWYk:f:o:p:G:c:s:m:l:U:r:"; | ||||
#else | #else | ||||
optstr = "aehuwxACDHIPSWYk:o:p:G:c:s:m:l:U:"; | optstr = "aehuwxACDHIPSWYk:f:o:p:G:c:s:m:l:U:"; | ||||
#endif | #endif | ||||
while ((c = getopt(argc, argv, optstr)) != -1) { | while ((c = getopt(argc, argv, optstr)) != -1) { | ||||
switch (c) { | switch (c) { | ||||
case 'a': | case 'a': | ||||
set_config_bool("x86.x2apic", false); | set_config_bool("x86.x2apic", false); | ||||
break; | break; | ||||
case 'A': | case 'A': | ||||
set_config_bool("acpi_tables", true); | set_config_bool("acpi_tables", true); | ||||
Show All 11 Lines | case 'p': | ||||
if (topology_parse(optarg) != 0) { | if (topology_parse(optarg) != 0) { | ||||
errx(EX_USAGE, "invalid cpu topology " | errx(EX_USAGE, "invalid cpu topology " | ||||
"'%s'", optarg); | "'%s'", optarg); | ||||
} | } | ||||
break; | break; | ||||
case 'C': | case 'C': | ||||
set_config_bool("memory.guest_in_core", true); | set_config_bool("memory.guest_in_core", true); | ||||
break; | break; | ||||
case 'f': | |||||
if (qemu_fwcfg_parse_cmdline_arg(optarg) != 0) { | |||||
exit(1); | |||||
} | |||||
break; | |||||
case 'G': | case 'G': | ||||
parse_gdb_options(optarg); | parse_gdb_options(optarg); | ||||
break; | break; | ||||
case 'k': | case 'k': | ||||
parse_simple_config_file(optarg); | parse_simple_config_file(optarg); | ||||
break; | break; | ||||
case 'l': | case 'l': | ||||
if (strncmp(optarg, "help", strlen(optarg)) == 0) { | if (strncmp(optarg, "help", strlen(optarg)) == 0) { | ||||
▲ Show 20 Lines • Show All 157 Lines • ▼ Show 20 Lines | #endif | ||||
init_bootrom(ctx); | init_bootrom(ctx); | ||||
atkbdc_init(ctx); | atkbdc_init(ctx); | ||||
pci_irq_init(ctx); | pci_irq_init(ctx); | ||||
ioapic_init(ctx); | ioapic_init(ctx); | ||||
rtc_init(ctx); | rtc_init(ctx); | ||||
sci_init(ctx); | sci_init(ctx); | ||||
const char *fwcfg = lpc_fwcfg(); | |||||
if (lpc_bootrom()) { | |||||
if (fwcfg == NULL || strcmp(fwcfg, "bhyve") == 0) { | |||||
fwctl_init(); | |||||
} else if (strcmp(fwcfg, "qemu") == 0) { | |||||
if (qemu_fwcfg_init(ctx) != 0) { | |||||
fprintf(stderr, | |||||
"qemu fwcfg initialization error"); | |||||
exit(4); | |||||
} | |||||
/* | /* | ||||
* QEMU uses fwcfg item 0x0f (FW_CFG_MAX_CPUS) to report | |||||
* the number of cpus to the guest but states that it | |||||
* has a special meaning for x86. Don't know yet if that | |||||
* can cause unintented side-effects. Use an own fwcfg | |||||
* item to be safe. | |||||
* | |||||
* QEMU comment: | |||||
* FW_CFG_MAX_CPUS is a bit confusing/problematic | |||||
* on x86: | |||||
* | |||||
* For machine types prior to 1.8, SeaBIOS needs | |||||
* FW_CFG_MAX_CPUS for building MPTable, ACPI MADT, | |||||
* ACPI CPU hotplug and ACPI SRAT table, that | |||||
* tables are based on xAPIC ID and QEMU<->SeaBIOS | |||||
* interface for CPU hotplug also uses APIC ID and | |||||
* not "CPU index". This means that FW_CFG_MAX_CPUS | |||||
* is not the "maximum number of CPUs", but the | |||||
* "limit to the APIC ID values SeaBIOS may see". | |||||
* | |||||
* So for compatibility reasons with old BIOSes we | |||||
* are stuck with "etc/max-cpus" actually being | |||||
* apic_id_limit | |||||
*/ | |||||
if (qemu_fwcfg_add_file("opt/bhyve/hw.ncpu", | |||||
sizeof(guest_ncpus), &guest_ncpus) != 0) { | |||||
fprintf(stderr, | |||||
"Could not add qemu fwcfg opt/bhyve/hw.ncpu"); | |||||
exit(4); | |||||
} | |||||
if (e820_init(ctx) != 0) { | |||||
fprintf(stderr, "Unable to setup E820"); | |||||
exit(4); | |||||
} | |||||
} else { | |||||
fprintf(stderr, "Invalid fwcfg %s", fwcfg); | |||||
exit(4); | |||||
} | |||||
} | |||||
/* | |||||
* Exit if a device emulation finds an error in its initilization | * Exit if a device emulation finds an error in its initilization | ||||
*/ | */ | ||||
if (init_pci(ctx) != 0) { | if (init_pci(ctx) != 0) { | ||||
perror("device emulation initialization error"); | perror("device emulation initialization error"); | ||||
exit(4); | exit(4); | ||||
} | } | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | #endif | ||||
error = smbios_build(ctx); | error = smbios_build(ctx); | ||||
assert(error == 0); | assert(error == 0); | ||||
if (get_config_bool("acpi_tables")) { | if (get_config_bool("acpi_tables")) { | ||||
error = acpi_build(ctx, guest_ncpus); | error = acpi_build(ctx, guest_ncpus); | ||||
assert(error == 0); | assert(error == 0); | ||||
} | } | ||||
if (lpc_bootrom()) | if (strcmp(fwcfg, "qemu") == 0) { | ||||
fwctl_init(); | struct qemu_fwcfg_item *const e820_fwcfg_item = | ||||
e820_get_fwcfg_item(); | |||||
if (e820_fwcfg_item == NULL) { | |||||
fprintf(stderr, "invalid e820 table"); | |||||
exit(4); | |||||
} | |||||
if (qemu_fwcfg_add_file("etc/e820", e820_fwcfg_item->size, | |||||
e820_fwcfg_item->data) != 0) { | |||||
fprintf(stderr, "could not add qemu fwcfg etc/e820"); | |||||
exit(4); | |||||
} | |||||
free(e820_fwcfg_item); | |||||
} | |||||
/* | /* | ||||
* Change the proc title to include the VM name. | * Change the proc title to include the VM name. | ||||
*/ | */ | ||||
setproctitle("%s", vmname); | setproctitle("%s", vmname); | ||||
#ifndef WITHOUT_CAPSICUM | #ifndef WITHOUT_CAPSICUM | ||||
caph_cache_catpages(); | caph_cache_catpages(); | ||||
▲ Show 20 Lines • Show All 53 Lines • Show Last 20 Lines |