提交 605c690b 编写于 作者: P Peter Maydell

Merge remote-tracking branch 'remotes/kraxel/tags/pull-bootindex-20141015-1' into staging

allow changing bootorder via monitor at runtime,
by making bootindex a writable qom property.

* remotes/kraxel/tags/pull-bootindex-20141015-1: (34 commits)
  bootindex: change fprintf to error_report
  bootindex: delete bootindex when device is removed
  bootindex: move calling add_boot_device_patch to bootindex setter function
  ide: add calling add_boot_device_patch in bootindex setter function
  nvma: ide: add bootindex to qom property
  usb-storage: add bootindex to qom property
  virtio-blk: alias bootindex property explicitly for virt-blk-pci/ccw/s390
  block: remove bootindex property from qdev to qom
  virtio-blk: add bootindex to qom property
  ide: add bootindex to qom property
  scsi: add bootindex to qom property
  isa-fdc: remove bootindexA/B property from qdev to qom
  redirect: remove bootindex property from qdev to qom
  vfio: remove bootindex property from qdev to qom
  pci-assign: remove bootindex property from qdev to qom
  host-libusb: remove bootindex property from qdev to qom
  virtio-net: alias bootindex property explicitly for virt-net-pci/ccw/s390
  net: remove bootindex property from qdev to qom
  usb-net: add bootindex to qom property
  vmxnet3: add bootindex to qom property
  ...
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
......@@ -127,7 +127,7 @@ endif #CONFIG_BSD_USER
# System emulator target
ifdef CONFIG_SOFTMMU
obj-y += arch_init.o cpus.o monitor.o gdbstub.o balloon.o ioport.o numa.o
obj-y += qtest.o
obj-y += qtest.o bootdevice.o
obj-y += hw/
obj-$(CONFIG_FDT) += device_tree.o
obj-$(CONFIG_KVM) += kvm-all.o
......
/*
* QEMU Boot Device Implement
*
* Copyright (c) 2014 HUAWEI TECHNOLOGIES CO.,LTD.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "sysemu/sysemu.h"
#include "qapi/visitor.h"
#include "qemu/error-report.h"
typedef struct FWBootEntry FWBootEntry;
struct FWBootEntry {
QTAILQ_ENTRY(FWBootEntry) link;
int32_t bootindex;
DeviceState *dev;
char *suffix;
};
static QTAILQ_HEAD(, FWBootEntry) fw_boot_order =
QTAILQ_HEAD_INITIALIZER(fw_boot_order);
void check_boot_index(int32_t bootindex, Error **errp)
{
FWBootEntry *i;
if (bootindex >= 0) {
QTAILQ_FOREACH(i, &fw_boot_order, link) {
if (i->bootindex == bootindex) {
error_setg(errp, "The bootindex %d has already been used",
bootindex);
return;
}
}
}
}
void del_boot_device_path(DeviceState *dev, const char *suffix)
{
FWBootEntry *i;
if (dev == NULL) {
return;
}
QTAILQ_FOREACH(i, &fw_boot_order, link) {
if ((!suffix || !g_strcmp0(i->suffix, suffix)) &&
i->dev == dev) {
QTAILQ_REMOVE(&fw_boot_order, i, link);
g_free(i->suffix);
g_free(i);
break;
}
}
}
void add_boot_device_path(int32_t bootindex, DeviceState *dev,
const char *suffix)
{
FWBootEntry *node, *i;
if (bootindex < 0) {
del_boot_device_path(dev, suffix);
return;
}
assert(dev != NULL || suffix != NULL);
del_boot_device_path(dev, suffix);
node = g_malloc0(sizeof(FWBootEntry));
node->bootindex = bootindex;
node->suffix = g_strdup(suffix);
node->dev = dev;
QTAILQ_FOREACH(i, &fw_boot_order, link) {
if (i->bootindex == bootindex) {
error_report("Two devices with same boot index %d", bootindex);
exit(1);
} else if (i->bootindex < bootindex) {
continue;
}
QTAILQ_INSERT_BEFORE(i, node, link);
return;
}
QTAILQ_INSERT_TAIL(&fw_boot_order, node, link);
}
DeviceState *get_boot_device(uint32_t position)
{
uint32_t counter = 0;
FWBootEntry *i = NULL;
DeviceState *res = NULL;
if (!QTAILQ_EMPTY(&fw_boot_order)) {
QTAILQ_FOREACH(i, &fw_boot_order, link) {
if (counter == position) {
res = i->dev;
break;
}
counter++;
}
}
return res;
}
/*
* This function returns null terminated string that consist of new line
* separated device paths.
*
* memory pointed by "size" is assigned total length of the array in bytes
*
*/
char *get_boot_devices_list(size_t *size, bool ignore_suffixes)
{
FWBootEntry *i;
size_t total = 0;
char *list = NULL;
QTAILQ_FOREACH(i, &fw_boot_order, link) {
char *devpath = NULL, *bootpath;
size_t len;
if (i->dev) {
devpath = qdev_get_fw_dev_path(i->dev);
assert(devpath);
}
if (i->suffix && !ignore_suffixes && devpath) {
size_t bootpathlen = strlen(devpath) + strlen(i->suffix) + 1;
bootpath = g_malloc(bootpathlen);
snprintf(bootpath, bootpathlen, "%s%s", devpath, i->suffix);
g_free(devpath);
} else if (devpath) {
bootpath = devpath;
} else if (!ignore_suffixes) {
assert(i->suffix);
bootpath = g_strdup(i->suffix);
} else {
bootpath = g_strdup("");
}
if (total) {
list[total-1] = '\n';
}
len = strlen(bootpath) + 1;
list = g_realloc(list, total + len);
memcpy(&list[total], bootpath, len);
total += len;
g_free(bootpath);
}
*size = total;
if (boot_strict && *size > 0) {
list[total-1] = '\n';
list = g_realloc(list, total + 5);
memcpy(&list[total], "HALT", 5);
*size = total + 5;
}
return list;
}
typedef struct {
int32_t *bootindex;
const char *suffix;
DeviceState *dev;
} BootIndexProperty;
static void device_get_bootindex(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
BootIndexProperty *prop = opaque;
visit_type_int32(v, prop->bootindex, name, errp);
}
static void device_set_bootindex(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
BootIndexProperty *prop = opaque;
int32_t boot_index;
Error *local_err = NULL;
visit_type_int32(v, &boot_index, name, &local_err);
if (local_err) {
goto out;
}
/* check whether bootindex is present in fw_boot_order list */
check_boot_index(boot_index, &local_err);
if (local_err) {
goto out;
}
/* change bootindex to a new one */
*prop->bootindex = boot_index;
add_boot_device_path(*prop->bootindex, prop->dev, prop->suffix);
out:
if (local_err) {
error_propagate(errp, local_err);
}
}
static void property_release_bootindex(Object *obj, const char *name,
void *opaque)
{
BootIndexProperty *prop = opaque;
del_boot_device_path(prop->dev, prop->suffix);
g_free(prop);
}
void device_add_bootindex_property(Object *obj, int32_t *bootindex,
const char *name, const char *suffix,
DeviceState *dev, Error **errp)
{
Error *local_err = NULL;
BootIndexProperty *prop = g_malloc0(sizeof(*prop));
prop->bootindex = bootindex;
prop->suffix = suffix;
prop->dev = dev;
object_property_add(obj, name, "int32",
device_get_bootindex,
device_set_bootindex,
property_release_bootindex,
prop, &local_err);
if (local_err) {
error_propagate(errp, local_err);
g_free(prop);
return;
}
/* initialize devices' bootindex property to -1 */
object_property_set_int(obj, -1, name, NULL);
}
......@@ -2216,9 +2216,6 @@ static void isabus_fdc_realize(DeviceState *dev, Error **errp)
error_propagate(errp, err);
return;
}
add_boot_device_path(isa->bootindexA, dev, "/floppy@0");
add_boot_device_path(isa->bootindexB, dev, "/floppy@1");
}
static void sysbus_fdc_initfn(Object *obj)
......@@ -2291,8 +2288,6 @@ static Property isa_fdc_properties[] = {
DEFINE_PROP_UINT32("dma", FDCtrlISABus, dma, 2),
DEFINE_PROP_DRIVE("driveA", FDCtrlISABus, state.drives[0].bs),
DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.drives[1].bs),
DEFINE_PROP_INT32("bootindexA", FDCtrlISABus, bootindexA, -1),
DEFINE_PROP_INT32("bootindexB", FDCtrlISABus, bootindexB, -1),
DEFINE_PROP_BIT("check_media_rate", FDCtrlISABus, state.check_media_rate,
0, true),
DEFINE_PROP_END_OF_LIST(),
......@@ -2310,11 +2305,24 @@ static void isabus_fdc_class_init(ObjectClass *klass, void *data)
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
static void isabus_fdc_instance_init(Object *obj)
{
FDCtrlISABus *isa = ISA_FDC(obj);
device_add_bootindex_property(obj, &isa->bootindexA,
"bootindexA", "/floppy@0",
DEVICE(obj), NULL);
device_add_bootindex_property(obj, &isa->bootindexB,
"bootindexB", "/floppy@1",
DEVICE(obj), NULL);
}
static const TypeInfo isa_fdc_info = {
.name = TYPE_ISA_FDC,
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(FDCtrlISABus),
.class_init = isabus_fdc_class_init,
.instance_init = isabus_fdc_instance_init,
};
static const VMStateDescription vmstate_sysbus_fdc ={
......
......@@ -24,6 +24,8 @@
#include <hw/hw.h>
#include <hw/pci/msix.h>
#include <hw/pci/pci.h>
#include "sysemu/sysemu.h"
#include "qapi/visitor.h"
#include "nvme.h"
......@@ -871,11 +873,53 @@ static void nvme_class_init(ObjectClass *oc, void *data)
dc->vmsd = &nvme_vmstate;
}
static void nvme_get_bootindex(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
NvmeCtrl *s = NVME(obj);
visit_type_int32(v, &s->conf.bootindex, name, errp);
}
static void nvme_set_bootindex(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
NvmeCtrl *s = NVME(obj);
int32_t boot_index;
Error *local_err = NULL;
visit_type_int32(v, &boot_index, name, &local_err);
if (local_err) {
goto out;
}
/* check whether bootindex is present in fw_boot_order list */
check_boot_index(boot_index, &local_err);
if (local_err) {
goto out;
}
/* change bootindex to a new one */
s->conf.bootindex = boot_index;
out:
if (local_err) {
error_propagate(errp, local_err);
}
}
static void nvme_instance_init(Object *obj)
{
object_property_add(obj, "bootindex", "int32",
nvme_get_bootindex,
nvme_set_bootindex, NULL, NULL, NULL);
object_property_set_int(obj, -1, "bootindex", NULL);
}
static const TypeInfo nvme_info = {
.name = "nvme",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(NvmeCtrl),
.class_init = nvme_class_init,
.instance_init = nvme_instance_init,
};
static void nvme_register_types(void)
......
......@@ -768,8 +768,6 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
bdrv_set_guest_block_size(s->bs, s->conf->logical_block_size);
bdrv_iostatus_enable(s->bs);
add_boot_device_path(s->conf->bootindex, dev, "/disk@0,0");
}
static void virtio_blk_device_unrealize(DeviceState *dev, Error **errp)
......@@ -794,6 +792,9 @@ static void virtio_blk_instance_init(Object *obj)
(Object **)&s->blk.iothread,
qdev_prop_allow_set_link_before_realize,
OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL);
device_add_bootindex_property(obj, &s->blk.conf.bootindex,
"bootindex", "/disk@0,0",
DEVICE(obj), NULL);
}
static Property virtio_blk_properties[] = {
......
......@@ -1825,8 +1825,6 @@ static int assigned_initfn(struct PCIDevice *pci_dev)
assigned_dev_load_option_rom(dev);
add_boot_device_path(dev->bootindex, &pci_dev->qdev, NULL);
return 0;
assigned_out:
......@@ -1850,13 +1848,22 @@ static void assigned_exitfn(struct PCIDevice *pci_dev)
free_assigned_device(dev);
}
static void assigned_dev_instance_init(Object *obj)
{
PCIDevice *pci_dev = PCI_DEVICE(obj);
AssignedDevice *d = DO_UPCAST(AssignedDevice, dev, PCI_DEVICE(obj));
device_add_bootindex_property(obj, &d->bootindex,
"bootindex", NULL,
&pci_dev->qdev, NULL);
}
static Property assigned_dev_properties[] = {
DEFINE_PROP_PCI_HOST_DEVADDR("host", AssignedDevice, host),
DEFINE_PROP_BIT("prefer_msi", AssignedDevice, features,
ASSIGNED_DEVICE_PREFER_MSI_BIT, false),
DEFINE_PROP_BIT("share_intx", AssignedDevice, features,
ASSIGNED_DEVICE_SHARE_INTX_BIT, true),
DEFINE_PROP_INT32("bootindex", AssignedDevice, bootindex, -1),
DEFINE_PROP_STRING("configfd", AssignedDevice, configfd_name),
DEFINE_PROP_END_OF_LIST(),
};
......@@ -1882,6 +1889,7 @@ static const TypeInfo assign_info = {
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(AssignedDevice),
.class_init = assign_class_init,
.instance_init = assigned_dev_instance_init,
};
static void assign_register_types(void)
......
......@@ -23,6 +23,7 @@
#include "sysemu/blockdev.h"
#include "hw/block/block.h"
#include "sysemu/sysemu.h"
#include "qapi/visitor.h"
/* --------------------------------- */
......@@ -191,6 +192,51 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind)
return 0;
}
static void ide_dev_get_bootindex(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
IDEDevice *d = IDE_DEVICE(obj);
visit_type_int32(v, &d->conf.bootindex, name, errp);
}
static void ide_dev_set_bootindex(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
IDEDevice *d = IDE_DEVICE(obj);
int32_t boot_index;
Error *local_err = NULL;
visit_type_int32(v, &boot_index, name, &local_err);
if (local_err) {
goto out;
}
/* check whether bootindex is present in fw_boot_order list */
check_boot_index(boot_index, &local_err);
if (local_err) {
goto out;
}
/* change bootindex to a new one */
d->conf.bootindex = boot_index;
if (d->unit != -1) {
add_boot_device_path(d->conf.bootindex, &d->qdev,
d->unit ? "/disk@1" : "/disk@0");
}
out:
if (local_err) {
error_propagate(errp, local_err);
}
}
static void ide_dev_instance_init(Object *obj)
{
object_property_add(obj, "bootindex", "int32",
ide_dev_get_bootindex,
ide_dev_set_bootindex, NULL, NULL, NULL);
object_property_set_int(obj, -1, "bootindex", NULL);
}
static int ide_hd_initfn(IDEDevice *dev)
{
return ide_dev_initfn(dev, IDE_HD);
......@@ -300,6 +346,7 @@ static const TypeInfo ide_device_type_info = {
.abstract = true,
.class_size = sizeof(IDEDeviceClass),
.class_init = ide_device_class_init,
.instance_init = ide_dev_instance_init,
};
static void ide_register_types(void)
......
......@@ -4296,7 +4296,6 @@ static int vfio_initfn(PCIDevice *pdev)
}
}
add_boot_device_path(vdev->bootindex, &pdev->qdev, NULL);
vfio_register_err_notifier(vdev);
return 0;
......@@ -4365,13 +4364,22 @@ post_reset:
vfio_pci_post_reset(vdev);
}
static void vfio_instance_init(Object *obj)
{
PCIDevice *pci_dev = PCI_DEVICE(obj);
VFIODevice *vdev = DO_UPCAST(VFIODevice, pdev, PCI_DEVICE(obj));
device_add_bootindex_property(obj, &vdev->bootindex,
"bootindex", NULL,
&pci_dev->qdev, NULL);
}
static Property vfio_pci_dev_properties[] = {
DEFINE_PROP_PCI_HOST_DEVADDR("host", VFIODevice, host),
DEFINE_PROP_UINT32("x-intx-mmap-timeout-ms", VFIODevice,
intx.mmap_timeout, 1100),
DEFINE_PROP_BIT("x-vga", VFIODevice, features,
VFIO_FEATURE_ENABLE_VGA_BIT, false),
DEFINE_PROP_INT32("bootindex", VFIODevice, bootindex, -1),
/*
* TODO - support passed fds... is this necessary?
* DEFINE_PROP_STRING("vfiofd", VFIODevice, vfiofd_name),
......@@ -4407,6 +4415,7 @@ static const TypeInfo vfio_pci_dev_info = {
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(VFIODevice),
.class_init = vfio_pci_dev_class_init,
.instance_init = vfio_instance_init,
};
static void register_vfio_pci_dev_type(void)
......
......@@ -1569,8 +1569,6 @@ static int pci_e1000_init(PCIDevice *pci_dev)
qemu_format_nic_info_str(qemu_get_queue(d->nic), macaddr);
add_boot_device_path(d->conf.bootindex, dev, "/ethernet-phy@0");
d->autoneg_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, e1000_autoneg_timer, d);
d->mit_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, e1000_mit_timer, d);
......@@ -1621,10 +1619,19 @@ static void e1000_class_init(ObjectClass *klass, void *data)
dc->props = e1000_properties;
}
static void e1000_instance_init(Object *obj)
{
E1000State *n = E1000(obj);
device_add_bootindex_property(obj, &n->conf.bootindex,
"bootindex", "/ethernet-phy@0",
DEVICE(n), NULL);
}
static const TypeInfo e1000_base_info = {
.name = TYPE_E1000_BASE,
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(E1000State),
.instance_init = e1000_instance_init,
.class_size = sizeof(E1000BaseClass),
.abstract = true,
};
......@@ -1668,6 +1675,7 @@ static void e1000_register_types(void)
type_info.parent = TYPE_E1000_BASE;
type_info.class_data = (void *)info;
type_info.class_init = e1000_class_init;
type_info.instance_init = e1000_instance_init;
type_register(&type_info);
}
......
......@@ -1901,11 +1901,17 @@ static int e100_nic_init(PCIDevice *pci_dev)
s->vmstate->name = qemu_get_queue(s->nic)->model;
vmstate_register(&pci_dev->qdev, -1, s->vmstate, s);
add_boot_device_path(s->conf.bootindex, &pci_dev->qdev, "/ethernet-phy@0");
return 0;
}
static void eepro100_instance_init(Object *obj)
{
EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, PCI_DEVICE(obj));
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", "/ethernet-phy@0",
DEVICE(s), NULL);
}
static E100PCIDeviceInfo e100_devices[] = {
{
.name = "i82550",
......@@ -2104,7 +2110,8 @@ static void eepro100_register_types(void)
type_info.parent = TYPE_PCI_DEVICE;
type_info.class_init = eepro100_class_init;
type_info.instance_size = sizeof(EEPRO100State);
type_info.instance_init = eepro100_instance_init;
type_register(&type_info);
}
}
......
......@@ -42,6 +42,7 @@
#include "hw/sparc/sun4m.h"
#include "pcnet.h"
#include "trace.h"
#include "sysemu/sysemu.h"
#define TYPE_LANCE "lance"
#define SYSBUS_PCNET(obj) \
......@@ -143,6 +144,16 @@ static void lance_reset(DeviceState *dev)
pcnet_h_reset(&d->state);
}
static void lance_instance_init(Object *obj)
{
SysBusPCNetState *d = SYSBUS_PCNET(obj);
PCNetState *s = &d->state;
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", "/ethernet-phy@0",
DEVICE(obj), NULL);
}
static Property lance_properties[] = {
DEFINE_PROP_PTR("dma", SysBusPCNetState, state.dma_opaque),
DEFINE_NIC_PROPERTIES(SysBusPCNetState, state.conf),
......@@ -169,6 +180,7 @@ static const TypeInfo lance_info = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SysBusPCNetState),
.class_init = lance_class_init,
.instance_init = lance_instance_init,
};
static void lance_register_types(void)
......
......@@ -28,6 +28,7 @@
#include "net/net.h"
#include "ne2000.h"
#include "exec/address-spaces.h"
#include "qapi/visitor.h"
#define TYPE_ISA_NE2000 "ne2k_isa"
#define ISA_NE2000(obj) OBJECT_CHECK(ISANE2000State, (obj), TYPE_ISA_NE2000)
......@@ -101,11 +102,54 @@ static void isa_ne2000_class_initfn(ObjectClass *klass, void *data)
set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
}
static void isa_ne2000_get_bootindex(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
ISANE2000State *isa = ISA_NE2000(obj);
NE2000State *s = &isa->ne2000;
visit_type_int32(v, &s->c.bootindex, name, errp);
}
static void isa_ne2000_set_bootindex(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
ISANE2000State *isa = ISA_NE2000(obj);
NE2000State *s = &isa->ne2000;
int32_t boot_index;
Error *local_err = NULL;
visit_type_int32(v, &boot_index, name, &local_err);
if (local_err) {
goto out;
}
/* check whether bootindex is present in fw_boot_order list */
check_boot_index(boot_index, &local_err);
if (local_err) {
goto out;
}
/* change bootindex to a new one */
s->c.bootindex = boot_index;
out:
if (local_err) {
error_propagate(errp, local_err);
}
}
static void isa_ne2000_instance_init(Object *obj)
{
object_property_add(obj, "bootindex", "int32",
isa_ne2000_get_bootindex,
isa_ne2000_set_bootindex, NULL, NULL, NULL);
object_property_set_int(obj, -1, "bootindex", NULL);
}
static const TypeInfo ne2000_isa_info = {
.name = TYPE_ISA_NE2000,
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(ISANE2000State),
.class_init = isa_ne2000_class_initfn,
.instance_init = isa_ne2000_instance_init,
};
static void ne2000_isa_register_types(void)
......
......@@ -738,8 +738,6 @@ static int pci_ne2000_init(PCIDevice *pci_dev)
object_get_typename(OBJECT(pci_dev)), pci_dev->qdev.id, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a);
add_boot_device_path(s->c.bootindex, &pci_dev->qdev, "/ethernet-phy@0");
return 0;
}
......@@ -752,6 +750,17 @@ static void pci_ne2000_exit(PCIDevice *pci_dev)
qemu_free_irq(s->irq);
}
static void ne2000_instance_init(Object *obj)
{
PCIDevice *pci_dev = PCI_DEVICE(obj);
PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
NE2000State *s = &d->ne2000;
device_add_bootindex_property(obj, &s->c.bootindex,
"bootindex", "/ethernet-phy@0",
&pci_dev->qdev, NULL);
}
static Property ne2000_properties[] = {
DEFINE_NIC_PROPERTIES(PCINE2000State, ne2000.c),
DEFINE_PROP_END_OF_LIST(),
......@@ -778,6 +787,7 @@ static const TypeInfo ne2000_info = {
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCINE2000State),
.class_init = ne2000_class_init,
.instance_init = ne2000_instance_init,
};
static void ne2000_register_types(void)
......
......@@ -32,6 +32,7 @@
#include "hw/loader.h"
#include "qemu/timer.h"
#include "sysemu/dma.h"
#include "sysemu/sysemu.h"
#include "pcnet.h"
......@@ -344,6 +345,16 @@ static void pci_reset(DeviceState *dev)
pcnet_h_reset(&d->state);
}
static void pcnet_instance_init(Object *obj)
{
PCIPCNetState *d = PCI_PCNET(obj);
PCNetState *s = &d->state;
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", "/ethernet-phy@0",
DEVICE(obj), NULL);
}
static Property pcnet_properties[] = {
DEFINE_NIC_PROPERTIES(PCIPCNetState, state.conf),
DEFINE_PROP_END_OF_LIST(),
......@@ -372,6 +383,7 @@ static const TypeInfo pcnet_info = {
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIPCNetState),
.class_init = pcnet_class_init,
.instance_init = pcnet_instance_init,
};
static void pci_pcnet_register_types(void)
......
......@@ -1735,8 +1735,6 @@ int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info)
s->nic = qemu_new_nic(info, &s->conf, object_get_typename(OBJECT(dev)), dev->id, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
add_boot_device_path(s->conf.bootindex, dev, "/ethernet-phy@0");
/* Initialize the PROM */
/*
......
......@@ -66,5 +66,4 @@ void pcnet_set_link_status(NetClientState *nc);
void pcnet_common_cleanup(PCNetState *d);
int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info);
extern const VMStateDescription vmstate_pcnet;
#endif
......@@ -3538,11 +3538,18 @@ static int pci_rtl8139_init(PCIDevice *dev)
s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, rtl8139_timer, s);
rtl8139_set_next_tctr_time(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
add_boot_device_path(s->conf.bootindex, d, "/ethernet-phy@0");
return 0;
}
static void rtl8139_instance_init(Object *obj)
{
RTL8139State *s = RTL8139(obj);
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", "/ethernet-phy@0",
DEVICE(obj), NULL);
}
static Property rtl8139_properties[] = {
DEFINE_NIC_PROPERTIES(RTL8139State, conf),
DEFINE_PROP_END_OF_LIST(),
......@@ -3571,6 +3578,7 @@ static const TypeInfo rtl8139_info = {
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(RTL8139State),
.class_init = rtl8139_class_init,
.instance_init = rtl8139_instance_init,
};
static void rtl8139_register_types(void)
......
......@@ -221,11 +221,18 @@ static int spapr_vlan_init(VIOsPAPRDevice *sdev)
object_get_typename(OBJECT(sdev)), sdev->qdev.id, dev);
qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);
add_boot_device_path(dev->nicconf.bootindex, DEVICE(dev), "");
return 0;
}
static void spapr_vlan_instance_init(Object *obj)
{
VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(obj);
device_add_bootindex_property(obj, &dev->nicconf.bootindex,
"bootindex", "",
DEVICE(dev), NULL);
}
void spapr_vlan_create(VIOsPAPRBus *bus, NICInfo *nd)
{
DeviceState *dev;
......@@ -553,6 +560,7 @@ static const TypeInfo spapr_vlan_info = {
.parent = TYPE_VIO_SPAPR_DEVICE,
.instance_size = sizeof(VIOsPAPRVLANDevice),
.class_init = spapr_vlan_class_init,
.instance_init = spapr_vlan_instance_init,
};
static void spapr_vlan_register_types(void)
......
......@@ -1661,8 +1661,6 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
n->qdev = dev;
register_savevm(dev, "virtio-net", -1, VIRTIO_NET_VM_VERSION,
virtio_net_save, virtio_net_load, n);
add_boot_device_path(n->nic_conf.bootindex, dev, "/ethernet-phy@0");
}
static void virtio_net_device_unrealize(DeviceState *dev, Error **errp)
......@@ -1714,6 +1712,9 @@ static void virtio_net_instance_init(Object *obj)
* Can be overriden with virtio_net_set_config_size.
*/
n->config_size = sizeof(struct virtio_net_config);
device_add_bootindex_property(obj, &n->nic_conf.bootindex,
"bootindex", "/ethernet-phy@0",
DEVICE(n), NULL);
}
static Property virtio_net_properties[] = {
......
......@@ -2172,11 +2172,16 @@ static int vmxnet3_pci_init(PCIDevice *pci_dev)
register_savevm(dev, "vmxnet3-msix", -1, 1,
vmxnet3_msix_save, vmxnet3_msix_load, s);
add_boot_device_path(s->conf.bootindex, dev, "/ethernet-phy@0");
return 0;
}
static void vmxnet3_instance_init(Object *obj)
{
VMXNET3State *s = VMXNET3(obj);
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", "/ethernet-phy@0",
DEVICE(obj), NULL);
}
static void vmxnet3_pci_uninit(PCIDevice *pci_dev)
{
......@@ -2524,6 +2529,7 @@ static const TypeInfo vmxnet3_info = {
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(VMXNET3State),
.class_init = vmxnet3_class_init,
.instance_init = vmxnet3_instance_init,
};
static void vmxnet3_register_types(void)
......
......@@ -402,6 +402,26 @@ static void fw_cfg_add_bytes_read_callback(FWCfgState *s, uint16_t key,
s->entries[arch][key].callback_opaque = callback_opaque;
}
static void *fw_cfg_modify_bytes_read(FWCfgState *s, uint16_t key,
void *data, size_t len)
{
void *ptr;
int arch = !!(key & FW_CFG_ARCH_LOCAL);
key &= FW_CFG_ENTRY_MASK;
assert(key < FW_CFG_MAX_ENTRY && len < UINT32_MAX);
/* return the old data to the function caller, avoid memory leak */
ptr = s->entries[arch][key].data;
s->entries[arch][key].data = data;
s->entries[arch][key].len = len;
s->entries[arch][key].callback_opaque = NULL;
s->entries[arch][key].callback = NULL;
return ptr;
}
void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len)
{
fw_cfg_add_bytes_read_callback(s, key, NULL, NULL, data, len);
......@@ -499,13 +519,42 @@ void fw_cfg_add_file(FWCfgState *s, const char *filename,
fw_cfg_add_file_callback(s, filename, NULL, NULL, data, len);
}
static void fw_cfg_machine_ready(struct Notifier *n, void *data)
void *fw_cfg_modify_file(FWCfgState *s, const char *filename,
void *data, size_t len)
{
int i, index;
assert(s->files);
index = be32_to_cpu(s->files->count);
assert(index < FW_CFG_FILE_SLOTS);
for (i = 0; i < index; i++) {
if (strcmp(filename, s->files->f[i].name) == 0) {
return fw_cfg_modify_bytes_read(s, FW_CFG_FILE_FIRST + i,
data, len);
}
}
/* add new one */
fw_cfg_add_file_callback(s, filename, NULL, NULL, data, len);
return NULL;
}
static void fw_cfg_machine_reset(void *opaque)
{
void *ptr;
size_t len;
FWCfgState *s = container_of(n, FWCfgState, machine_ready);
FWCfgState *s = opaque;
char *bootindex = get_boot_devices_list(&len, false);
fw_cfg_add_file(s, "bootorder", (uint8_t*)bootindex, len);
ptr = fw_cfg_modify_file(s, "bootorder", (uint8_t *)bootindex, len);
g_free(ptr);
}
static void fw_cfg_machine_ready(struct Notifier *n, void *data)
{
FWCfgState *s = container_of(n, FWCfgState, machine_ready);
qemu_register_reset(fw_cfg_machine_reset, s);
}
FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
......
......@@ -162,6 +162,8 @@ static void s390_virtio_net_instance_init(Object *obj)
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_NET);
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
"bootindex", &error_abort);
}
static int s390_virtio_blk_init(VirtIOS390Device *s390_dev)
......@@ -183,6 +185,8 @@ static void s390_virtio_blk_instance_init(Object *obj)
TYPE_VIRTIO_BLK);
object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread",
&error_abort);
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
"bootindex", &error_abort);
}
static int s390_virtio_serial_init(VirtIOS390Device *s390_dev)
......
......@@ -795,6 +795,8 @@ static void virtio_ccw_net_instance_init(Object *obj)
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_NET);
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
"bootindex", &error_abort);
}
static int virtio_ccw_blk_init(VirtioCcwDevice *ccw_dev)
......@@ -817,6 +819,8 @@ static void virtio_ccw_blk_instance_init(Object *obj)
TYPE_VIRTIO_BLK);
object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread",
&error_abort);
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
"bootindex", &error_abort);
}
static int virtio_ccw_serial_init(VirtioCcwDevice *ccw_dev)
......
......@@ -233,7 +233,8 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv,
dev = qdev_create(&bus->qbus, driver);
qdev_prop_set_uint32(dev, "scsi-id", unit);
if (bootindex >= 0) {
qdev_prop_set_int32(dev, "bootindex", bootindex);
object_property_set_int(OBJECT(dev), bootindex, "bootindex",
&error_abort);
}
if (object_property_find(OBJECT(dev), "removable", NULL)) {
qdev_prop_set_bit(dev, "removable", removable);
......@@ -2006,6 +2007,16 @@ static void scsi_device_class_init(ObjectClass *klass, void *data)
k->props = scsi_props;
}
static void scsi_dev_instance_init(Object *obj)
{
DeviceState *dev = DEVICE(obj);
SCSIDevice *s = DO_UPCAST(SCSIDevice, qdev, dev);
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", NULL,
&s->qdev, NULL);
}
static const TypeInfo scsi_device_type_info = {
.name = TYPE_SCSI_DEVICE,
.parent = TYPE_DEVICE,
......@@ -2013,6 +2024,7 @@ static const TypeInfo scsi_device_type_info = {
.abstract = true,
.class_size = sizeof(SCSIDeviceClass),
.class_init = scsi_device_class_init,
.instance_init = scsi_dev_instance_init,
};
static void scsi_register_types(void)
......
......@@ -2269,7 +2269,6 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
bdrv_set_guest_block_size(s->qdev.conf.bs, s->qdev.blocksize);
bdrv_iostatus_enable(s->qdev.conf.bs);
add_boot_device_path(s->qdev.conf.bootindex, &dev->qdev, NULL);
}
static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
......@@ -2662,7 +2661,6 @@ static const TypeInfo scsi_cd_info = {
#ifdef __linux__
static Property scsi_block_properties[] = {
DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.bs),
DEFINE_PROP_INT32("bootindex", SCSIDiskState, qdev.conf.bootindex, -1),
DEFINE_PROP_END_OF_LIST(),
};
......
......@@ -413,9 +413,6 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp)
/* define device state */
s->type = scsiid.scsi_type;
DPRINTF("device type %d\n", s->type);
if (s->type == TYPE_DISK || s->type == TYPE_ROM) {
add_boot_device_path(s->conf.bootindex, &s->qdev, NULL);
}
switch (s->type) {
case TYPE_TAPE:
......@@ -463,7 +460,6 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
static Property scsi_generic_properties[] = {
DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.bs),
DEFINE_PROP_INT32("bootindex", SCSIDevice, conf.bootindex, -1),
DEFINE_PROP_END_OF_LIST(),
};
......
......@@ -1371,8 +1371,16 @@ static void usb_net_realize(USBDevice *dev, Error **errrp)
s->conf.macaddr.a[4],
s->conf.macaddr.a[5]);
usb_desc_set_string(dev, STRING_ETHADDR, s->usbstring_mac);
}
static void usb_net_instance_init(Object *obj)
{
USBDevice *dev = USB_DEVICE(obj);
USBNetState *s = DO_UPCAST(USBNetState, dev, dev);
add_boot_device_path(s->conf.bootindex, &dev->qdev, "/ethernet@0");
device_add_bootindex_property(obj, &s->conf.bootindex,
"bootindex", "/ethernet-phy@0",
&dev->qdev, NULL);
}
static USBDevice *usb_net_init(USBBus *bus, const char *cmdline)
......@@ -1438,6 +1446,7 @@ static const TypeInfo net_info = {
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(USBNetState),
.class_init = usb_net_class_initfn,
.instance_init = usb_net_instance_init,
};
static void usb_net_register_types(void)
......
......@@ -17,6 +17,7 @@
#include "monitor/monitor.h"
#include "sysemu/sysemu.h"
#include "sysemu/blockdev.h"
#include "qapi/visitor.h"
//#define DEBUG_MSD
......@@ -59,6 +60,7 @@ typedef struct {
/* usb-storage only */
BlockConf conf;
uint32_t removable;
SCSIDevice *scsi_dev;
} MSDState;
struct usb_msd_cbw {
......@@ -633,6 +635,7 @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
return;
}
usb_msd_handle_reset(dev);
s->scsi_dev = scsi_dev;
if (bdrv_key_required(bs)) {
if (cur_mon) {
......@@ -765,6 +768,54 @@ static void usb_msd_class_initfn_storage(ObjectClass *klass, void *data)
usb_msd_class_initfn_common(klass);
}
static void usb_msd_get_bootindex(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
USBDevice *dev = USB_DEVICE(obj);
MSDState *s = DO_UPCAST(MSDState, dev, dev);
visit_type_int32(v, &s->conf.bootindex, name, errp);
}
static void usb_msd_set_bootindex(Object *obj, Visitor *v, void *opaque,
const char *name, Error **errp)
{
USBDevice *dev = USB_DEVICE(obj);
MSDState *s = DO_UPCAST(MSDState, dev, dev);
int32_t boot_index;
Error *local_err = NULL;
visit_type_int32(v, &boot_index, name, &local_err);
if (local_err) {
goto out;
}
/* check whether bootindex is present in fw_boot_order list */
check_boot_index(boot_index, &local_err);
if (local_err) {
goto out;
}
/* change bootindex to a new one */
s->conf.bootindex = boot_index;
if (s->scsi_dev) {
object_property_set_int(OBJECT(s->scsi_dev), boot_index, "bootindex",
&error_abort);
}
out:
if (local_err) {
error_propagate(errp, local_err);
}
}
static void usb_msd_instance_init(Object *obj)
{
object_property_add(obj, "bootindex", "int32",
usb_msd_get_bootindex,
usb_msd_set_bootindex, NULL, NULL, NULL);
object_property_set_int(obj, -1, "bootindex", NULL);
}
static void usb_msd_class_initfn_bot(ObjectClass *klass, void *data)
{
USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
......@@ -780,6 +831,7 @@ static const TypeInfo msd_info = {
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(MSDState),
.class_init = usb_msd_class_initfn_storage,
.instance_init = usb_msd_instance_init,
};
static const TypeInfo bot_info = {
......
......@@ -978,10 +978,19 @@ static void usb_host_realize(USBDevice *udev, Error **errp)
qemu_add_exit_notifier(&s->exit);
QTAILQ_INSERT_TAIL(&hostdevs, s, next);
add_boot_device_path(s->bootindex, &udev->qdev, NULL);
usb_host_auto_check(NULL);
}
static void usb_host_instance_init(Object *obj)
{
USBDevice *udev = USB_DEVICE(obj);
USBHostDevice *s = USB_HOST_DEVICE(udev);
device_add_bootindex_property(obj, &s->bootindex,
"bootindex", NULL,
&udev->qdev, NULL);
}
static void usb_host_handle_destroy(USBDevice *udev)
{
USBHostDevice *s = USB_HOST_DEVICE(udev);
......@@ -1465,7 +1474,6 @@ static Property usb_host_dev_properties[] = {
DEFINE_PROP_UINT32("productid", USBHostDevice, match.product_id, 0),
DEFINE_PROP_UINT32("isobufs", USBHostDevice, iso_urb_count, 4),
DEFINE_PROP_UINT32("isobsize", USBHostDevice, iso_urb_frames, 32),
DEFINE_PROP_INT32("bootindex", USBHostDevice, bootindex, -1),
DEFINE_PROP_UINT32("loglevel", USBHostDevice, loglevel,
LIBUSB_LOG_LEVEL_WARNING),
DEFINE_PROP_BIT("pipeline", USBHostDevice, options,
......@@ -1498,6 +1506,7 @@ static TypeInfo usb_host_dev_info = {
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(USBHostDevice),
.class_init = usb_host_class_initfn,
.instance_init = usb_host_instance_init,
};
static void usb_host_register_types(void)
......
......@@ -1401,7 +1401,6 @@ static void usbredir_realize(USBDevice *udev, Error **errp)
usbredir_chardev_read, usbredir_chardev_event, dev);
qemu_add_vm_change_state_handler(usbredir_vm_state_change, dev);
add_boot_device_path(dev->bootindex, &udev->qdev, NULL);
}
static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
......@@ -2471,7 +2470,6 @@ static Property usbredir_properties[] = {
DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, usbredirparser_warning),
DEFINE_PROP_STRING("filter", USBRedirDevice, filter_str),
DEFINE_PROP_INT32("bootindex", USBRedirDevice, bootindex, -1),
DEFINE_PROP_END_OF_LIST(),
};
......@@ -2496,11 +2494,22 @@ static void usbredir_class_initfn(ObjectClass *klass, void *data)
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}
static void usbredir_instance_init(Object *obj)
{
USBDevice *udev = USB_DEVICE(obj);
USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
device_add_bootindex_property(obj, &dev->bootindex,
"bootindex", NULL,
&udev->qdev, NULL);
}
static const TypeInfo usbredir_dev_info = {
.name = "usb-redir",
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(USBRedirDevice),
.class_init = usbredir_class_initfn,
.instance_init = usbredir_instance_init,
};
static void usbredir_register_types(void)
......
......@@ -1115,6 +1115,8 @@ static void virtio_blk_pci_instance_init(Object *obj)
TYPE_VIRTIO_BLK);
object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread",
&error_abort);
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
"bootindex", &error_abort);
}
static const TypeInfo virtio_blk_pci_info = {
......@@ -1466,6 +1468,8 @@ static void virtio_net_pci_instance_init(Object *obj)
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_NET);
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
"bootindex", &error_abort);
}
static const TypeInfo virtio_net_pci_info = {
......
......@@ -49,7 +49,6 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
_conf.physical_block_size, 512), \
DEFINE_PROP_UINT16("min_io_size", _state, _conf.min_io_size, 0), \
DEFINE_PROP_UINT32("opt_io_size", _state, _conf.opt_io_size, 0), \
DEFINE_PROP_INT32("bootindex", _state, _conf.bootindex, -1), \
DEFINE_PROP_UINT32("discard_granularity", _state, \
_conf.discard_granularity, -1)
......
......@@ -76,6 +76,8 @@ void fw_cfg_add_file(FWCfgState *s, const char *filename, void *data,
void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
FWCfgReadCallback callback, void *callback_opaque,
void *data, size_t len);
void *fw_cfg_modify_file(FWCfgState *s, const char *filename, void *data,
size_t len);
FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
hwaddr crl_addr, hwaddr data_addr);
......
......@@ -36,8 +36,7 @@ typedef struct NICConf {
#define DEFINE_NIC_PROPERTIES(_state, _conf) \
DEFINE_PROP_MACADDR("mac", _state, _conf.macaddr), \
DEFINE_PROP_VLAN("vlan", _state, _conf.peers), \
DEFINE_PROP_NETDEV("netdev", _state, _conf.peers), \
DEFINE_PROP_INT32("bootindex", _state, _conf.bootindex, -1)
DEFINE_PROP_NETDEV("netdev", _state, _conf.peers)
/* Net clients */
......
......@@ -130,6 +130,7 @@ extern int no_shutdown;
extern int semihosting_enabled;
extern int old_param;
extern int boot_menu;
extern bool boot_strict;
extern uint8_t *boot_splash_filedata;
extern size_t boot_splash_filedata_size;
extern uint8_t qemu_extra_params_fw[2];
......@@ -212,6 +213,11 @@ void add_boot_device_path(int32_t bootindex, DeviceState *dev,
char *get_boot_devices_list(size_t *size, bool ignore_suffixes);
DeviceState *get_boot_device(uint32_t position);
void check_boot_index(int32_t bootindex, Error **errp);
void del_boot_device_path(DeviceState *dev, const char *suffix);
void device_add_bootindex_property(Object *obj, int32_t *bootindex,
const char *name, const char *suffix,
DeviceState *dev, Error **errp);
QemuOpts *qemu_get_machine_opts(void);
......
......@@ -180,23 +180,12 @@ int ctrl_grab = 0;
unsigned int nb_prom_envs = 0;
const char *prom_envs[MAX_PROM_ENVS];
int boot_menu;
static bool boot_strict;
bool boot_strict;
uint8_t *boot_splash_filedata;
size_t boot_splash_filedata_size;
uint8_t qemu_extra_params_fw[2];
int icount_align_option;
typedef struct FWBootEntry FWBootEntry;
struct FWBootEntry {
QTAILQ_ENTRY(FWBootEntry) link;
int32_t bootindex;
DeviceState *dev;
char *suffix;
};
static QTAILQ_HEAD(, FWBootEntry) fw_boot_order =
QTAILQ_HEAD_INITIALIZER(fw_boot_order);
int nb_numa_nodes;
int max_numa_nodeid;
......@@ -1246,111 +1235,6 @@ static void restore_boot_order(void *opaque)
g_free(normal_boot_order);
}
void add_boot_device_path(int32_t bootindex, DeviceState *dev,
const char *suffix)
{
FWBootEntry *node, *i;
if (bootindex < 0) {
return;
}
assert(dev != NULL || suffix != NULL);
node = g_malloc0(sizeof(FWBootEntry));
node->bootindex = bootindex;
node->suffix = g_strdup(suffix);
node->dev = dev;
QTAILQ_FOREACH(i, &fw_boot_order, link) {
if (i->bootindex == bootindex) {
fprintf(stderr, "Two devices with same boot index %d\n", bootindex);
exit(1);
} else if (i->bootindex < bootindex) {
continue;
}
QTAILQ_INSERT_BEFORE(i, node, link);
return;
}
QTAILQ_INSERT_TAIL(&fw_boot_order, node, link);
}
DeviceState *get_boot_device(uint32_t position)
{
uint32_t counter = 0;
FWBootEntry *i = NULL;
DeviceState *res = NULL;
if (!QTAILQ_EMPTY(&fw_boot_order)) {
QTAILQ_FOREACH(i, &fw_boot_order, link) {
if (counter == position) {
res = i->dev;
break;
}
counter++;
}
}
return res;
}
/*
* This function returns null terminated string that consist of new line
* separated device paths.
*
* memory pointed by "size" is assigned total length of the array in bytes
*
*/
char *get_boot_devices_list(size_t *size, bool ignore_suffixes)
{
FWBootEntry *i;
size_t total = 0;
char *list = NULL;
QTAILQ_FOREACH(i, &fw_boot_order, link) {
char *devpath = NULL, *bootpath;
size_t len;
if (i->dev) {
devpath = qdev_get_fw_dev_path(i->dev);
assert(devpath);
}
if (i->suffix && !ignore_suffixes && devpath) {
size_t bootpathlen = strlen(devpath) + strlen(i->suffix) + 1;
bootpath = g_malloc(bootpathlen);
snprintf(bootpath, bootpathlen, "%s%s", devpath, i->suffix);
g_free(devpath);
} else if (devpath) {
bootpath = devpath;
} else if (!ignore_suffixes) {
assert(i->suffix);
bootpath = g_strdup(i->suffix);
} else {
bootpath = g_strdup("");
}
if (total) {
list[total-1] = '\n';
}
len = strlen(bootpath) + 1;
list = g_realloc(list, total + len);
memcpy(&list[total], bootpath, len);
total += len;
g_free(bootpath);
}
*size = total;
if (boot_strict && *size > 0) {
list[total-1] = '\n';
list = g_realloc(list, total + 5);
memcpy(&list[total], "HALT", 5);
*size = total + 5;
}
return list;
}
static QemuOptsList qemu_smp_opts = {
.name = "smp-opts",
.implied_opt_name = "cpus",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册