mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-23 03:29:43 +00:00
machine: use QAPI struct for boot configuration
As part of converting -boot to a property with a QAPI type, define the struct and use it throughout QEMU to access boot configuration. machine_boot_parse takes care of doing the QemuOpts->QAPI conversion by hand, for now. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Message-Id: <20220414165300.555321-2-pbonzini@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
70be1d93f9
commit
97ec4d21e0
@ -1365,7 +1365,7 @@ static void n8x0_init(MachineState *machine,
|
||||
}
|
||||
|
||||
if (option_rom[0].name &&
|
||||
(machine->boot_order[0] == 'n' || !machine->kernel_filename)) {
|
||||
(machine->boot_config.order[0] == 'n' || !machine->kernel_filename)) {
|
||||
uint8_t *nolo_tags = g_new(uint8_t, 0x10000);
|
||||
/* No, wait, better start at the ROM. */
|
||||
s->mpu->cpu->env.regs[15] = OMAP2_Q2_BASE + 0x400000;
|
||||
|
@ -784,6 +784,68 @@ static void machine_set_smp(Object *obj, Visitor *v, const char *name,
|
||||
machine_parse_smp_config(ms, config, errp);
|
||||
}
|
||||
|
||||
void machine_boot_parse(MachineState *ms, QemuOpts *opts, Error **errp)
|
||||
{
|
||||
MachineClass *machine_class = MACHINE_GET_CLASS(ms);
|
||||
const char *s;
|
||||
ERRP_GUARD();
|
||||
|
||||
ms->boot_config = (BootConfiguration) {
|
||||
.has_order = true,
|
||||
.order = (char *)machine_class->default_boot_order,
|
||||
.has_strict = true,
|
||||
.strict = false,
|
||||
};
|
||||
if (!opts) {
|
||||
return;
|
||||
}
|
||||
|
||||
s = qemu_opt_get(opts, "order");
|
||||
if (s) {
|
||||
validate_bootdevices(s, errp);
|
||||
if (*errp) {
|
||||
return;
|
||||
}
|
||||
ms->boot_config.order = (char *)s;
|
||||
}
|
||||
|
||||
s = qemu_opt_get(opts, "once");
|
||||
if (s) {
|
||||
validate_bootdevices(s, errp);
|
||||
if (*errp) {
|
||||
return;
|
||||
}
|
||||
ms->boot_config.has_once = true;
|
||||
ms->boot_config.once = (char *)s;
|
||||
}
|
||||
|
||||
s = qemu_opt_get(opts, "splash");
|
||||
if (s) {
|
||||
ms->boot_config.has_splash = true;
|
||||
ms->boot_config.splash = (char *)s;
|
||||
}
|
||||
|
||||
s = qemu_opt_get(opts, "splash-time");
|
||||
if (s) {
|
||||
ms->boot_config.has_splash_time = true;
|
||||
ms->boot_config.splash_time = qemu_opt_get_number(opts, "splash-time", -1);
|
||||
}
|
||||
|
||||
s = qemu_opt_get(opts, "reboot-timeout");
|
||||
if (s) {
|
||||
ms->boot_config.has_reboot_timeout = true;
|
||||
ms->boot_config.reboot_timeout = qemu_opt_get_number(opts, "reboot-timeout", -1);
|
||||
}
|
||||
|
||||
s = qemu_opt_get(opts, "menu");
|
||||
if (s) {
|
||||
ms->boot_config.has_menu = true;
|
||||
ms->boot_config.menu = qemu_opt_get_bool(opts, "menu", false);
|
||||
}
|
||||
|
||||
ms->boot_config.strict = qemu_opt_get_bool(opts, "strict", false);
|
||||
}
|
||||
|
||||
static void machine_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
MachineClass *mc = MACHINE_CLASS(oc);
|
||||
@ -1229,9 +1291,9 @@ void qdev_machine_creation_done(void)
|
||||
{
|
||||
cpu_synchronize_all_post_init();
|
||||
|
||||
if (current_machine->boot_once) {
|
||||
qemu_boot_set(current_machine->boot_once, &error_fatal);
|
||||
qemu_register_reset(restore_boot_order, g_strdup(current_machine->boot_order));
|
||||
if (current_machine->boot_config.has_once) {
|
||||
qemu_boot_set(current_machine->boot_config.once, &error_fatal);
|
||||
qemu_register_reset(restore_boot_order, g_strdup(current_machine->boot_config.order));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -147,7 +147,7 @@ static FWCfgState *create_fw_cfg(MachineState *ms)
|
||||
fw_cfg_add_file(fw_cfg, "/etc/power-button-addr",
|
||||
g_memdup(&val, sizeof(val)), sizeof(val));
|
||||
|
||||
fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ms->boot_order[0]);
|
||||
fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ms->boot_config.order[0]);
|
||||
qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
|
||||
|
||||
return fw_cfg;
|
||||
@ -391,8 +391,8 @@ static void machine_hppa_init(MachineState *machine)
|
||||
* mode (kernel_entry=1), and to boot from CD (gr[24]='d')
|
||||
* or hard disc * (gr[24]='c').
|
||||
*/
|
||||
kernel_entry = boot_menu ? 1 : 0;
|
||||
cpu[0]->env.gr[24] = machine->boot_order[0];
|
||||
kernel_entry = machine->boot_config.has_menu ? machine->boot_config.menu : 0;
|
||||
cpu[0]->env.gr[24] = machine->boot_config.order[0];
|
||||
}
|
||||
|
||||
/* We jump to the firmware entry routine and pass the
|
||||
|
@ -675,7 +675,7 @@ void pc_cmos_init(PCMachineState *pcms,
|
||||
object_property_set_link(OBJECT(pcms), "rtc_state", OBJECT(s),
|
||||
&error_abort);
|
||||
|
||||
set_boot_dev(s, MACHINE(pcms)->boot_order, &error_fatal);
|
||||
set_boot_dev(s, MACHINE(pcms)->boot_config.order, &error_fatal);
|
||||
|
||||
val = 0;
|
||||
val |= 0x02; /* FPU is there */
|
||||
|
@ -178,21 +178,13 @@ error:
|
||||
|
||||
static void fw_cfg_bootsplash(FWCfgState *s)
|
||||
{
|
||||
const char *boot_splash_filename = NULL;
|
||||
const char *boot_splash_time = NULL;
|
||||
char *filename, *file_data;
|
||||
gsize file_size;
|
||||
int file_type;
|
||||
|
||||
/* get user configuration */
|
||||
QemuOptsList *plist = qemu_find_opts("boot-opts");
|
||||
QemuOpts *opts = QTAILQ_FIRST(&plist->head);
|
||||
boot_splash_filename = qemu_opt_get(opts, "splash");
|
||||
boot_splash_time = qemu_opt_get(opts, "splash-time");
|
||||
|
||||
/* insert splash time if user configurated */
|
||||
if (boot_splash_time) {
|
||||
int64_t bst_val = qemu_opt_get_number(opts, "splash-time", -1);
|
||||
if (current_machine->boot_config.has_splash_time) {
|
||||
int64_t bst_val = current_machine->boot_config.splash_time;
|
||||
uint16_t bst_le16;
|
||||
|
||||
/* validate the input */
|
||||
@ -208,7 +200,8 @@ static void fw_cfg_bootsplash(FWCfgState *s)
|
||||
}
|
||||
|
||||
/* insert splash file if user configurated */
|
||||
if (boot_splash_filename) {
|
||||
if (current_machine->boot_config.has_splash) {
|
||||
const char *boot_splash_filename = current_machine->boot_config.splash;
|
||||
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, boot_splash_filename);
|
||||
if (filename == NULL) {
|
||||
error_report("failed to find file '%s'", boot_splash_filename);
|
||||
@ -238,17 +231,11 @@ static void fw_cfg_bootsplash(FWCfgState *s)
|
||||
|
||||
static void fw_cfg_reboot(FWCfgState *s)
|
||||
{
|
||||
const char *reboot_timeout = NULL;
|
||||
uint64_t rt_val = -1;
|
||||
uint32_t rt_le32;
|
||||
|
||||
/* get user configuration */
|
||||
QemuOptsList *plist = qemu_find_opts("boot-opts");
|
||||
QemuOpts *opts = QTAILQ_FIRST(&plist->head);
|
||||
reboot_timeout = qemu_opt_get(opts, "reboot-timeout");
|
||||
|
||||
if (reboot_timeout) {
|
||||
rt_val = qemu_opt_get_number(opts, "reboot-timeout", -1);
|
||||
if (current_machine->boot_config.has_reboot_timeout) {
|
||||
rt_val = current_machine->boot_config.reboot_timeout;
|
||||
|
||||
/* validate the input */
|
||||
if (rt_val > 0xffff && rt_val != (uint64_t)-1) {
|
||||
@ -1133,7 +1120,7 @@ static void fw_cfg_common_realize(DeviceState *dev, Error **errp)
|
||||
fw_cfg_add_bytes(s, FW_CFG_SIGNATURE, (char *)"QEMU", 4);
|
||||
fw_cfg_add_bytes(s, FW_CFG_UUID, &qemu_uuid, 16);
|
||||
fw_cfg_add_i16(s, FW_CFG_NOGRAPHIC, (uint16_t)!machine->enable_graphics);
|
||||
fw_cfg_add_i16(s, FW_CFG_BOOT_MENU, (uint16_t)boot_menu);
|
||||
fw_cfg_add_i16(s, FW_CFG_BOOT_MENU, (uint16_t)(machine->boot_config.has_menu && machine->boot_config.menu));
|
||||
fw_cfg_bootsplash(s);
|
||||
fw_cfg_reboot(s);
|
||||
|
||||
|
@ -111,7 +111,7 @@ static void ppc_core99_init(MachineState *machine)
|
||||
const char *kernel_filename = machine->kernel_filename;
|
||||
const char *kernel_cmdline = machine->kernel_cmdline;
|
||||
const char *initrd_filename = machine->initrd_filename;
|
||||
const char *boot_device = machine->boot_order;
|
||||
const char *boot_device = machine->boot_config.order;
|
||||
Core99MachineState *core99_machine = CORE99_MACHINE(machine);
|
||||
PowerPCCPU *cpu = NULL;
|
||||
CPUPPCState *env = NULL;
|
||||
|
@ -82,7 +82,7 @@ static void ppc_heathrow_init(MachineState *machine)
|
||||
{
|
||||
ram_addr_t ram_size = machine->ram_size;
|
||||
const char *bios_name = machine->firmware ?: PROM_FILENAME;
|
||||
const char *boot_device = machine->boot_order;
|
||||
const char *boot_device = machine->boot_config.order;
|
||||
PowerPCCPU *cpu = NULL;
|
||||
CPUPPCState *env = NULL;
|
||||
char *filename;
|
||||
|
@ -381,7 +381,7 @@ static void ibm_40p_init(MachineState *machine)
|
||||
}
|
||||
boot_device = 'm';
|
||||
} else {
|
||||
boot_device = machine->boot_order[0];
|
||||
boot_device = machine->boot_config.order[0];
|
||||
}
|
||||
|
||||
fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)machine->smp.max_cpus);
|
||||
|
@ -1044,8 +1044,8 @@ static void spapr_dt_chosen(SpaprMachineState *spapr, void *fdt, bool reset)
|
||||
_FDT(fdt_setprop(fdt, chosen, "qemu,boot-kernel-le", NULL, 0));
|
||||
}
|
||||
}
|
||||
if (boot_menu) {
|
||||
_FDT((fdt_setprop_cell(fdt, chosen, "qemu,boot-menu", boot_menu)));
|
||||
if (machine->boot_config.has_menu && machine->boot_config.menu) {
|
||||
_FDT((fdt_setprop_cell(fdt, chosen, "qemu,boot-menu", true)));
|
||||
}
|
||||
_FDT(fdt_setprop_cell(fdt, chosen, "qemu,graphic-width", graphic_width));
|
||||
_FDT(fdt_setprop_cell(fdt, chosen, "qemu,graphic-height", graphic_height));
|
||||
|
@ -290,13 +290,10 @@ static Property s390_ipl_properties[] = {
|
||||
|
||||
static void s390_ipl_set_boot_menu(S390IPLState *ipl)
|
||||
{
|
||||
QemuOptsList *plist = qemu_find_opts("boot-opts");
|
||||
QemuOpts *opts = QTAILQ_FIRST(&plist->head);
|
||||
const char *tmp;
|
||||
unsigned long splash_time = 0;
|
||||
|
||||
if (!get_boot_device(0)) {
|
||||
if (boot_menu) {
|
||||
if (current_machine->boot_config.has_menu && current_machine->boot_config.menu) {
|
||||
error_report("boot menu requires a bootindex to be specified for "
|
||||
"the IPL device");
|
||||
}
|
||||
@ -306,7 +303,7 @@ static void s390_ipl_set_boot_menu(S390IPLState *ipl)
|
||||
switch (ipl->iplb.pbt) {
|
||||
case S390_IPL_TYPE_CCW:
|
||||
/* In the absence of -boot menu, use zipl parameters */
|
||||
if (!qemu_opt_get(opts, "menu")) {
|
||||
if (!current_machine->boot_config.has_menu) {
|
||||
ipl->qipl.qipl_flags |= QIPL_FLAG_BM_OPTS_ZIPL;
|
||||
return;
|
||||
}
|
||||
@ -314,26 +311,21 @@ static void s390_ipl_set_boot_menu(S390IPLState *ipl)
|
||||
case S390_IPL_TYPE_QEMU_SCSI:
|
||||
break;
|
||||
default:
|
||||
if (boot_menu) {
|
||||
if (current_machine->boot_config.has_menu && current_machine->boot_config.menu) {
|
||||
error_report("boot menu is not supported for this device type");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!boot_menu) {
|
||||
if (!current_machine->boot_config.has_menu || !current_machine->boot_config.menu) {
|
||||
return;
|
||||
}
|
||||
|
||||
ipl->qipl.qipl_flags |= QIPL_FLAG_BM_OPTS_CMD;
|
||||
|
||||
tmp = qemu_opt_get(opts, "splash-time");
|
||||
|
||||
if (tmp && qemu_strtoul(tmp, NULL, 10, &splash_time)) {
|
||||
error_report("splash-time is invalid, forcing it to 0");
|
||||
ipl->qipl.boot_menu_timeout = 0;
|
||||
return;
|
||||
if (current_machine->boot_config.has_splash_time) {
|
||||
splash_time = current_machine->boot_config.splash_time;
|
||||
}
|
||||
|
||||
if (splash_time > 0xffffffff) {
|
||||
error_report("splash-time is too large, forcing it to max value");
|
||||
ipl->qipl.boot_menu_timeout = 0xffffffff;
|
||||
|
@ -1050,7 +1050,7 @@ static void sun4m_hw_init(MachineState *machine)
|
||||
machine->ram_size, &initrd_size);
|
||||
|
||||
nvram_init(nvram, (uint8_t *)&nd->macaddr, machine->kernel_cmdline,
|
||||
machine->boot_order, machine->ram_size, kernel_size,
|
||||
machine->boot_config.order, machine->ram_size, kernel_size,
|
||||
graphic_width, graphic_height, graphic_depth,
|
||||
hwdef->nvram_machine_id, "Sun4m");
|
||||
|
||||
@ -1091,7 +1091,7 @@ static void sun4m_hw_init(MachineState *machine)
|
||||
}
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, INITRD_LOAD_ADDR);
|
||||
fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
|
||||
fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, machine->boot_order[0]);
|
||||
fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, machine->boot_config.order[0]);
|
||||
qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
|
||||
}
|
||||
|
||||
|
@ -695,7 +695,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
|
||||
&kernel_addr, &kernel_entry);
|
||||
|
||||
sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", machine->ram_size,
|
||||
machine->boot_order,
|
||||
machine->boot_config.order,
|
||||
kernel_addr, kernel_size,
|
||||
machine->kernel_cmdline,
|
||||
initrd_addr, initrd_size,
|
||||
@ -727,7 +727,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
|
||||
}
|
||||
fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr);
|
||||
fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
|
||||
fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, machine->boot_order[0]);
|
||||
fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, machine->boot_config.order[0]);
|
||||
|
||||
fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_WIDTH, graphic_width);
|
||||
fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_HEIGHT, graphic_height);
|
||||
|
@ -26,6 +26,7 @@ OBJECT_DECLARE_TYPE(MachineState, MachineClass, MACHINE)
|
||||
extern MachineState *current_machine;
|
||||
|
||||
void machine_run_board_init(MachineState *machine);
|
||||
void machine_boot_parse(MachineState *ms, QemuOpts *opts, Error **errp);
|
||||
bool machine_usb(MachineState *machine);
|
||||
int machine_phandle_start(MachineState *machine);
|
||||
bool machine_dump_guest_core(MachineState *machine);
|
||||
@ -350,8 +351,7 @@ struct MachineState {
|
||||
ram_addr_t ram_size;
|
||||
ram_addr_t maxram_size;
|
||||
uint64_t ram_slots;
|
||||
const char *boot_order;
|
||||
const char *boot_once;
|
||||
BootConfiguration boot_config;
|
||||
char *kernel_filename;
|
||||
char *kernel_cmdline;
|
||||
char *initrd_filename;
|
||||
|
@ -46,8 +46,6 @@ extern int alt_grab;
|
||||
extern int ctrl_grab;
|
||||
extern int graphic_rotate;
|
||||
extern int old_param;
|
||||
extern int boot_menu;
|
||||
extern bool boot_strict;
|
||||
extern uint8_t *boot_splash_filedata;
|
||||
extern bool enable_mlock;
|
||||
extern bool enable_cpu_pm;
|
||||
|
@ -1395,6 +1395,36 @@
|
||||
'data': { 'device': 'str', 'msg': 'str' },
|
||||
'features': ['deprecated'] }
|
||||
|
||||
##
|
||||
# @BootConfiguration:
|
||||
#
|
||||
# Schema for virtual machine boot configuration.
|
||||
#
|
||||
# @order: Boot order (a=floppy, c=hard disk, d=CD-ROM, n=network)
|
||||
#
|
||||
# @once: Boot order to apply on first boot
|
||||
#
|
||||
# @menu: Whether to show a boot menu
|
||||
#
|
||||
# @splash: The name of the file to be passed to the firmware as logo picture, if @menu is true.
|
||||
#
|
||||
# @splash-time: How long to show the logo picture, in milliseconds
|
||||
#
|
||||
# @reboot-timeout: Timeout before guest reboots after boot fails
|
||||
#
|
||||
# @strict: Whether to attempt booting from devices not included in the boot order
|
||||
#
|
||||
# Since: 7.1
|
||||
##
|
||||
{ 'struct': 'BootConfiguration', 'data': {
|
||||
'*order': 'str',
|
||||
'*once': 'str',
|
||||
'*menu': 'bool',
|
||||
'*splash': 'str',
|
||||
'*splash-time': 'int',
|
||||
'*reboot-timeout': 'int',
|
||||
'*strict': 'bool' } }
|
||||
|
||||
##
|
||||
# @SMPConfiguration:
|
||||
#
|
||||
|
@ -268,7 +268,8 @@ char *get_boot_devices_list(size_t *size)
|
||||
|
||||
*size = total;
|
||||
|
||||
if (boot_strict && *size > 0) {
|
||||
if (current_machine->boot_config.has_strict &&
|
||||
current_machine->boot_config.strict && *size > 0) {
|
||||
list[total-1] = '\n';
|
||||
list = g_realloc(list, total + 5);
|
||||
memcpy(&list[total], "HALT", 5);
|
||||
|
@ -54,8 +54,6 @@ int alt_grab;
|
||||
int ctrl_grab;
|
||||
unsigned int nb_prom_envs;
|
||||
const char *prom_envs[MAX_PROM_ENVS];
|
||||
int boot_menu;
|
||||
bool boot_strict;
|
||||
uint8_t *boot_splash_filedata;
|
||||
int only_migratable; /* turn it off unless user states otherwise */
|
||||
int icount_align_option;
|
||||
|
25
softmmu/vl.c
25
softmmu/vl.c
@ -1884,9 +1884,6 @@ static bool object_create_early(const char *type)
|
||||
|
||||
static void qemu_apply_machine_options(QDict *qdict)
|
||||
{
|
||||
MachineClass *machine_class = MACHINE_GET_CLASS(current_machine);
|
||||
const char *boot_order = NULL;
|
||||
const char *boot_once = NULL;
|
||||
QemuOpts *opts;
|
||||
|
||||
object_set_properties_from_keyval(OBJECT(current_machine), qdict, false, &error_fatal);
|
||||
@ -1895,27 +1892,7 @@ static void qemu_apply_machine_options(QDict *qdict)
|
||||
current_machine->ram_slots = ram_slots;
|
||||
|
||||
opts = qemu_opts_find(qemu_find_opts("boot-opts"), NULL);
|
||||
if (opts) {
|
||||
boot_order = qemu_opt_get(opts, "order");
|
||||
if (boot_order) {
|
||||
validate_bootdevices(boot_order, &error_fatal);
|
||||
}
|
||||
|
||||
boot_once = qemu_opt_get(opts, "once");
|
||||
if (boot_once) {
|
||||
validate_bootdevices(boot_once, &error_fatal);
|
||||
}
|
||||
|
||||
boot_menu = qemu_opt_get_bool(opts, "menu", boot_menu);
|
||||
boot_strict = qemu_opt_get_bool(opts, "strict", false);
|
||||
}
|
||||
|
||||
if (!boot_order) {
|
||||
boot_order = machine_class->default_boot_order;
|
||||
}
|
||||
|
||||
current_machine->boot_order = boot_order;
|
||||
current_machine->boot_once = boot_once;
|
||||
machine_boot_parse(current_machine, opts, &error_fatal);
|
||||
|
||||
if (semihosting_enabled() && !semihosting_get_argc()) {
|
||||
/* fall back to the -kernel/-append */
|
||||
|
Loading…
Reference in New Issue
Block a user