mirror of https://github.com/xqemu/xqemu.git
allow changing bootorder via monitor at runtime,
by making bootindex a writable qom property. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJUPjeVAAoJEEy22O7T6HE4j5QP/RtecYdC9yiOGsGcI4lrDMo8 5j61JzvY7bpPGJykXH7c8B9s3n2LQIW4rzD5mDVB/bKXPwh3SbqPBQmd1T6G7lrR 4lV+c/pvrTDE9V1k0Favbe0pbfOkaBAnMyYEYFkoK7hzVUTN6acbkz0LhXudb4ci 7V9wbSLnZZrTxB50NTJu17EIa7RCDKQR6urskrxAsJeqCAT7NQtXM5ls1dfGvHQs Tc6u4+zRqv2Rzr9YxkFKPZe55rTBMUw3fcwg9F3657dCujYvcMq8+ZwFGiMXSjll oUFxwgZn05aRQwxG1YfFDI576+f9ZCirkQBoDBwgp3ZSLTN8CLVDZ0X1FA7vjntH fr5j7D0M2ftSsUDI2E3UOzaNtbtyQaCkggl+zc0fgw7dEfbitqpUZQQ4wGngBTKJ BFkky+29MhBTLqBC38S9iUGqUbHbrqIHP/hSW8ixAGm4n8dul+ROgX4ynFZNOuxE NEA1rRspDHNVanb+gcpK0wv58vvmwbECGrovkI7ffeCo+8+MDW3ebRbQ2fIxUa4C KbPp6b5vICVcsG0+XRbjA2rNn76iJYCjc+PX1WQX6vgPYEPRah51G44KLyN/r8kj fw7wOuYomtu+2nymH/8QXBEyACiuCJLTmOykHxsrYURR3VvVeg2Z0j4e7fNOg/Is +d+cVKKkN8JLFRlXG8qu =utUi -----END PGP SIGNATURE----- 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: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
605c690b1b
|
@ -127,7 +127,7 @@ endif #CONFIG_BSD_USER
|
||||||
# System emulator target
|
# System emulator target
|
||||||
ifdef CONFIG_SOFTMMU
|
ifdef CONFIG_SOFTMMU
|
||||||
obj-y += arch_init.o cpus.o monitor.o gdbstub.o balloon.o ioport.o numa.o
|
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-y += hw/
|
||||||
obj-$(CONFIG_FDT) += device_tree.o
|
obj-$(CONFIG_FDT) += device_tree.o
|
||||||
obj-$(CONFIG_KVM) += kvm-all.o
|
obj-$(CONFIG_KVM) += kvm-all.o
|
||||||
|
|
|
@ -0,0 +1,258 @@
|
||||||
|
/*
|
||||||
|
* 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);
|
error_propagate(errp, err);
|
||||||
return;
|
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)
|
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_UINT32("dma", FDCtrlISABus, dma, 2),
|
||||||
DEFINE_PROP_DRIVE("driveA", FDCtrlISABus, state.drives[0].bs),
|
DEFINE_PROP_DRIVE("driveA", FDCtrlISABus, state.drives[0].bs),
|
||||||
DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.drives[1].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,
|
DEFINE_PROP_BIT("check_media_rate", FDCtrlISABus, state.check_media_rate,
|
||||||
0, true),
|
0, true),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
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);
|
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 = {
|
static const TypeInfo isa_fdc_info = {
|
||||||
.name = TYPE_ISA_FDC,
|
.name = TYPE_ISA_FDC,
|
||||||
.parent = TYPE_ISA_DEVICE,
|
.parent = TYPE_ISA_DEVICE,
|
||||||
.instance_size = sizeof(FDCtrlISABus),
|
.instance_size = sizeof(FDCtrlISABus),
|
||||||
.class_init = isabus_fdc_class_init,
|
.class_init = isabus_fdc_class_init,
|
||||||
|
.instance_init = isabus_fdc_instance_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const VMStateDescription vmstate_sysbus_fdc ={
|
static const VMStateDescription vmstate_sysbus_fdc ={
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
#include <hw/hw.h>
|
#include <hw/hw.h>
|
||||||
#include <hw/pci/msix.h>
|
#include <hw/pci/msix.h>
|
||||||
#include <hw/pci/pci.h>
|
#include <hw/pci/pci.h>
|
||||||
|
#include "sysemu/sysemu.h"
|
||||||
|
#include "qapi/visitor.h"
|
||||||
|
|
||||||
#include "nvme.h"
|
#include "nvme.h"
|
||||||
|
|
||||||
|
@ -871,11 +873,53 @@ static void nvme_class_init(ObjectClass *oc, void *data)
|
||||||
dc->vmsd = &nvme_vmstate;
|
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 = {
|
static const TypeInfo nvme_info = {
|
||||||
.name = "nvme",
|
.name = "nvme",
|
||||||
.parent = TYPE_PCI_DEVICE,
|
.parent = TYPE_PCI_DEVICE,
|
||||||
.instance_size = sizeof(NvmeCtrl),
|
.instance_size = sizeof(NvmeCtrl),
|
||||||
.class_init = nvme_class_init,
|
.class_init = nvme_class_init,
|
||||||
|
.instance_init = nvme_instance_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void nvme_register_types(void)
|
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_set_guest_block_size(s->bs, s->conf->logical_block_size);
|
||||||
|
|
||||||
bdrv_iostatus_enable(s->bs);
|
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)
|
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,
|
(Object **)&s->blk.iothread,
|
||||||
qdev_prop_allow_set_link_before_realize,
|
qdev_prop_allow_set_link_before_realize,
|
||||||
OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL);
|
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[] = {
|
static Property virtio_blk_properties[] = {
|
||||||
|
|
|
@ -1825,8 +1825,6 @@ static int assigned_initfn(struct PCIDevice *pci_dev)
|
||||||
|
|
||||||
assigned_dev_load_option_rom(dev);
|
assigned_dev_load_option_rom(dev);
|
||||||
|
|
||||||
add_boot_device_path(dev->bootindex, &pci_dev->qdev, NULL);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
assigned_out:
|
assigned_out:
|
||||||
|
@ -1850,13 +1848,22 @@ static void assigned_exitfn(struct PCIDevice *pci_dev)
|
||||||
free_assigned_device(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[] = {
|
static Property assigned_dev_properties[] = {
|
||||||
DEFINE_PROP_PCI_HOST_DEVADDR("host", AssignedDevice, host),
|
DEFINE_PROP_PCI_HOST_DEVADDR("host", AssignedDevice, host),
|
||||||
DEFINE_PROP_BIT("prefer_msi", AssignedDevice, features,
|
DEFINE_PROP_BIT("prefer_msi", AssignedDevice, features,
|
||||||
ASSIGNED_DEVICE_PREFER_MSI_BIT, false),
|
ASSIGNED_DEVICE_PREFER_MSI_BIT, false),
|
||||||
DEFINE_PROP_BIT("share_intx", AssignedDevice, features,
|
DEFINE_PROP_BIT("share_intx", AssignedDevice, features,
|
||||||
ASSIGNED_DEVICE_SHARE_INTX_BIT, true),
|
ASSIGNED_DEVICE_SHARE_INTX_BIT, true),
|
||||||
DEFINE_PROP_INT32("bootindex", AssignedDevice, bootindex, -1),
|
|
||||||
DEFINE_PROP_STRING("configfd", AssignedDevice, configfd_name),
|
DEFINE_PROP_STRING("configfd", AssignedDevice, configfd_name),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
@ -1882,6 +1889,7 @@ static const TypeInfo assign_info = {
|
||||||
.parent = TYPE_PCI_DEVICE,
|
.parent = TYPE_PCI_DEVICE,
|
||||||
.instance_size = sizeof(AssignedDevice),
|
.instance_size = sizeof(AssignedDevice),
|
||||||
.class_init = assign_class_init,
|
.class_init = assign_class_init,
|
||||||
|
.instance_init = assigned_dev_instance_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void assign_register_types(void)
|
static void assign_register_types(void)
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "sysemu/blockdev.h"
|
#include "sysemu/blockdev.h"
|
||||||
#include "hw/block/block.h"
|
#include "hw/block/block.h"
|
||||||
#include "sysemu/sysemu.h"
|
#include "sysemu/sysemu.h"
|
||||||
|
#include "qapi/visitor.h"
|
||||||
|
|
||||||
/* --------------------------------- */
|
/* --------------------------------- */
|
||||||
|
|
||||||
|
@ -191,6 +192,51 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind)
|
||||||
return 0;
|
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)
|
static int ide_hd_initfn(IDEDevice *dev)
|
||||||
{
|
{
|
||||||
return ide_dev_initfn(dev, IDE_HD);
|
return ide_dev_initfn(dev, IDE_HD);
|
||||||
|
@ -300,6 +346,7 @@ static const TypeInfo ide_device_type_info = {
|
||||||
.abstract = true,
|
.abstract = true,
|
||||||
.class_size = sizeof(IDEDeviceClass),
|
.class_size = sizeof(IDEDeviceClass),
|
||||||
.class_init = ide_device_class_init,
|
.class_init = ide_device_class_init,
|
||||||
|
.instance_init = ide_dev_instance_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void ide_register_types(void)
|
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);
|
vfio_register_err_notifier(vdev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -4365,13 +4364,22 @@ post_reset:
|
||||||
vfio_pci_post_reset(vdev);
|
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[] = {
|
static Property vfio_pci_dev_properties[] = {
|
||||||
DEFINE_PROP_PCI_HOST_DEVADDR("host", VFIODevice, host),
|
DEFINE_PROP_PCI_HOST_DEVADDR("host", VFIODevice, host),
|
||||||
DEFINE_PROP_UINT32("x-intx-mmap-timeout-ms", VFIODevice,
|
DEFINE_PROP_UINT32("x-intx-mmap-timeout-ms", VFIODevice,
|
||||||
intx.mmap_timeout, 1100),
|
intx.mmap_timeout, 1100),
|
||||||
DEFINE_PROP_BIT("x-vga", VFIODevice, features,
|
DEFINE_PROP_BIT("x-vga", VFIODevice, features,
|
||||||
VFIO_FEATURE_ENABLE_VGA_BIT, false),
|
VFIO_FEATURE_ENABLE_VGA_BIT, false),
|
||||||
DEFINE_PROP_INT32("bootindex", VFIODevice, bootindex, -1),
|
|
||||||
/*
|
/*
|
||||||
* TODO - support passed fds... is this necessary?
|
* TODO - support passed fds... is this necessary?
|
||||||
* DEFINE_PROP_STRING("vfiofd", VFIODevice, vfiofd_name),
|
* DEFINE_PROP_STRING("vfiofd", VFIODevice, vfiofd_name),
|
||||||
|
@ -4407,6 +4415,7 @@ static const TypeInfo vfio_pci_dev_info = {
|
||||||
.parent = TYPE_PCI_DEVICE,
|
.parent = TYPE_PCI_DEVICE,
|
||||||
.instance_size = sizeof(VFIODevice),
|
.instance_size = sizeof(VFIODevice),
|
||||||
.class_init = vfio_pci_dev_class_init,
|
.class_init = vfio_pci_dev_class_init,
|
||||||
|
.instance_init = vfio_instance_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void register_vfio_pci_dev_type(void)
|
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);
|
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->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);
|
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;
|
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 = {
|
static const TypeInfo e1000_base_info = {
|
||||||
.name = TYPE_E1000_BASE,
|
.name = TYPE_E1000_BASE,
|
||||||
.parent = TYPE_PCI_DEVICE,
|
.parent = TYPE_PCI_DEVICE,
|
||||||
.instance_size = sizeof(E1000State),
|
.instance_size = sizeof(E1000State),
|
||||||
|
.instance_init = e1000_instance_init,
|
||||||
.class_size = sizeof(E1000BaseClass),
|
.class_size = sizeof(E1000BaseClass),
|
||||||
.abstract = true,
|
.abstract = true,
|
||||||
};
|
};
|
||||||
|
@ -1668,6 +1675,7 @@ static void e1000_register_types(void)
|
||||||
type_info.parent = TYPE_E1000_BASE;
|
type_info.parent = TYPE_E1000_BASE;
|
||||||
type_info.class_data = (void *)info;
|
type_info.class_data = (void *)info;
|
||||||
type_info.class_init = e1000_class_init;
|
type_info.class_init = e1000_class_init;
|
||||||
|
type_info.instance_init = e1000_instance_init;
|
||||||
|
|
||||||
type_register(&type_info);
|
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;
|
s->vmstate->name = qemu_get_queue(s->nic)->model;
|
||||||
vmstate_register(&pci_dev->qdev, -1, s->vmstate, s);
|
vmstate_register(&pci_dev->qdev, -1, s->vmstate, s);
|
||||||
|
|
||||||
add_boot_device_path(s->conf.bootindex, &pci_dev->qdev, "/ethernet-phy@0");
|
|
||||||
|
|
||||||
return 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[] = {
|
static E100PCIDeviceInfo e100_devices[] = {
|
||||||
{
|
{
|
||||||
.name = "i82550",
|
.name = "i82550",
|
||||||
|
@ -2104,7 +2110,8 @@ static void eepro100_register_types(void)
|
||||||
type_info.parent = TYPE_PCI_DEVICE;
|
type_info.parent = TYPE_PCI_DEVICE;
|
||||||
type_info.class_init = eepro100_class_init;
|
type_info.class_init = eepro100_class_init;
|
||||||
type_info.instance_size = sizeof(EEPRO100State);
|
type_info.instance_size = sizeof(EEPRO100State);
|
||||||
|
type_info.instance_init = eepro100_instance_init;
|
||||||
|
|
||||||
type_register(&type_info);
|
type_register(&type_info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "hw/sparc/sun4m.h"
|
#include "hw/sparc/sun4m.h"
|
||||||
#include "pcnet.h"
|
#include "pcnet.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
|
#include "sysemu/sysemu.h"
|
||||||
|
|
||||||
#define TYPE_LANCE "lance"
|
#define TYPE_LANCE "lance"
|
||||||
#define SYSBUS_PCNET(obj) \
|
#define SYSBUS_PCNET(obj) \
|
||||||
|
@ -143,6 +144,16 @@ static void lance_reset(DeviceState *dev)
|
||||||
pcnet_h_reset(&d->state);
|
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[] = {
|
static Property lance_properties[] = {
|
||||||
DEFINE_PROP_PTR("dma", SysBusPCNetState, state.dma_opaque),
|
DEFINE_PROP_PTR("dma", SysBusPCNetState, state.dma_opaque),
|
||||||
DEFINE_NIC_PROPERTIES(SysBusPCNetState, state.conf),
|
DEFINE_NIC_PROPERTIES(SysBusPCNetState, state.conf),
|
||||||
|
@ -169,6 +180,7 @@ static const TypeInfo lance_info = {
|
||||||
.parent = TYPE_SYS_BUS_DEVICE,
|
.parent = TYPE_SYS_BUS_DEVICE,
|
||||||
.instance_size = sizeof(SysBusPCNetState),
|
.instance_size = sizeof(SysBusPCNetState),
|
||||||
.class_init = lance_class_init,
|
.class_init = lance_class_init,
|
||||||
|
.instance_init = lance_instance_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void lance_register_types(void)
|
static void lance_register_types(void)
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "net/net.h"
|
#include "net/net.h"
|
||||||
#include "ne2000.h"
|
#include "ne2000.h"
|
||||||
#include "exec/address-spaces.h"
|
#include "exec/address-spaces.h"
|
||||||
|
#include "qapi/visitor.h"
|
||||||
|
|
||||||
#define TYPE_ISA_NE2000 "ne2k_isa"
|
#define TYPE_ISA_NE2000 "ne2k_isa"
|
||||||
#define ISA_NE2000(obj) OBJECT_CHECK(ISANE2000State, (obj), TYPE_ISA_NE2000)
|
#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);
|
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 = {
|
static const TypeInfo ne2000_isa_info = {
|
||||||
.name = TYPE_ISA_NE2000,
|
.name = TYPE_ISA_NE2000,
|
||||||
.parent = TYPE_ISA_DEVICE,
|
.parent = TYPE_ISA_DEVICE,
|
||||||
.instance_size = sizeof(ISANE2000State),
|
.instance_size = sizeof(ISANE2000State),
|
||||||
.class_init = isa_ne2000_class_initfn,
|
.class_init = isa_ne2000_class_initfn,
|
||||||
|
.instance_init = isa_ne2000_instance_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void ne2000_isa_register_types(void)
|
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);
|
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);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -752,6 +750,17 @@ static void pci_ne2000_exit(PCIDevice *pci_dev)
|
||||||
qemu_free_irq(s->irq);
|
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[] = {
|
static Property ne2000_properties[] = {
|
||||||
DEFINE_NIC_PROPERTIES(PCINE2000State, ne2000.c),
|
DEFINE_NIC_PROPERTIES(PCINE2000State, ne2000.c),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
|
@ -778,6 +787,7 @@ static const TypeInfo ne2000_info = {
|
||||||
.parent = TYPE_PCI_DEVICE,
|
.parent = TYPE_PCI_DEVICE,
|
||||||
.instance_size = sizeof(PCINE2000State),
|
.instance_size = sizeof(PCINE2000State),
|
||||||
.class_init = ne2000_class_init,
|
.class_init = ne2000_class_init,
|
||||||
|
.instance_init = ne2000_instance_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void ne2000_register_types(void)
|
static void ne2000_register_types(void)
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "hw/loader.h"
|
#include "hw/loader.h"
|
||||||
#include "qemu/timer.h"
|
#include "qemu/timer.h"
|
||||||
#include "sysemu/dma.h"
|
#include "sysemu/dma.h"
|
||||||
|
#include "sysemu/sysemu.h"
|
||||||
|
|
||||||
#include "pcnet.h"
|
#include "pcnet.h"
|
||||||
|
|
||||||
|
@ -344,6 +345,16 @@ static void pci_reset(DeviceState *dev)
|
||||||
pcnet_h_reset(&d->state);
|
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[] = {
|
static Property pcnet_properties[] = {
|
||||||
DEFINE_NIC_PROPERTIES(PCIPCNetState, state.conf),
|
DEFINE_NIC_PROPERTIES(PCIPCNetState, state.conf),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
|
@ -372,6 +383,7 @@ static const TypeInfo pcnet_info = {
|
||||||
.parent = TYPE_PCI_DEVICE,
|
.parent = TYPE_PCI_DEVICE,
|
||||||
.instance_size = sizeof(PCIPCNetState),
|
.instance_size = sizeof(PCIPCNetState),
|
||||||
.class_init = pcnet_class_init,
|
.class_init = pcnet_class_init,
|
||||||
|
.instance_init = pcnet_instance_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void pci_pcnet_register_types(void)
|
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);
|
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);
|
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 */
|
/* Initialize the PROM */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -66,5 +66,4 @@ void pcnet_set_link_status(NetClientState *nc);
|
||||||
void pcnet_common_cleanup(PCNetState *d);
|
void pcnet_common_cleanup(PCNetState *d);
|
||||||
int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info);
|
int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info);
|
||||||
extern const VMStateDescription vmstate_pcnet;
|
extern const VMStateDescription vmstate_pcnet;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3538,11 +3538,18 @@ static int pci_rtl8139_init(PCIDevice *dev)
|
||||||
s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, rtl8139_timer, s);
|
s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, rtl8139_timer, s);
|
||||||
rtl8139_set_next_tctr_time(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
|
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;
|
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[] = {
|
static Property rtl8139_properties[] = {
|
||||||
DEFINE_NIC_PROPERTIES(RTL8139State, conf),
|
DEFINE_NIC_PROPERTIES(RTL8139State, conf),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
|
@ -3571,6 +3578,7 @@ static const TypeInfo rtl8139_info = {
|
||||||
.parent = TYPE_PCI_DEVICE,
|
.parent = TYPE_PCI_DEVICE,
|
||||||
.instance_size = sizeof(RTL8139State),
|
.instance_size = sizeof(RTL8139State),
|
||||||
.class_init = rtl8139_class_init,
|
.class_init = rtl8139_class_init,
|
||||||
|
.instance_init = rtl8139_instance_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void rtl8139_register_types(void)
|
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);
|
object_get_typename(OBJECT(sdev)), sdev->qdev.id, dev);
|
||||||
qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);
|
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;
|
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)
|
void spapr_vlan_create(VIOsPAPRBus *bus, NICInfo *nd)
|
||||||
{
|
{
|
||||||
DeviceState *dev;
|
DeviceState *dev;
|
||||||
|
@ -553,6 +560,7 @@ static const TypeInfo spapr_vlan_info = {
|
||||||
.parent = TYPE_VIO_SPAPR_DEVICE,
|
.parent = TYPE_VIO_SPAPR_DEVICE,
|
||||||
.instance_size = sizeof(VIOsPAPRVLANDevice),
|
.instance_size = sizeof(VIOsPAPRVLANDevice),
|
||||||
.class_init = spapr_vlan_class_init,
|
.class_init = spapr_vlan_class_init,
|
||||||
|
.instance_init = spapr_vlan_instance_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void spapr_vlan_register_types(void)
|
static void spapr_vlan_register_types(void)
|
||||||
|
|
|
@ -1661,8 +1661,6 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
|
||||||
n->qdev = dev;
|
n->qdev = dev;
|
||||||
register_savevm(dev, "virtio-net", -1, VIRTIO_NET_VM_VERSION,
|
register_savevm(dev, "virtio-net", -1, VIRTIO_NET_VM_VERSION,
|
||||||
virtio_net_save, virtio_net_load, n);
|
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)
|
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.
|
* Can be overriden with virtio_net_set_config_size.
|
||||||
*/
|
*/
|
||||||
n->config_size = sizeof(struct virtio_net_config);
|
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[] = {
|
static Property virtio_net_properties[] = {
|
||||||
|
|
|
@ -2172,11 +2172,16 @@ static int vmxnet3_pci_init(PCIDevice *pci_dev)
|
||||||
register_savevm(dev, "vmxnet3-msix", -1, 1,
|
register_savevm(dev, "vmxnet3-msix", -1, 1,
|
||||||
vmxnet3_msix_save, vmxnet3_msix_load, s);
|
vmxnet3_msix_save, vmxnet3_msix_load, s);
|
||||||
|
|
||||||
add_boot_device_path(s->conf.bootindex, dev, "/ethernet-phy@0");
|
|
||||||
|
|
||||||
return 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)
|
static void vmxnet3_pci_uninit(PCIDevice *pci_dev)
|
||||||
{
|
{
|
||||||
|
@ -2524,6 +2529,7 @@ static const TypeInfo vmxnet3_info = {
|
||||||
.parent = TYPE_PCI_DEVICE,
|
.parent = TYPE_PCI_DEVICE,
|
||||||
.instance_size = sizeof(VMXNET3State),
|
.instance_size = sizeof(VMXNET3State),
|
||||||
.class_init = vmxnet3_class_init,
|
.class_init = vmxnet3_class_init,
|
||||||
|
.instance_init = vmxnet3_instance_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void vmxnet3_register_types(void)
|
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;
|
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)
|
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);
|
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);
|
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;
|
size_t len;
|
||||||
FWCfgState *s = container_of(n, FWCfgState, machine_ready);
|
FWCfgState *s = opaque;
|
||||||
char *bootindex = get_boot_devices_list(&len, false);
|
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,
|
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),
|
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
|
||||||
TYPE_VIRTIO_NET);
|
TYPE_VIRTIO_NET);
|
||||||
|
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
|
||||||
|
"bootindex", &error_abort);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s390_virtio_blk_init(VirtIOS390Device *s390_dev)
|
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);
|
TYPE_VIRTIO_BLK);
|
||||||
object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread",
|
object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread",
|
||||||
&error_abort);
|
&error_abort);
|
||||||
|
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
|
||||||
|
"bootindex", &error_abort);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int s390_virtio_serial_init(VirtIOS390Device *s390_dev)
|
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),
|
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
|
||||||
TYPE_VIRTIO_NET);
|
TYPE_VIRTIO_NET);
|
||||||
|
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
|
||||||
|
"bootindex", &error_abort);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int virtio_ccw_blk_init(VirtioCcwDevice *ccw_dev)
|
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);
|
TYPE_VIRTIO_BLK);
|
||||||
object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread",
|
object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread",
|
||||||
&error_abort);
|
&error_abort);
|
||||||
|
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
|
||||||
|
"bootindex", &error_abort);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int virtio_ccw_serial_init(VirtioCcwDevice *ccw_dev)
|
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);
|
dev = qdev_create(&bus->qbus, driver);
|
||||||
qdev_prop_set_uint32(dev, "scsi-id", unit);
|
qdev_prop_set_uint32(dev, "scsi-id", unit);
|
||||||
if (bootindex >= 0) {
|
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)) {
|
if (object_property_find(OBJECT(dev), "removable", NULL)) {
|
||||||
qdev_prop_set_bit(dev, "removable", removable);
|
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;
|
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 = {
|
static const TypeInfo scsi_device_type_info = {
|
||||||
.name = TYPE_SCSI_DEVICE,
|
.name = TYPE_SCSI_DEVICE,
|
||||||
.parent = TYPE_DEVICE,
|
.parent = TYPE_DEVICE,
|
||||||
|
@ -2013,6 +2024,7 @@ static const TypeInfo scsi_device_type_info = {
|
||||||
.abstract = true,
|
.abstract = true,
|
||||||
.class_size = sizeof(SCSIDeviceClass),
|
.class_size = sizeof(SCSIDeviceClass),
|
||||||
.class_init = scsi_device_class_init,
|
.class_init = scsi_device_class_init,
|
||||||
|
.instance_init = scsi_dev_instance_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void scsi_register_types(void)
|
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_set_guest_block_size(s->qdev.conf.bs, s->qdev.blocksize);
|
||||||
|
|
||||||
bdrv_iostatus_enable(s->qdev.conf.bs);
|
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)
|
static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
|
||||||
|
@ -2662,7 +2661,6 @@ static const TypeInfo scsi_cd_info = {
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
static Property scsi_block_properties[] = {
|
static Property scsi_block_properties[] = {
|
||||||
DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.bs),
|
DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.bs),
|
||||||
DEFINE_PROP_INT32("bootindex", SCSIDiskState, qdev.conf.bootindex, -1),
|
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -413,9 +413,6 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp)
|
||||||
/* define device state */
|
/* define device state */
|
||||||
s->type = scsiid.scsi_type;
|
s->type = scsiid.scsi_type;
|
||||||
DPRINTF("device type %d\n", s->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) {
|
switch (s->type) {
|
||||||
case TYPE_TAPE:
|
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[] = {
|
static Property scsi_generic_properties[] = {
|
||||||
DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.bs),
|
DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.bs),
|
||||||
DEFINE_PROP_INT32("bootindex", SCSIDevice, conf.bootindex, -1),
|
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
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[4],
|
||||||
s->conf.macaddr.a[5]);
|
s->conf.macaddr.a[5]);
|
||||||
usb_desc_set_string(dev, STRING_ETHADDR, s->usbstring_mac);
|
usb_desc_set_string(dev, STRING_ETHADDR, s->usbstring_mac);
|
||||||
|
}
|
||||||
|
|
||||||
add_boot_device_path(s->conf.bootindex, &dev->qdev, "/ethernet@0");
|
static void usb_net_instance_init(Object *obj)
|
||||||
|
{
|
||||||
|
USBDevice *dev = USB_DEVICE(obj);
|
||||||
|
USBNetState *s = DO_UPCAST(USBNetState, dev, dev);
|
||||||
|
|
||||||
|
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)
|
static USBDevice *usb_net_init(USBBus *bus, const char *cmdline)
|
||||||
|
@ -1438,6 +1446,7 @@ static const TypeInfo net_info = {
|
||||||
.parent = TYPE_USB_DEVICE,
|
.parent = TYPE_USB_DEVICE,
|
||||||
.instance_size = sizeof(USBNetState),
|
.instance_size = sizeof(USBNetState),
|
||||||
.class_init = usb_net_class_initfn,
|
.class_init = usb_net_class_initfn,
|
||||||
|
.instance_init = usb_net_instance_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void usb_net_register_types(void)
|
static void usb_net_register_types(void)
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "monitor/monitor.h"
|
#include "monitor/monitor.h"
|
||||||
#include "sysemu/sysemu.h"
|
#include "sysemu/sysemu.h"
|
||||||
#include "sysemu/blockdev.h"
|
#include "sysemu/blockdev.h"
|
||||||
|
#include "qapi/visitor.h"
|
||||||
|
|
||||||
//#define DEBUG_MSD
|
//#define DEBUG_MSD
|
||||||
|
|
||||||
|
@ -59,6 +60,7 @@ typedef struct {
|
||||||
/* usb-storage only */
|
/* usb-storage only */
|
||||||
BlockConf conf;
|
BlockConf conf;
|
||||||
uint32_t removable;
|
uint32_t removable;
|
||||||
|
SCSIDevice *scsi_dev;
|
||||||
} MSDState;
|
} MSDState;
|
||||||
|
|
||||||
struct usb_msd_cbw {
|
struct usb_msd_cbw {
|
||||||
|
@ -633,6 +635,7 @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
usb_msd_handle_reset(dev);
|
usb_msd_handle_reset(dev);
|
||||||
|
s->scsi_dev = scsi_dev;
|
||||||
|
|
||||||
if (bdrv_key_required(bs)) {
|
if (bdrv_key_required(bs)) {
|
||||||
if (cur_mon) {
|
if (cur_mon) {
|
||||||
|
@ -765,6 +768,54 @@ static void usb_msd_class_initfn_storage(ObjectClass *klass, void *data)
|
||||||
usb_msd_class_initfn_common(klass);
|
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)
|
static void usb_msd_class_initfn_bot(ObjectClass *klass, void *data)
|
||||||
{
|
{
|
||||||
USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
|
USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
|
||||||
|
@ -780,6 +831,7 @@ static const TypeInfo msd_info = {
|
||||||
.parent = TYPE_USB_DEVICE,
|
.parent = TYPE_USB_DEVICE,
|
||||||
.instance_size = sizeof(MSDState),
|
.instance_size = sizeof(MSDState),
|
||||||
.class_init = usb_msd_class_initfn_storage,
|
.class_init = usb_msd_class_initfn_storage,
|
||||||
|
.instance_init = usb_msd_instance_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const TypeInfo bot_info = {
|
static const TypeInfo bot_info = {
|
||||||
|
|
|
@ -978,10 +978,19 @@ static void usb_host_realize(USBDevice *udev, Error **errp)
|
||||||
qemu_add_exit_notifier(&s->exit);
|
qemu_add_exit_notifier(&s->exit);
|
||||||
|
|
||||||
QTAILQ_INSERT_TAIL(&hostdevs, s, next);
|
QTAILQ_INSERT_TAIL(&hostdevs, s, next);
|
||||||
add_boot_device_path(s->bootindex, &udev->qdev, NULL);
|
|
||||||
usb_host_auto_check(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)
|
static void usb_host_handle_destroy(USBDevice *udev)
|
||||||
{
|
{
|
||||||
USBHostDevice *s = USB_HOST_DEVICE(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("productid", USBHostDevice, match.product_id, 0),
|
||||||
DEFINE_PROP_UINT32("isobufs", USBHostDevice, iso_urb_count, 4),
|
DEFINE_PROP_UINT32("isobufs", USBHostDevice, iso_urb_count, 4),
|
||||||
DEFINE_PROP_UINT32("isobsize", USBHostDevice, iso_urb_frames, 32),
|
DEFINE_PROP_UINT32("isobsize", USBHostDevice, iso_urb_frames, 32),
|
||||||
DEFINE_PROP_INT32("bootindex", USBHostDevice, bootindex, -1),
|
|
||||||
DEFINE_PROP_UINT32("loglevel", USBHostDevice, loglevel,
|
DEFINE_PROP_UINT32("loglevel", USBHostDevice, loglevel,
|
||||||
LIBUSB_LOG_LEVEL_WARNING),
|
LIBUSB_LOG_LEVEL_WARNING),
|
||||||
DEFINE_PROP_BIT("pipeline", USBHostDevice, options,
|
DEFINE_PROP_BIT("pipeline", USBHostDevice, options,
|
||||||
|
@ -1498,6 +1506,7 @@ static TypeInfo usb_host_dev_info = {
|
||||||
.parent = TYPE_USB_DEVICE,
|
.parent = TYPE_USB_DEVICE,
|
||||||
.instance_size = sizeof(USBHostDevice),
|
.instance_size = sizeof(USBHostDevice),
|
||||||
.class_init = usb_host_class_initfn,
|
.class_init = usb_host_class_initfn,
|
||||||
|
.instance_init = usb_host_instance_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void usb_host_register_types(void)
|
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);
|
usbredir_chardev_read, usbredir_chardev_event, dev);
|
||||||
|
|
||||||
qemu_add_vm_change_state_handler(usbredir_vm_state_change, 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)
|
static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
|
||||||
|
@ -2471,7 +2470,6 @@ static Property usbredir_properties[] = {
|
||||||
DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
|
DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
|
||||||
DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, usbredirparser_warning),
|
DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, usbredirparser_warning),
|
||||||
DEFINE_PROP_STRING("filter", USBRedirDevice, filter_str),
|
DEFINE_PROP_STRING("filter", USBRedirDevice, filter_str),
|
||||||
DEFINE_PROP_INT32("bootindex", USBRedirDevice, bootindex, -1),
|
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
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);
|
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 = {
|
static const TypeInfo usbredir_dev_info = {
|
||||||
.name = "usb-redir",
|
.name = "usb-redir",
|
||||||
.parent = TYPE_USB_DEVICE,
|
.parent = TYPE_USB_DEVICE,
|
||||||
.instance_size = sizeof(USBRedirDevice),
|
.instance_size = sizeof(USBRedirDevice),
|
||||||
.class_init = usbredir_class_initfn,
|
.class_init = usbredir_class_initfn,
|
||||||
|
.instance_init = usbredir_instance_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void usbredir_register_types(void)
|
static void usbredir_register_types(void)
|
||||||
|
|
|
@ -1115,6 +1115,8 @@ static void virtio_blk_pci_instance_init(Object *obj)
|
||||||
TYPE_VIRTIO_BLK);
|
TYPE_VIRTIO_BLK);
|
||||||
object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread",
|
object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread",
|
||||||
&error_abort);
|
&error_abort);
|
||||||
|
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
|
||||||
|
"bootindex", &error_abort);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo virtio_blk_pci_info = {
|
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),
|
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
|
||||||
TYPE_VIRTIO_NET);
|
TYPE_VIRTIO_NET);
|
||||||
|
object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
|
||||||
|
"bootindex", &error_abort);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo virtio_net_pci_info = {
|
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), \
|
_conf.physical_block_size, 512), \
|
||||||
DEFINE_PROP_UINT16("min_io_size", _state, _conf.min_io_size, 0), \
|
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_UINT32("opt_io_size", _state, _conf.opt_io_size, 0), \
|
||||||
DEFINE_PROP_INT32("bootindex", _state, _conf.bootindex, -1), \
|
|
||||||
DEFINE_PROP_UINT32("discard_granularity", _state, \
|
DEFINE_PROP_UINT32("discard_granularity", _state, \
|
||||||
_conf.discard_granularity, -1)
|
_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,
|
void fw_cfg_add_file_callback(FWCfgState *s, const char *filename,
|
||||||
FWCfgReadCallback callback, void *callback_opaque,
|
FWCfgReadCallback callback, void *callback_opaque,
|
||||||
void *data, size_t len);
|
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,
|
FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
|
||||||
hwaddr crl_addr, hwaddr data_addr);
|
hwaddr crl_addr, hwaddr data_addr);
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,7 @@ typedef struct NICConf {
|
||||||
#define DEFINE_NIC_PROPERTIES(_state, _conf) \
|
#define DEFINE_NIC_PROPERTIES(_state, _conf) \
|
||||||
DEFINE_PROP_MACADDR("mac", _state, _conf.macaddr), \
|
DEFINE_PROP_MACADDR("mac", _state, _conf.macaddr), \
|
||||||
DEFINE_PROP_VLAN("vlan", _state, _conf.peers), \
|
DEFINE_PROP_VLAN("vlan", _state, _conf.peers), \
|
||||||
DEFINE_PROP_NETDEV("netdev", _state, _conf.peers), \
|
DEFINE_PROP_NETDEV("netdev", _state, _conf.peers)
|
||||||
DEFINE_PROP_INT32("bootindex", _state, _conf.bootindex, -1)
|
|
||||||
|
|
||||||
|
|
||||||
/* Net clients */
|
/* Net clients */
|
||||||
|
|
|
@ -130,6 +130,7 @@ extern int no_shutdown;
|
||||||
extern int semihosting_enabled;
|
extern int semihosting_enabled;
|
||||||
extern int old_param;
|
extern int old_param;
|
||||||
extern int boot_menu;
|
extern int boot_menu;
|
||||||
|
extern bool boot_strict;
|
||||||
extern uint8_t *boot_splash_filedata;
|
extern uint8_t *boot_splash_filedata;
|
||||||
extern size_t boot_splash_filedata_size;
|
extern size_t boot_splash_filedata_size;
|
||||||
extern uint8_t qemu_extra_params_fw[2];
|
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);
|
char *get_boot_devices_list(size_t *size, bool ignore_suffixes);
|
||||||
|
|
||||||
DeviceState *get_boot_device(uint32_t position);
|
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);
|
QemuOpts *qemu_get_machine_opts(void);
|
||||||
|
|
||||||
|
|
118
vl.c
118
vl.c
|
@ -180,23 +180,12 @@ int ctrl_grab = 0;
|
||||||
unsigned int nb_prom_envs = 0;
|
unsigned int nb_prom_envs = 0;
|
||||||
const char *prom_envs[MAX_PROM_ENVS];
|
const char *prom_envs[MAX_PROM_ENVS];
|
||||||
int boot_menu;
|
int boot_menu;
|
||||||
static bool boot_strict;
|
bool boot_strict;
|
||||||
uint8_t *boot_splash_filedata;
|
uint8_t *boot_splash_filedata;
|
||||||
size_t boot_splash_filedata_size;
|
size_t boot_splash_filedata_size;
|
||||||
uint8_t qemu_extra_params_fw[2];
|
uint8_t qemu_extra_params_fw[2];
|
||||||
|
|
||||||
int icount_align_option;
|
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 nb_numa_nodes;
|
||||||
int max_numa_nodeid;
|
int max_numa_nodeid;
|
||||||
|
@ -1246,111 +1235,6 @@ static void restore_boot_order(void *opaque)
|
||||||
g_free(normal_boot_order);
|
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 = {
|
static QemuOptsList qemu_smp_opts = {
|
||||||
.name = "smp-opts",
|
.name = "smp-opts",
|
||||||
.implied_opt_name = "cpus",
|
.implied_opt_name = "cpus",
|
||||||
|
|
Loading…
Reference in New Issue