Compare commits

...

34 Commits

Author SHA1 Message Date
Gonglei
54086fe5d2 bootindex: change fprintf to error_report
The function may be called by qmp command, we should
report error message to the caller.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 10:46:01 +02:00
Gonglei
4aca8a8178 bootindex: delete bootindex when device is removed
Device should be removed from global boot list when
it is hot-unplugged.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 10:46:01 +02:00
Gonglei
d749e10c4f bootindex: move calling add_boot_device_patch to bootindex setter function
On this way, we can assure the new bootindex take effect
during vm rebooting.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 10:46:01 +02:00
Gonglei
d2b186f96d ide: add calling add_boot_device_patch in bootindex setter function
On this way, we can assure the new bootindex take effect
during vm rebooting. Meanwhile set the initial value of
bootindex to -1.

Because ide devcies's unit property maybe
do not initialize when set_bootindex function is called,
so that we don't know its suffix. So we have to save the
call add_boot_device_path() on ide realize/init function.
When we want to change bootindex during vm rebooting, we
can call it in setter function.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 10:45:51 +02:00
Gonglei
33739c7129 nvma: ide: add bootindex to qom property
At present, nvma cannot boot. However, it provides already
a bootindex property, so change bootindex to qom for nvma
device, but not call add_boot_device_path.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 10:27:52 +02:00
Gonglei
89f0762dde usb-storage: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Because usb-storage rely on scsi-disk which is created
in usb_msg_realize_storage(), so we should store the SCSIDevice
pointer in MSDState struct. Only in this way, we can change
the global boot_order_list when we want to change the bootindex
during vm rebooting by calling object_property_set_int(Object(SCSIDevice),).

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 10:27:07 +02:00
Gonglei
aeb98ddc50 virtio-blk: alias bootindex property explicitly for virt-blk-pci/ccw/s390
Since the "bootindex" property is a QOM property and not a qdev property
now, we must alias it explicitly for virtio-blk-pci, as well as CCW and
s390-virtio.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:55 +02:00
Gonglei
8dece34f26 block: remove bootindex property from qdev to qom
Remove bootindex form qdev property to qom, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:55 +02:00
Gonglei
3342ec324a virtio-blk: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:55 +02:00
Gonglei
4556363087 ide: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:55 +02:00
Gonglei
44fb6337b9 scsi: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:55 +02:00
Gonglei
81782b6a78 isa-fdc: remove bootindexA/B property from qdev to qom
Remove bootindexA/B form qdev property to qom, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:55 +02:00
Gonglei
295857994c redirect: remove bootindex property from qdev to qom
Remove bootindex form qdev property to qom, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:55 +02:00
Gonglei
abc5b3bfe1 vfio: remove bootindex property from qdev to qom
Remove bootindex form qdev property to qom, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:55 +02:00
Gonglei
7f6014af27 pci-assign: remove bootindex property from qdev to qom
Remove bootindex form qdev property to qom, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:54 +02:00
Gonglei
e6adae52b1 host-libusb: remove bootindex property from qdev to qom
Remove bootindex form qdev property to qom, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:54 +02:00
Gonglei
0cf63c3e35 virtio-net: alias bootindex property explicitly for virt-net-pci/ccw/s390
Since the "bootindex" property is a QOM property and not a qdev property
now, we must alias it explicitly for virtio-net-pci, as well as CCW and
s390-virtio.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:54 +02:00
Gonglei
45e8a9e123 net: remove bootindex property from qdev to qom
Remove bootindex form qdev property to qom, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:54 +02:00
Gonglei
c11f4bc9ff usb-net: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:54 +02:00
Gonglei
e25524efb0 vmxnet3: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:54 +02:00
Gonglei
dfe79cf268 spapr_lian: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:54 +02:00
Gonglei
afd7c850f5 rtl8139: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:54 +02:00
Gonglei
ea3b3511cd pcnet: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:54 +02:00
Gonglei
6cb0851d62 ne2000: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

At present, isa_ne2000 device does not support to boot
os, so we register two seprate qom getter/setter functions.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:54 +02:00
Gonglei
7317bb1782 eepro100: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:54 +02:00
Gonglei
5df3bf623d e1000: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:54 +02:00
Gonglei
aa4197c323 virtio-net: add bootindex to qom property
Add a qom property with the same name 'bootindex',
when we remove it form qdev property, things will
continue to work just fine, and we can use qom features
which are not supported by qdev property.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:53 +02:00
Gonglei
12da309778 bootindex: add a setter/getter functions wrapper for bootindex property
when we remove bootindex form qdev.property to qom.property,
we can use those functions set/get bootindex property for all
correlative devices. Meanwhile set the initial value of
bootindex to -1.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:47 +02:00
Gonglei
a598f2ffc2 bootindex: support to set a existent device's bootindex to -1
When set a device's bootindex to -1, we remove it from global
fw_boot_order list.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:47 +02:00
Gonglei
e614b54b93 bootindex: rework add_boot_device_path function
Add the function of updating bootindex about fw_boot_order list
in add_boot_device_path(). We should delete the old one if a
device has existed in global fw_boot_order list.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:47 +02:00
Gonglei
bdbb5b1706 fw_cfg: add fw_cfg_machine_reset function
We must assure that the changed bootindex can take effect
when guest is rebooted. So we introduce fw_cfg_machine_reset(),
which change the fw_cfg file's bootindex data using the new
global fw_boot_order list.

Signed-off-by: Chenliang <chenliang88@huawei.com>
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:52:15 +02:00
Gonglei
9d27572d62 bootindex: add del_boot_device_path function
Introduce del_boot_device_path() to clean up fw_cfg content when
hot-unplugging a device that refers to a bootindex or update a
existent devcie's bootindex.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Chenliang <chenliang88@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:49:48 +02:00
Gonglei
694fb857ab bootindex: add check bootindex function
Determine whether a given bootindex exists or not.
If exists, we report an error.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:49:48 +02:00
Gonglei
bc74112f7e bootdevice: move bootdevice related code to new file bootdevice.c
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-10-15 09:49:48 +02:00
36 changed files with 690 additions and 166 deletions

View File

@@ -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

258
bootdevice.c Normal file
View File

@@ -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);
}

View File

@@ -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 ={

View File

@@ -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)

View File

@@ -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[] = {

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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);
}

View File

@@ -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);
}
}

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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 */
/*

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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[] = {

View File

@@ -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)

View File

@@ -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,

View File

@@ -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)

View File

@@ -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)

View File

@@ -231,7 +231,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);
@@ -2016,6 +2017,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,
@@ -2023,6 +2034,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)

View File

@@ -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(),
};

View File

@@ -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(),
};

View File

@@ -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);
}
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)
@@ -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)

View File

@@ -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 {
@@ -634,6 +636,7 @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
}
s->bus.qbus.allow_hotplug = 0;
usb_msd_handle_reset(dev);
s->scsi_dev = scsi_dev;
if (bdrv_key_required(bs)) {
if (cur_mon) {
@@ -767,6 +770,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 = {

View File

@@ -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)

View File

@@ -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)

View File

@@ -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 = {

View File

@@ -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)

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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);

118
vl.c
View File

@@ -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",