From a46622fd07edc6fd3c66f8ab79b4782a78b115f3 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Fri, 7 Mar 2014 15:37:40 +1100 Subject: spapr_hcall: Fix little-endian resource handling in H_SET_MODE This changes resource code definitions to ones used in the host kernel. This fixes H_SET_MODE_RESOURCE_LE (switch between big endian and little endian) to sync registers from KVM before changing LPCR value. This adds a set_spr() helper to update an SPR in a CPU's context to avoid possible races and makes use of it to change LPCR. Signed-off-by: Alexey Kardashevskiy Reviewed-by: Greg Kurz Signed-off-by: Andreas Färber --- include/hw/ppc/spapr.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 449fc7ca2d..5fdac1e009 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -153,8 +153,13 @@ typedef struct sPAPREnvironment { #define H_PP1 (1ULL<<(63-62)) #define H_PP2 (1ULL<<(63-63)) -/* H_SET_MODE flags */ -#define H_SET_MODE_ENDIAN 4 +/* Values for 2nd argument to H_SET_MODE */ +#define H_SET_MODE_RESOURCE_SET_CIABR 1 +#define H_SET_MODE_RESOURCE_SET_DAWR 2 +#define H_SET_MODE_RESOURCE_ADDR_TRANS_MODE 3 +#define H_SET_MODE_RESOURCE_LE 4 + +/* Flags for H_SET_MODE_RESOURCE_LE */ #define H_SET_MODE_ENDIAN_BIG 0 #define H_SET_MODE_ENDIAN_LITTLE 1 -- cgit v1.2.3-55-g7522 From 30e32af7466841f5fc08a5339e2184884a7bc6f3 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Mon, 17 Mar 2014 13:40:22 +1100 Subject: vl.c: Extend get_boot_devices_list() to ignore suffixes As suffixes do not make sense for sPAPR's device tree and there is no way to filter them out on the BusState::get_fw_dev_path() level, let's add an ability for the external caller to specify whether to apply suffixes or not. We could handle suffixes in SLOF (ignored for now) but this would require serious rework in the node opening code in SLOF, which has no obvious benefit for the currently emulated sPAPR machine. Signed-off-by: Alexey Kardashevskiy Signed-off-by: Andreas Färber --- hw/nvram/fw_cfg.c | 2 +- include/sysemu/sysemu.h | 2 +- vl.c | 8 +++++--- 3 files changed, 7 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index cb36dc2d0c..282341ac1b 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -504,7 +504,7 @@ static void fw_cfg_machine_ready(struct Notifier *n, void *data) { size_t len; FWCfgState *s = container_of(n, FWCfgState, machine_ready); - char *bootindex = get_boot_devices_list(&len); + char *bootindex = get_boot_devices_list(&len, false); fw_cfg_add_file(s, "bootorder", (uint8_t*)bootindex, len); } diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index c01304d39a..3915ce3204 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -186,7 +186,7 @@ void rtc_change_mon_event(struct tm *tm); void add_boot_device_path(int32_t bootindex, DeviceState *dev, const char *suffix); -char *get_boot_devices_list(size_t *size); +char *get_boot_devices_list(size_t *size, bool ignore_suffixes); DeviceState *get_boot_device(uint32_t position); diff --git a/vl.c b/vl.c index f0fe48b106..1adc8f4e40 100644 --- a/vl.c +++ b/vl.c @@ -1209,7 +1209,7 @@ DeviceState *get_boot_device(uint32_t position) * memory pointed by "size" is assigned total length of the array in bytes * */ -char *get_boot_devices_list(size_t *size) +char *get_boot_devices_list(size_t *size, bool ignore_suffixes) { FWBootEntry *i; size_t total = 0; @@ -1224,7 +1224,7 @@ char *get_boot_devices_list(size_t *size) assert(devpath); } - if (i->suffix && devpath) { + if (i->suffix && !ignore_suffixes && devpath) { size_t bootpathlen = strlen(devpath) + strlen(i->suffix) + 1; bootpath = g_malloc(bootpathlen); @@ -1232,9 +1232,11 @@ char *get_boot_devices_list(size_t *size) g_free(devpath); } else if (devpath) { bootpath = devpath; - } else { + } else if (!ignore_suffixes) { assert(i->suffix); bootpath = g_strdup(i->suffix); + } else { + bootpath = g_strdup(""); } if (total) { -- cgit v1.2.3-55-g7522 From 6b1566cbe372660c77ca4aa7aa0071fa30f5f930 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 17 Mar 2014 13:40:23 +1100 Subject: qdev: Introduce FWPathProvider interface QEMU supports firmware names for all devices in the QEMU tree but some architectures expect some parts of firmware path names in different format. This introduces a firmware-pathname-change interface definition. If some machines needs to redefine the firmware path format, it has to add the TYPE_FW_PATH_PROVIDER interface to an object that is above the device on the QOM tree (typically /machine). Signed-off-by: Paolo Bonzini Signed-off-by: Alexey Kardashevskiy Signed-off-by: Andreas Färber --- hw/core/Makefile.objs | 1 + hw/core/fw-path-provider.c | 51 +++++++++++++++++++++++++++++++++++++++++++ hw/core/qdev.c | 18 ++++++++++++++- include/hw/fw-path-provider.h | 47 +++++++++++++++++++++++++++++++++++++++ tests/Makefile | 1 + 5 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 hw/core/fw-path-provider.c create mode 100644 include/hw/fw-path-provider.h (limited to 'include') diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs index 981593c7e6..5377d052e9 100644 --- a/hw/core/Makefile.objs +++ b/hw/core/Makefile.objs @@ -1,5 +1,6 @@ # core qdev-related obj files, also used by *-user: common-obj-y += qdev.o qdev-properties.o +common-obj-y += fw-path-provider.o # irq.o needed for qdev GPIO handling: common-obj-y += irq.o common-obj-y += hotplug.o diff --git a/hw/core/fw-path-provider.c b/hw/core/fw-path-provider.c new file mode 100644 index 0000000000..b11715733d --- /dev/null +++ b/hw/core/fw-path-provider.c @@ -0,0 +1,51 @@ +/* + * Firmware patch provider class and helpers. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "hw/fw-path-provider.h" + +char *fw_path_provider_get_dev_path(FWPathProvider *p, BusState *bus, + DeviceState *dev) +{ + FWPathProviderClass *k = FW_PATH_PROVIDER_GET_CLASS(p); + + return k->get_dev_path(p, bus, dev); +} + +char *fw_path_provider_try_get_dev_path(Object *o, BusState *bus, + DeviceState *dev) +{ + FWPathProvider *p = (FWPathProvider *) + object_dynamic_cast(o, TYPE_FW_PATH_PROVIDER); + + if (p) { + return fw_path_provider_get_dev_path(p, bus, dev); + } + + return NULL; +} + +static const TypeInfo fw_path_provider_info = { + .name = TYPE_FW_PATH_PROVIDER, + .parent = TYPE_INTERFACE, + .class_size = sizeof(FWPathProviderClass), +}; + +static void fw_path_provider_register_types(void) +{ + type_register_static(&fw_path_provider_info); +} + +type_init(fw_path_provider_register_types) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 9f0a522ee8..cd09cd4d95 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -26,6 +26,7 @@ this API directly. */ #include "hw/qdev.h" +#include "hw/fw-path-provider.h" #include "sysemu/sysemu.h" #include "qapi/error.h" #include "qapi/qmp/qerror.h" @@ -568,6 +569,18 @@ static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev) return NULL; } +static char *qdev_get_fw_dev_path_from_handler(BusState *bus, DeviceState *dev) +{ + Object *obj = OBJECT(dev); + char *d = NULL; + + while (!d && obj->parent) { + obj = obj->parent; + d = fw_path_provider_try_get_dev_path(obj, bus, dev); + } + return d; +} + static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size) { int l = 0; @@ -575,7 +588,10 @@ static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size) if (dev && dev->parent_bus) { char *d; l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size); - d = bus_get_fw_dev_path(dev->parent_bus, dev); + d = qdev_get_fw_dev_path_from_handler(dev->parent_bus, dev); + if (!d) { + d = bus_get_fw_dev_path(dev->parent_bus, dev); + } if (d) { l += snprintf(p + l, size - l, "%s", d); g_free(d); diff --git a/include/hw/fw-path-provider.h b/include/hw/fw-path-provider.h new file mode 100644 index 0000000000..301834972c --- /dev/null +++ b/include/hw/fw-path-provider.h @@ -0,0 +1,47 @@ +/* + * Firmware patch provider class and helpers definitions. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef FW_PATH_PROVIDER_H +#define FW_PATH_PROVIDER_H 1 + +#include "qemu-common.h" +#include "qom/object.h" + +#define TYPE_FW_PATH_PROVIDER "fw-path-provider" + +#define FW_PATH_PROVIDER_CLASS(klass) \ + OBJECT_CLASS_CHECK(FWPathProviderClass, (klass), TYPE_FW_PATH_PROVIDER) +#define FW_PATH_PROVIDER_GET_CLASS(obj) \ + OBJECT_GET_CLASS(FWPathProviderClass, (obj), TYPE_FW_PATH_PROVIDER) +#define FW_PATH_PROVIDER(obj) \ + INTERFACE_CHECK(FWPathProvider, (obj), TYPE_FW_PATH_PROVIDER) + +typedef struct FWPathProvider { + Object parent_obj; +} FWPathProvider; + +typedef struct FWPathProviderClass { + InterfaceClass parent_class; + + char *(*get_dev_path)(FWPathProvider *p, BusState *bus, DeviceState *dev); +} FWPathProviderClass; + +char *fw_path_provider_get_dev_path(FWPathProvider *p, BusState *bus, + DeviceState *dev); +char *fw_path_provider_try_get_dev_path(Object *o, BusState *bus, + DeviceState *dev); + +#endif /* FW_PATH_PROVIDER_H */ diff --git a/tests/Makefile b/tests/Makefile index 471b4c8785..2d021fb16d 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -206,6 +206,7 @@ tests/test-int128$(EXESUF): tests/test-int128.o tests/test-qdev-global-props$(EXESUF): tests/test-qdev-global-props.o \ hw/core/qdev.o hw/core/qdev-properties.o hw/core/hotplug.o\ hw/core/irq.o \ + hw/core/fw-path-provider.o \ $(qom-core-obj) \ $(test-qapi-obj-y) \ libqemuutil.a libqemustub.a -- cgit v1.2.3-55-g7522