aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS13
-rw-r--r--block/nbd.c25
-rw-r--r--blockdev-nbd.c6
-rw-r--r--crypto/tlssession.c6
-rw-r--r--docs/tools/qemu-nbd.rst13
-rw-r--r--hw/arm/Kconfig1
-rw-r--r--hw/arm/aspeed.c100
-rw-r--r--hw/arm/aspeed_ast2600.c2
-rw-r--r--hw/arm/aspeed_soc.c2
-rw-r--r--hw/audio/cs4231a.c2
-rw-r--r--hw/audio/gus.c2
-rw-r--r--hw/audio/sb16.c2
-rw-r--r--hw/block/fdc-isa.c2
-rw-r--r--hw/block/m25p80.c1
-rw-r--r--hw/char/parallel.c2
-rw-r--r--hw/char/serial-isa.c2
-rw-r--r--hw/gpio/aspeed_gpio.c2
-rw-r--r--hw/i2c/pmbus_device.c112
-rw-r--r--hw/ide/isa.c2
-rw-r--r--hw/input/pckbd.c26
-rw-r--r--hw/ipmi/isa_ipmi_bt.c2
-rw-r--r--hw/ipmi/isa_ipmi_kcs.c2
-rw-r--r--hw/isa/isa-bus.c37
-rw-r--r--hw/isa/piix4.c56
-rw-r--r--hw/mips/gt64xxx_pci.c80
-rw-r--r--hw/mips/malta.c7
-rw-r--r--hw/net/ne2000-isa.c2
-rw-r--r--hw/rtc/m48t59-isa.c9
-rw-r--r--hw/rtc/mc146818rtc.c13
-rw-r--r--hw/sensor/Kconfig4
-rw-r--r--hw/sensor/isl_pmbus_vr.c279
-rw-r--r--hw/sensor/meson.build1
-rw-r--r--hw/ssi/aspeed_smc.c53
-rw-r--r--hw/tpm/tpm_tis_isa.c2
-rw-r--r--include/block/nbd.h3
-rw-r--r--include/hw/i2c/pmbus_device.h25
-rw-r--r--include/hw/isa/isa.h3
-rw-r--r--include/hw/mips/mips.h3
-rw-r--r--include/hw/rtc/mc146818rtc.h1
-rw-r--r--include/hw/sensor/isl_pmbus_vr.h52
-rw-r--r--include/hw/southbridge/piix.h2
-rw-r--r--include/hw/ssi/aspeed_smc.h3
-rw-r--r--linux-user/ppc/cpu_loop.c3
-rw-r--r--linux-user/signal.c2
-rw-r--r--nbd/client-connection.c12
-rw-r--r--nbd/server.c13
-rw-r--r--pc-bios/openbios-ppcbin697088 -> 677196 bytes
-rw-r--r--pc-bios/openbios-sparc32bin382048 -> 382080 bytes
-rw-r--r--pc-bios/openbios-sparc64bin1593408 -> 1593408 bytes
-rw-r--r--qapi/block-core.json3
-rw-r--r--qemu-io-cmds.c16
-rw-r--r--qemu-nbd.c25
m---------roms/openbios0
-rw-r--r--target/mips/cpu.c11
-rw-r--r--target/mips/cpu.h9
-rw-r--r--target/mips/internal.h9
-rw-r--r--tests/avocado/linux_ssh_mips_malta.py3
-rw-r--r--tests/qemu-iotests/172.out26
-rwxr-xr-xtests/qemu-iotests/23399
-rw-r--r--tests/qemu-iotests/233.out58
-rwxr-xr-xtests/qemu-iotests/2416
-rw-r--r--tests/qemu-iotests/241.out6
-rw-r--r--tests/qemu-iotests/common.filter9
-rw-r--r--tests/qemu-iotests/common.tls31
-rw-r--r--tests/qemu-iotests/testrunner.py6
-rw-r--r--tests/qtest/isl_pmbus_vr-test.c474
-rw-r--r--tests/qtest/meson.build1
-rw-r--r--tests/tcg/ppc64le/signal_save_restore_xer.c8
68 files changed, 1463 insertions, 329 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 38d1ac8..f2e9ce1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3137,6 +3137,19 @@ F: include/hw/i2c/smbus_master.h
F: include/hw/i2c/smbus_slave.h
F: include/hw/i2c/smbus_eeprom.h
+PMBus
+M: Titus Rwantare <titusr@google.com>
+S: Maintained
+F: hw/i2c/pmbus_device.c
+F: hw/sensor/adm1272.c
+F: hw/sensor/isl_pmbus_vr.c
+F: hw/sensor/max34451.c
+F: include/hw/i2c/pmbus_device.h
+F: include/hw/sensor/isl_pmbus_vr.h
+F: tests/qtest/adm1272-test.c
+F: tests/qtest/max34451-test.c
+F: tests/qtest/isl_pmbus_vr-test.c
+
Firmware schema specifications
M: Philippe Mathieu-Daudé <f4bug@amsat.org>
R: Daniel P. Berrange <berrange@redhat.com>
diff --git a/block/nbd.c b/block/nbd.c
index 146d256..34b9429 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -90,9 +90,10 @@ typedef struct BDRVNBDState {
uint32_t reconnect_delay;
uint32_t open_timeout;
SocketAddress *saddr;
- char *export, *tlscredsid;
+ char *export;
+ char *tlscredsid;
QCryptoTLSCreds *tlscreds;
- const char *hostname;
+ char *tlshostname;
char *x_dirty_bitmap;
bool alloc_depth;
@@ -121,6 +122,8 @@ static void nbd_clear_bdrvstate(BlockDriverState *bs)
s->export = NULL;
g_free(s->tlscredsid);
s->tlscredsid = NULL;
+ g_free(s->tlshostname);
+ s->tlshostname = NULL;
g_free(s->x_dirty_bitmap);
s->x_dirty_bitmap = NULL;
}
@@ -1766,6 +1769,11 @@ static QemuOptsList nbd_runtime_opts = {
.help = "ID of the TLS credentials to use",
},
{
+ .name = "tls-hostname",
+ .type = QEMU_OPT_STRING,
+ .help = "Override hostname for validating TLS x509 certificate",
+ },
+ {
.name = "x-dirty-bitmap",
.type = QEMU_OPT_STRING,
.help = "experimental: expose named dirty bitmap in place of "
@@ -1831,12 +1839,11 @@ static int nbd_process_options(BlockDriverState *bs, QDict *options,
goto error;
}
- /* TODO SOCKET_ADDRESS_KIND_FD where fd has AF_INET or AF_INET6 */
- if (s->saddr->type != SOCKET_ADDRESS_TYPE_INET) {
- error_setg(errp, "TLS only supported over IP sockets");
- goto error;
+ s->tlshostname = g_strdup(qemu_opt_get(opts, "tls-hostname"));
+ if (!s->tlshostname &&
+ s->saddr->type == SOCKET_ADDRESS_TYPE_INET) {
+ s->tlshostname = g_strdup(s->saddr->u.inet.host);
}
- s->hostname = s->saddr->u.inet.host;
}
s->x_dirty_bitmap = g_strdup(qemu_opt_get(opts, "x-dirty-bitmap"));
@@ -1876,7 +1883,8 @@ static int nbd_open(BlockDriverState *bs, QDict *options, int flags,
}
s->conn = nbd_client_connection_new(s->saddr, true, s->export,
- s->x_dirty_bitmap, s->tlscreds);
+ s->x_dirty_bitmap, s->tlscreds,
+ s->tlshostname);
if (s->open_timeout) {
nbd_client_connection_enable_retry(s->conn);
@@ -2037,6 +2045,7 @@ static const char *const nbd_strong_runtime_opts[] = {
"port",
"export",
"tls-creds",
+ "tls-hostname",
"server.",
NULL
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index bdfa7ed..9840d25 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -148,12 +148,6 @@ void nbd_server_start(SocketAddress *addr, const char *tls_creds,
if (!nbd_server->tlscreds) {
goto error;
}
-
- /* TODO SOCKET_ADDRESS_TYPE_FD where fd has AF_INET or AF_INET6 */
- if (addr->type != SOCKET_ADDRESS_TYPE_INET) {
- error_setg(errp, "TLS is only supported with IPv4/IPv6");
- goto error;
- }
}
nbd_server->tlsauthz = g_strdup(tls_authz);
diff --git a/crypto/tlssession.c b/crypto/tlssession.c
index a8db8c7..b302d83 100644
--- a/crypto/tlssession.c
+++ b/crypto/tlssession.c
@@ -373,6 +373,12 @@ qcrypto_tls_session_check_certificate(QCryptoTLSSession *session,
session->hostname);
goto error;
}
+ } else {
+ if (session->creds->endpoint ==
+ QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT) {
+ error_setg(errp, "No hostname for certificate validation");
+ goto error;
+ }
}
}
diff --git a/docs/tools/qemu-nbd.rst b/docs/tools/qemu-nbd.rst
index 6031f96..2b8c90c 100644
--- a/docs/tools/qemu-nbd.rst
+++ b/docs/tools/qemu-nbd.rst
@@ -169,6 +169,19 @@ driver options if ``--image-opts`` is specified.
option; or provide the credentials needed for connecting as a client
in list mode.
+.. option:: --tls-hostname=hostname
+
+ When validating an x509 certificate received over a TLS connection,
+ the hostname that the NBD client used to connect will be checked
+ against information in the server provided certificate. Sometimes
+ it might be required to override the hostname used to perform this
+ check. For example, if the NBD client is using a tunnel from localhost
+ to connect to the remote server, the `--tls-hostname` option should
+ be used to set the officially expected hostname of the remote NBD
+ server. This can also be used if accessing NBD over a UNIX socket
+ where there is no inherent hostname available. This is only permitted
+ when acting as a NBD client with the `--list` option.
+
.. option:: --fork
Fork off the server process and exit the parent once the server is running.
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 6945330..97f3b38 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -400,6 +400,7 @@ config NPCM7XX
select SMBUS
select AT24C # EEPROM
select MAX34451
+ select ISL_PMBUS_VR
select PL310 # cache controller
select PMBUS
select SERIAL
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 11558b3..d205384 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -167,6 +167,11 @@ struct AspeedMachineState {
#define FUJI_BMC_HW_STRAP1 0x00000000
#define FUJI_BMC_HW_STRAP2 0x00000000
+/* Bletchley hardware value */
+/* TODO: Leave same as EVB for now. */
+#define BLETCHLEY_BMC_HW_STRAP1 AST2600_EVB_HW_STRAP1
+#define BLETCHLEY_BMC_HW_STRAP2 AST2600_EVB_HW_STRAP2
+
/*
* The max ram region is for firmwares that scan the address space
* with load/store to guess how much RAM the SoC has.
@@ -246,7 +251,7 @@ static void write_boot_rom(DriveInfo *dinfo, hwaddr addr, size_t rom_size,
Error **errp)
{
BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
- uint8_t *storage;
+ g_autofree void *storage = NULL;
int64_t size;
/* The block backend size should have already been 'validated' by
@@ -262,23 +267,25 @@ static void write_boot_rom(DriveInfo *dinfo, hwaddr addr, size_t rom_size,
rom_size = size;
}
- storage = g_new0(uint8_t, rom_size);
+ storage = g_malloc0(rom_size);
if (blk_pread(blk, 0, storage, rom_size) < 0) {
error_setg(errp, "failed to read the initial flash content");
return;
}
rom_add_blob_fixed("aspeed.boot_rom", storage, rom_size, addr);
- g_free(storage);
}
-static void aspeed_board_init_flashes(AspeedSMCState *s,
- const char *flashtype,
- int unit0)
+static void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,
+ unsigned int count, int unit0)
{
- int i ;
+ int i;
+
+ if (!flashtype) {
+ return;
+ }
- for (i = 0; i < s->num_cs; ++i) {
+ for (i = 0; i < count; ++i) {
DriveInfo *dinfo = drive_get(IF_MTD, 0, unit0 + i);
qemu_irq cs_line;
DeviceState *dev;
@@ -345,8 +352,6 @@ static void aspeed_machine_init(MachineState *machine)
&error_abort);
object_property_set_int(OBJECT(&bmc->soc), "hw-strap2", amc->hw_strap2,
&error_abort);
- object_property_set_int(OBJECT(&bmc->soc), "num-cs", amc->num_cs,
- &error_abort);
object_property_set_link(OBJECT(&bmc->soc), "dram",
OBJECT(machine->ram), &error_abort);
if (machine->kernel_filename) {
@@ -374,10 +379,10 @@ static void aspeed_machine_init(MachineState *machine)
aspeed_board_init_flashes(&bmc->soc.fmc,
bmc->fmc_model ? bmc->fmc_model : amc->fmc_model,
- 0);
+ amc->num_cs, 0);
aspeed_board_init_flashes(&bmc->soc.spi[0],
bmc->spi_model ? bmc->spi_model : amc->spi_model,
- bmc->soc.fmc.num_cs);
+ 1, amc->num_cs);
/* Install first FMC flash content as a boot rom. */
if (drive0) {
@@ -897,6 +902,54 @@ static void fuji_bmc_i2c_init(AspeedMachineState *bmc)
}
}
+#define TYPE_TMP421 "tmp421"
+
+static void bletchley_bmc_i2c_init(AspeedMachineState *bmc)
+{
+ AspeedSoCState *soc = &bmc->soc;
+ I2CBus *i2c[13] = {};
+ for (int i = 0; i < 13; i++) {
+ if ((i == 8) || (i == 11)) {
+ continue;
+ }
+ i2c[i] = aspeed_i2c_get_bus(&soc->i2c, i);
+ }
+
+ /* Bus 0 - 5 all have the same config. */
+ for (int i = 0; i < 6; i++) {
+ /* Missing model: ti,ina230 @ 0x45 */
+ /* Missing model: mps,mp5023 @ 0x40 */
+ i2c_slave_create_simple(i2c[i], TYPE_TMP421, 0x4f);
+ /* Missing model: nxp,pca9539 @ 0x76, but PCA9552 works enough */
+ i2c_slave_create_simple(i2c[i], TYPE_PCA9552, 0x76);
+ i2c_slave_create_simple(i2c[i], TYPE_PCA9552, 0x67);
+ /* Missing model: fsc,fusb302 @ 0x22 */
+ }
+
+ /* Bus 6 */
+ at24c_eeprom_init(i2c[6], 0x56, 65536);
+ /* Missing model: nxp,pcf85263 @ 0x51 , but ds1338 works enough */
+ i2c_slave_create_simple(i2c[6], "ds1338", 0x51);
+
+
+ /* Bus 7 */
+ at24c_eeprom_init(i2c[7], 0x54, 65536);
+
+ /* Bus 9 */
+ i2c_slave_create_simple(i2c[9], TYPE_TMP421, 0x4f);
+
+ /* Bus 10 */
+ i2c_slave_create_simple(i2c[10], TYPE_TMP421, 0x4f);
+ /* Missing model: ti,hdc1080 @ 0x40 */
+ i2c_slave_create_simple(i2c[10], TYPE_PCA9552, 0x67);
+
+ /* Bus 12 */
+ /* Missing model: adi,adm1278 @ 0x11 */
+ i2c_slave_create_simple(i2c[12], TYPE_TMP421, 0x4c);
+ i2c_slave_create_simple(i2c[12], TYPE_TMP421, 0x4d);
+ i2c_slave_create_simple(i2c[12], TYPE_PCA9552, 0x67);
+}
+
static bool aspeed_get_mmio_exec(Object *obj, Error **errp)
{
return ASPEED_MACHINE(obj)->mmio_exec;
@@ -1220,6 +1273,25 @@ static void aspeed_machine_fuji_class_init(ObjectClass *oc, void *data)
aspeed_soc_num_cpus(amc->soc_name);
};
+static void aspeed_machine_bletchley_class_init(ObjectClass *oc, void *data)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
+
+ mc->desc = "Facebook Bletchley BMC (Cortex-A7)";
+ amc->soc_name = "ast2600-a3";
+ amc->hw_strap1 = BLETCHLEY_BMC_HW_STRAP1;
+ amc->hw_strap2 = BLETCHLEY_BMC_HW_STRAP2;
+ amc->fmc_model = "w25q01jvq";
+ amc->spi_model = NULL;
+ amc->num_cs = 2;
+ amc->macs_mask = ASPEED_MAC2_ON;
+ amc->i2c_init = bletchley_bmc_i2c_init;
+ mc->default_ram_size = 512 * MiB;
+ mc->default_cpus = mc->min_cpus = mc->max_cpus =
+ aspeed_soc_num_cpus(amc->soc_name);
+}
+
static const TypeInfo aspeed_machine_types[] = {
{
.name = MACHINE_TYPE_NAME("palmetto-bmc"),
@@ -1274,6 +1346,10 @@ static const TypeInfo aspeed_machine_types[] = {
.parent = TYPE_ASPEED_MACHINE,
.class_init = aspeed_machine_fuji_class_init,
}, {
+ .name = MACHINE_TYPE_NAME("bletchley-bmc"),
+ .parent = TYPE_ASPEED_MACHINE,
+ .class_init = aspeed_machine_bletchley_class_init,
+ }, {
.name = TYPE_ASPEED_MACHINE,
.parent = TYPE_MACHINE,
.instance_size = sizeof(AspeedMachineState),
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index 21cd334..c1e15e3 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -163,7 +163,6 @@ static void aspeed_soc_ast2600_init(Object *obj)
snprintf(typename, sizeof(typename), "aspeed.fmc-%s", socname);
object_initialize_child(obj, "fmc", &s->fmc, typename);
- object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs");
for (i = 0; i < sc->spis_num; i++) {
snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
@@ -383,7 +382,6 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
for (i = 0; i < sc->spis_num; i++) {
object_property_set_link(OBJECT(&s->spi[i]), "dram",
OBJECT(s->dram_mr), &error_abort);
- object_property_set_int(OBJECT(&s->spi[i]), "num-cs", 1, &error_abort);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), errp)) {
return;
}
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
index 7d53cf2..58714cb 100644
--- a/hw/arm/aspeed_soc.c
+++ b/hw/arm/aspeed_soc.c
@@ -170,7 +170,6 @@ static void aspeed_soc_init(Object *obj)
snprintf(typename, sizeof(typename), "aspeed.fmc-%s", socname);
object_initialize_child(obj, "fmc", &s->fmc, typename);
- object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs");
for (i = 0; i < sc->spis_num; i++) {
snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
@@ -327,7 +326,6 @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
/* SPI */
for (i = 0; i < sc->spis_num; i++) {
- object_property_set_int(OBJECT(&s->spi[i]), "num-cs", 1, &error_abort);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->spi[i]), errp)) {
return;
}
diff --git a/hw/audio/cs4231a.c b/hw/audio/cs4231a.c
index 7d60ce6..0723e39 100644
--- a/hw/audio/cs4231a.c
+++ b/hw/audio/cs4231a.c
@@ -677,7 +677,7 @@ static void cs4231a_realizefn (DeviceState *dev, Error **errp)
return;
}
- isa_init_irq(d, &s->pic, s->irq);
+ s->pic = isa_get_irq(d, s->irq);
k = ISADMA_GET_CLASS(s->isa_dma);
k->register_channel(s->isa_dma, s->dma, cs_dma_read, s);
diff --git a/hw/audio/gus.c b/hw/audio/gus.c
index e8719ee..42f010b 100644
--- a/hw/audio/gus.c
+++ b/hw/audio/gus.c
@@ -282,7 +282,7 @@ static void gus_realizefn (DeviceState *dev, Error **errp)
s->emu.himemaddr = s->himem;
s->emu.gusdatapos = s->emu.himemaddr + 1024 * 1024 + 32;
s->emu.opaque = s;
- isa_init_irq (d, &s->pic, s->emu.gusirq);
+ s->pic = isa_get_irq(d, s->emu.gusirq);
AUD_set_active_out (s->voice, 1);
}
diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c
index 60f1f75..2215386 100644
--- a/hw/audio/sb16.c
+++ b/hw/audio/sb16.c
@@ -1408,7 +1408,7 @@ static void sb16_realizefn (DeviceState *dev, Error **errp)
return;
}
- isa_init_irq (isadev, &s->pic, s->irq);
+ s->pic = isa_get_irq(isadev, s->irq);
s->mixer_regs[0x80] = magic_of_irq (s->irq);
s->mixer_regs[0x81] = (1 << s->dma) | (1 << s->hdma);
diff --git a/hw/block/fdc-isa.c b/hw/block/fdc-isa.c
index ab663dc..fa20450 100644
--- a/hw/block/fdc-isa.c
+++ b/hw/block/fdc-isa.c
@@ -94,7 +94,7 @@ static void isabus_fdc_realize(DeviceState *dev, Error **errp)
isa->iobase, fdc_portio_list, fdctrl,
"fdc");
- isa_init_irq(isadev, &fdctrl->irq, isa->irq);
+ fdctrl->irq = isa_get_irq(isadev, isa->irq);
fdctrl->dma_chann = isa->dma;
if (fdctrl->dma_chann != -1) {
IsaDmaClass *k;
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index c6bf3c6..7d3d8b1 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -340,6 +340,7 @@ static const FlashPartInfo known_devices[] = {
{ INFO("w25q80bl", 0xef4014, 0, 64 << 10, 16, ER_4K) },
{ INFO("w25q256", 0xef4019, 0, 64 << 10, 512, ER_4K) },
{ INFO("w25q512jv", 0xef4020, 0, 64 << 10, 1024, ER_4K) },
+ { INFO("w25q01jvq", 0xef4021, 0, 64 << 10, 2048, ER_4K) },
};
typedef enum {
diff --git a/hw/char/parallel.c b/hw/char/parallel.c
index b45e67b..adb9bd9 100644
--- a/hw/char/parallel.c
+++ b/hw/char/parallel.c
@@ -553,7 +553,7 @@ static void parallel_isa_realizefn(DeviceState *dev, Error **errp)
index++;
base = isa->iobase;
- isa_init_irq(isadev, &s->irq, isa->isairq);
+ s->irq = isa_get_irq(isadev, isa->isairq);
qemu_register_reset(parallel_reset, s);
qemu_chr_fe_set_handlers(&s->chr, parallel_can_receive, NULL,
diff --git a/hw/char/serial-isa.c b/hw/char/serial-isa.c
index 1b8b303..7a7ed23 100644
--- a/hw/char/serial-isa.c
+++ b/hw/char/serial-isa.c
@@ -75,7 +75,7 @@ static void serial_isa_realizefn(DeviceState *dev, Error **errp)
}
index++;
- isa_init_irq(isadev, &s->irq, isa->isairq);
+ s->irq = isa_get_irq(isadev, isa->isairq);
qdev_realize(DEVICE(s), NULL, errp);
qdev_set_legacy_instance_id(dev, isa->iobase, 3);
diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c
index 911d21c..c63634d 100644
--- a/hw/gpio/aspeed_gpio.c
+++ b/hw/gpio/aspeed_gpio.c
@@ -571,7 +571,7 @@ static uint64_t aspeed_gpio_read(void *opaque, hwaddr offset, uint32_t size)
qemu_log_mask(LOG_GUEST_ERROR, "%s: no getter for offset 0x%"
HWADDR_PRIx"\n", __func__, offset);
return 0;
- };
+ }
}
static void aspeed_gpio_write(void *opaque, hwaddr offset, uint64_t data,
diff --git a/hw/i2c/pmbus_device.c b/hw/i2c/pmbus_device.c
index 24f8f52..62885fa 100644
--- a/hw/i2c/pmbus_device.c
+++ b/hw/i2c/pmbus_device.c
@@ -28,6 +28,24 @@ uint32_t pmbus_direct_mode2data(PMBusCoefficients c, uint16_t value)
return x;
}
+uint16_t pmbus_data2linear_mode(uint16_t value, int exp)
+{
+ /* L = D * 2^(-e) */
+ if (exp < 0) {
+ return value << (-exp);
+ }
+ return value >> exp;
+}
+
+uint16_t pmbus_linear_mode2data(uint16_t value, int exp)
+{
+ /* D = L * 2^e */
+ if (exp < 0) {
+ return value >> (-exp);
+ }
+ return value << exp;
+}
+
void pmbus_send(PMBusDevice *pmdev, const uint8_t *data, uint16_t len)
{
if (pmdev->out_buf_len + len > SMBUS_DATA_MAX_LEN) {
@@ -89,16 +107,16 @@ void pmbus_send_string(PMBusDevice *pmdev, const char *data)
}
-static uint64_t pmbus_receive_uint(const uint8_t *buf, uint8_t len)
+static uint64_t pmbus_receive_uint(PMBusDevice *pmdev)
{
uint64_t ret = 0;
/* Exclude command code from return value */
- buf++;
- len--;
+ pmdev->in_buf++;
+ pmdev->in_buf_len--;
- for (int i = len - 1; i >= 0; i--) {
- ret = ret << 8 | buf[i];
+ for (int i = pmdev->in_buf_len - 1; i >= 0; i--) {
+ ret = ret << 8 | pmdev->in_buf[i];
}
return ret;
}
@@ -110,7 +128,7 @@ uint8_t pmbus_receive8(PMBusDevice *pmdev)
"%s: length mismatch. Expected 1 byte, got %d bytes\n",
__func__, pmdev->in_buf_len - 1);
}
- return pmbus_receive_uint(pmdev->in_buf, pmdev->in_buf_len);
+ return pmbus_receive_uint(pmdev);
}
uint16_t pmbus_receive16(PMBusDevice *pmdev)
@@ -120,7 +138,7 @@ uint16_t pmbus_receive16(PMBusDevice *pmdev)
"%s: length mismatch. Expected 2 bytes, got %d bytes\n",
__func__, pmdev->in_buf_len - 1);
}
- return pmbus_receive_uint(pmdev->in_buf, pmdev->in_buf_len);
+ return pmbus_receive_uint(pmdev);
}
uint32_t pmbus_receive32(PMBusDevice *pmdev)
@@ -130,7 +148,7 @@ uint32_t pmbus_receive32(PMBusDevice *pmdev)
"%s: length mismatch. Expected 4 bytes, got %d bytes\n",
__func__, pmdev->in_buf_len - 1);
}
- return pmbus_receive_uint(pmdev->in_buf, pmdev->in_buf_len);
+ return pmbus_receive_uint(pmdev);
}
uint64_t pmbus_receive64(PMBusDevice *pmdev)
@@ -140,7 +158,7 @@ uint64_t pmbus_receive64(PMBusDevice *pmdev)
"%s: length mismatch. Expected 8 bytes, got %d bytes\n",
__func__, pmdev->in_buf_len - 1);
}
- return pmbus_receive_uint(pmdev->in_buf, pmdev->in_buf_len);
+ return pmbus_receive_uint(pmdev);
}
static uint8_t pmbus_out_buf_pop(PMBusDevice *pmdev)
@@ -149,7 +167,7 @@ static uint8_t pmbus_out_buf_pop(PMBusDevice *pmdev)
qemu_log_mask(LOG_GUEST_ERROR,
"%s: tried to read from empty buffer",
__func__);
- return 0xFF;
+ return PMBUS_ERR_BYTE;
}
uint8_t data = pmdev->out_buf[pmdev->out_buf_len - 1];
pmdev->out_buf_len--;
@@ -243,18 +261,47 @@ void pmbus_check_limits(PMBusDevice *pmdev)
}
}
+/* assert the status_cml error upon receipt of malformed command */
+static void pmbus_cml_error(PMBusDevice *pmdev)
+{
+ for (int i = 0; i < pmdev->num_pages; i++) {
+ pmdev->pages[i].status_word |= PMBUS_STATUS_CML;
+ pmdev->pages[i].status_cml |= PB_CML_FAULT_INVALID_CMD;
+ }
+}
+
static uint8_t pmbus_receive_byte(SMBusDevice *smd)
{
PMBusDevice *pmdev = PMBUS_DEVICE(smd);
PMBusDeviceClass *pmdc = PMBUS_DEVICE_GET_CLASS(pmdev);
- uint8_t ret = 0xFF;
- uint8_t index = pmdev->page;
+ uint8_t ret = PMBUS_ERR_BYTE;
+ uint8_t index;
if (pmdev->out_buf_len != 0) {
ret = pmbus_out_buf_pop(pmdev);
return ret;
}
+ /*
+ * Reading from all pages will return the value from page 0,
+ * this is unspecified behaviour in general.
+ */
+ if (pmdev->page == PB_ALL_PAGES) {
+ index = 0;
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: tried to read from all pages\n",
+ __func__);
+ pmbus_cml_error(pmdev);
+ } else if (pmdev->page > pmdev->num_pages - 1) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: page %d is out of range\n",
+ __func__, pmdev->page);
+ pmbus_cml_error(pmdev);
+ return PMBUS_ERR_BYTE;
+ } else {
+ index = pmdev->page;
+ }
+
switch (pmdev->code) {
case PMBUS_PAGE:
pmbus_send8(pmdev, pmdev->page);
@@ -278,6 +325,11 @@ static uint8_t pmbus_receive_byte(SMBusDevice *smd)
case PMBUS_CAPABILITY:
pmbus_send8(pmdev, pmdev->capability);
+ if (pmdev->capability & BIT(7)) {
+ qemu_log_mask(LOG_UNIMP,
+ "%s: PEC is enabled but not yet supported.\n",
+ __func__);
+ }
break;
case PMBUS_VOUT_MODE: /* R/W byte */
@@ -368,6 +420,14 @@ static uint8_t pmbus_receive_byte(SMBusDevice *smd)
}
break;
+ case PMBUS_VOUT_MIN: /* R/W word */
+ if (pmdev->pages[index].page_flags & PB_HAS_VOUT_RATING) {
+ pmbus_send16(pmdev, pmdev->pages[index].vout_min);
+ } else {
+ goto passthough;
+ }
+ break;
+
/* TODO: implement coefficients support */
case PMBUS_POUT_MAX: /* R/W word */
@@ -708,6 +768,10 @@ static uint8_t pmbus_receive_byte(SMBusDevice *smd)
pmbus_send8(pmdev, pmdev->pages[index].status_other);
break;
+ case PMBUS_STATUS_MFR_SPECIFIC: /* R/W byte */
+ pmbus_send8(pmdev, pmdev->pages[index].status_mfr_specific);
+ break;
+
case PMBUS_READ_EIN: /* Read-Only block 5 bytes */
if (pmdev->pages[index].page_flags & PB_HAS_EIN) {
pmbus_send(pmdev, pmdev->pages[index].read_ein, 5);
@@ -1007,7 +1071,7 @@ static int pmbus_write_data(SMBusDevice *smd, uint8_t *buf, uint8_t len)
if (len == 0) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: writing empty data\n", __func__);
- return -1;
+ return PMBUS_ERR_BYTE;
}
if (!pmdev->pages) { /* allocate memory for pages on first use */
@@ -1026,6 +1090,7 @@ static int pmbus_write_data(SMBusDevice *smd, uint8_t *buf, uint8_t len)
pmdev->page = pmbus_receive8(pmdev);
return 0;
}
+
/* loop through all the pages when 0xFF is received */
if (pmdev->page == PB_ALL_PAGES) {
for (int i = 0; i < pmdev->num_pages; i++) {
@@ -1036,6 +1101,15 @@ static int pmbus_write_data(SMBusDevice *smd, uint8_t *buf, uint8_t len)
return 0;
}
+ if (pmdev->page > pmdev->num_pages - 1) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: page %u is out of range\n",
+ __func__, pmdev->page);
+ pmdev->page = 0; /* undefined behaviour - reset to page 0 */
+ pmbus_cml_error(pmdev);
+ return PMBUS_ERR_BYTE;
+ }
+
index = pmdev->page;
switch (pmdev->code) {
@@ -1149,6 +1223,14 @@ static int pmbus_write_data(SMBusDevice *smd, uint8_t *buf, uint8_t len)
}
break;
+ case PMBUS_VOUT_MIN: /* R/W word */
+ if (pmdev->pages[index].page_flags & PB_HAS_VOUT_RATING) {
+ pmdev->pages[index].vout_min = pmbus_receive16(pmdev);
+ } else {
+ goto passthrough;
+ }
+ break;
+
case PMBUS_POUT_MAX: /* R/W word */
if (pmdev->pages[index].page_flags & PB_HAS_VOUT) {
pmdev->pages[index].pout_max = pmbus_receive16(pmdev);
@@ -1482,6 +1564,10 @@ static int pmbus_write_data(SMBusDevice *smd, uint8_t *buf, uint8_t len)
pmdev->pages[index].status_other = pmbus_receive8(pmdev);
break;
+ case PMBUS_STATUS_MFR_SPECIFIC: /* R/W byte */
+ pmdev->pages[index].status_mfr_specific = pmbus_receive8(pmdev);
+ break;
+
case PMBUS_PAGE_PLUS_READ: /* Block Read-only */
case PMBUS_CAPABILITY: /* Read-Only byte */
case PMBUS_COEFFICIENTS: /* Read-only block 5 bytes */
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
index 24bbde2..8bedbd1 100644
--- a/hw/ide/isa.c
+++ b/hw/ide/isa.c
@@ -75,7 +75,7 @@ static void isa_ide_realizefn(DeviceState *dev, Error **errp)
ide_bus_init(&s->bus, sizeof(s->bus), dev, 0, 2);
ide_init_ioport(&s->bus, isadev, s->iobase, s->iobase2);
- isa_init_irq(isadev, &s->irq, s->isairq);
+ s->irq = isa_get_irq(isadev, s->isairq);
ide_init2(&s->bus, s->irq);
vmstate_register(VMSTATE_IF(dev), 0, &vmstate_ide_isa, s);
ide_register_restart_cb(&s->bus);
diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c
index baba62f..1773db0 100644
--- a/hw/input/pckbd.c
+++ b/hw/input/pckbd.c
@@ -26,6 +26,7 @@
#include "qemu/error-report.h"
#include "qemu/log.h"
#include "qemu/timer.h"
+#include "qapi/error.h"
#include "hw/isa/isa.h"
#include "migration/vmstate.h"
#include "hw/acpi/aml-build.h"
@@ -671,6 +672,8 @@ struct ISAKBDState {
KBDState kbd;
bool kbd_throttle;
MemoryRegion io[2];
+ uint8_t kbd_irq;
+ uint8_t mouse_irq;
};
void i8042_isa_mouse_fake_event(ISAKBDState *isa)
@@ -734,8 +737,20 @@ static void i8042_realizefn(DeviceState *dev, Error **errp)
ISAKBDState *isa_s = I8042(dev);
KBDState *s = &isa_s->kbd;
- isa_init_irq(isadev, &s->irq_kbd, 1);
- isa_init_irq(isadev, &s->irq_mouse, 12);
+ if (isa_s->kbd_irq >= ISA_NUM_IRQS) {
+ error_setg(errp, "Maximum value for \"kbd-irq\" is: %u",
+ ISA_NUM_IRQS - 1);
+ return;
+ }
+
+ if (isa_s->mouse_irq >= ISA_NUM_IRQS) {
+ error_setg(errp, "Maximum value for \"mouse-irq\" is: %u",
+ ISA_NUM_IRQS - 1);
+ return;
+ }
+
+ s->irq_kbd = isa_get_irq(isadev, isa_s->kbd_irq);
+ s->irq_mouse = isa_get_irq(isadev, isa_s->mouse_irq);
isa_register_ioport(isadev, isa_s->io + 0, 0x60);
isa_register_ioport(isadev, isa_s->io + 1, 0x64);
@@ -754,6 +769,7 @@ static void i8042_realizefn(DeviceState *dev, Error **errp)
static void i8042_build_aml(ISADevice *isadev, Aml *scope)
{
+ ISAKBDState *isa_s = I8042(isadev);
Aml *kbd;
Aml *mou;
Aml *crs;
@@ -761,7 +777,7 @@ static void i8042_build_aml(ISADevice *isadev, Aml *scope)
crs = aml_resource_template();
aml_append(crs, aml_io(AML_DECODE16, 0x0060, 0x0060, 0x01, 0x01));
aml_append(crs, aml_io(AML_DECODE16, 0x0064, 0x0064, 0x01, 0x01));
- aml_append(crs, aml_irq_no_flags(1));
+ aml_append(crs, aml_irq_no_flags(isa_s->kbd_irq));
kbd = aml_device("KBD");
aml_append(kbd, aml_name_decl("_HID", aml_eisaid("PNP0303")));
@@ -769,7 +785,7 @@ static void i8042_build_aml(ISADevice *isadev, Aml *scope)
aml_append(kbd, aml_name_decl("_CRS", crs));
crs = aml_resource_template();
- aml_append(crs, aml_irq_no_flags(12));
+ aml_append(crs, aml_irq_no_flags(isa_s->mouse_irq));
mou = aml_device("MOU");
aml_append(mou, aml_name_decl("_HID", aml_eisaid("PNP0F13")));
@@ -783,6 +799,8 @@ static void i8042_build_aml(ISADevice *isadev, Aml *scope)
static Property i8042_properties[] = {
DEFINE_PROP_BOOL("extended-state", ISAKBDState, kbd.extended_state, true),
DEFINE_PROP_BOOL("kbd-throttle", ISAKBDState, kbd_throttle, false),
+ DEFINE_PROP_UINT8("kbd-irq", ISAKBDState, kbd_irq, 1),
+ DEFINE_PROP_UINT8("mouse-irq", ISAKBDState, mouse_irq, 12),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/ipmi/isa_ipmi_bt.c b/hw/ipmi/isa_ipmi_bt.c
index 02625eb..88aa734 100644
--- a/hw/ipmi/isa_ipmi_bt.c
+++ b/hw/ipmi/isa_ipmi_bt.c
@@ -92,7 +92,7 @@ static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp)
}
if (iib->isairq > 0) {
- isa_init_irq(isadev, &iib->irq, iib->isairq);
+ iib->irq = isa_get_irq(isadev, iib->isairq);
iib->bt.use_irq = 1;
iib->bt.raise_irq = isa_ipmi_bt_raise_irq;
iib->bt.lower_irq = isa_ipmi_bt_lower_irq;
diff --git a/hw/ipmi/isa_ipmi_kcs.c b/hw/ipmi/isa_ipmi_kcs.c
index 3b23ad0..afabb95 100644
--- a/hw/ipmi/isa_ipmi_kcs.c
+++ b/hw/ipmi/isa_ipmi_kcs.c
@@ -91,7 +91,7 @@ static void ipmi_isa_realize(DeviceState *dev, Error **errp)
}
if (iik->isairq > 0) {
- isa_init_irq(isadev, &iik->irq, iik->isairq);
+ iik->irq = isa_get_irq(isadev, iik->isairq);
iik->kcs.use_irq = 1;
iik->kcs.raise_irq = isa_ipmi_kcs_raise_irq;
iik->kcs.lower_irq = isa_ipmi_kcs_lower_irq;
diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
index 6c31398..0ad1c5f 100644
--- a/hw/isa/isa-bus.c
+++ b/hw/isa/isa-bus.c
@@ -21,21 +21,18 @@
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qapi/error.h"
-#include "monitor/monitor.h"
#include "hw/sysbus.h"
#include "sysemu/sysemu.h"
#include "hw/isa/isa.h"
static ISABus *isabus;
-static void isabus_dev_print(Monitor *mon, DeviceState *dev, int indent);
static char *isabus_get_fw_dev_path(DeviceState *dev);
static void isa_bus_class_init(ObjectClass *klass, void *data)
{
BusClass *k = BUS_CLASS(klass);
- k->print_dev = isabus_dev_print;
k->get_fw_dev_path = isabus_get_fw_dev_path;
}
@@ -88,19 +85,9 @@ qemu_irq isa_get_irq(ISADevice *dev, unsigned isairq)
return isabus->irqs[isairq];
}
-void isa_init_irq(ISADevice *dev, qemu_irq *p, unsigned isairq)
-{
- assert(dev->nirqs < ARRAY_SIZE(dev->isairq));
- assert(isairq < ISA_NUM_IRQS);
- dev->isairq[dev->nirqs] = isairq;
- *p = isa_get_irq(dev, isairq);
- dev->nirqs++;
-}
-
void isa_connect_gpio_out(ISADevice *isadev, int gpioirq, unsigned isairq)
{
- qemu_irq irq;
- isa_init_irq(isadev, &irq, isairq);
+ qemu_irq irq = isa_get_irq(isadev, isairq);
qdev_connect_gpio_out(DEVICE(isadev), gpioirq, irq);
}
@@ -153,14 +140,6 @@ int isa_register_portio_list(ISADevice *dev,
return 0;
}
-static void isa_device_init(Object *obj)
-{
- ISADevice *dev = ISA_DEVICE(obj);
-
- dev->isairq[0] = -1;
- dev->isairq[1] = -1;
-}
-
ISADevice *isa_new(const char *name)
{
return ISA_DEVICE(qdev_new(name));
@@ -222,19 +201,6 @@ void isa_build_aml(ISABus *bus, Aml *scope)
}
}
-static void isabus_dev_print(Monitor *mon, DeviceState *dev, int indent)
-{
- ISADevice *d = ISA_DEVICE(dev);
-
- if (d->isairq[1] != -1) {
- monitor_printf(mon, "%*sisa irqs %d,%d\n", indent, "",
- d->isairq[0], d->isairq[1]);
- } else if (d->isairq[0] != -1) {
- monitor_printf(mon, "%*sisa irq %d\n", indent, "",
- d->isairq[0]);
- }
-}
-
static void isabus_bridge_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -260,7 +226,6 @@ static const TypeInfo isa_device_type_info = {
.name = TYPE_ISA_DEVICE,
.parent = TYPE_DEVICE,
.instance_size = sizeof(ISADevice),
- .instance_init = isa_device_init,
.abstract = true,
.class_size = sizeof(ISADeviceClass),
.class_init = isa_device_class_init,
diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 0fe7b69..8607e0a 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -39,8 +39,6 @@
#include "sysemu/runstate.h"
#include "qom/object.h"
-PCIDevice *piix4_dev;
-
struct PIIX4State {
PCIDevice dev;
qemu_irq cpu_intr;
@@ -54,6 +52,27 @@ struct PIIX4State {
OBJECT_DECLARE_SIMPLE_TYPE(PIIX4State, PIIX4_PCI_DEVICE)
+static void piix4_set_irq(void *opaque, int irq_num, int level)
+{
+ int i, pic_irq, pic_level;
+ PIIX4State *s = opaque;
+ PCIBus *bus = pci_get_bus(&s->dev);
+
+ /* now we change the pic irq level according to the piix irq mappings */
+ /* XXX: optimize */
+ pic_irq = s->dev.config[PIIX_PIRQCA + irq_num];
+ if (pic_irq < ISA_NUM_IRQS) {
+ /* The pic level is the logical OR of all the PCI irqs mapped to it. */
+ pic_level = 0;
+ for (i = 0; i < PIIX_NUM_PIRQS; i++) {
+ if (pic_irq == s->dev.config[PIIX_PIRQCA + i]) {
+ pic_level |= pci_bus_get_irq_level(bus, i);
+ }
+ }
+ qemu_set_irq(s->isa[pic_irq], pic_level);
+ }
+}
+
static void piix4_isa_reset(DeviceState *dev)
{
PIIX4State *d = PIIX4_PCI_DEVICE(dev);
@@ -197,9 +216,7 @@ static void piix4_realize(PCIDevice *dev, Error **errp)
if (!qdev_realize(DEVICE(&s->rtc), BUS(isa_bus), errp)) {
return;
}
- isa_init_irq(ISA_DEVICE(&s->rtc), &s->rtc.irq, RTC_ISA_IRQ);
-
- piix4_dev = dev;
+ s->rtc.irq = isa_get_irq(ISA_DEVICE(&s->rtc), s->rtc.isairq);
}
static void piix4_init(Object *obj)
@@ -248,8 +265,34 @@ static void piix4_register_types(void)
type_init(piix4_register_types)
+static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
+{
+ int slot;
+
+ slot = PCI_SLOT(pci_dev->devfn);
+
+ switch (slot) {
+ /* PIIX4 USB */
+ case 10:
+ return 3;
+ /* AMD 79C973 Ethernet */
+ case 11:
+ return 1;
+ /* Crystal 4281 Sound */
+ case 12:
+ return 2;
+ /* PCI slot 1 to 4 */
+ case 18 ... 21:
+ return ((slot - 18) + irq_num) & 0x03;
+ /* Unknown device, don't do any translation */
+ default:
+ return irq_num;
+ }
+}
+
DeviceState *piix4_create(PCIBus *pci_bus, ISABus **isa_bus, I2CBus **smbus)
{
+ PIIX4State *s;
PCIDevice *pci;
DeviceState *dev;
int devfn = PCI_DEVFN(10, 0);
@@ -257,6 +300,7 @@ DeviceState *piix4_create(PCIBus *pci_bus, ISABus **isa_bus, I2CBus **smbus)
pci = pci_create_simple_multifunction(pci_bus, devfn, true,
TYPE_PIIX4_PCI_DEVICE);
dev = DEVICE(pci);
+ s = PIIX4_PCI_DEVICE(pci);
if (isa_bus) {
*isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0"));
}
@@ -271,5 +315,7 @@ DeviceState *piix4_create(PCIBus *pci_bus, ISABus **isa_bus, I2CBus **smbus)
NULL, 0, NULL);
}
+ pci_bus_irqs(pci_bus, piix4_set_irq, pci_slot_get_pirq, s, PIIX_NUM_PIRQS);
+
return dev;
}
diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c
index c7480bd..e0ff1b5 100644
--- a/hw/mips/gt64xxx_pci.c
+++ b/hw/mips/gt64xxx_pci.c
@@ -26,10 +26,8 @@
#include "qapi/error.h"
#include "qemu/units.h"
#include "qemu/log.h"
-#include "hw/mips/mips.h"
#include "hw/pci/pci.h"
#include "hw/pci/pci_host.h"
-#include "hw/southbridge/piix.h"
#include "migration/vmstate.h"
#include "hw/intc/i8259.h"
#include "hw/irq.h"
@@ -981,56 +979,6 @@ static const MemoryRegionOps isd_mem_ops = {
},
};
-static int gt64120_pci_map_irq(PCIDevice *pci_dev, int irq_num)
-{
- int slot;
-
- slot = PCI_SLOT(pci_dev->devfn);
-
- switch (slot) {
- /* PIIX4 USB */
- case 10:
- return 3;
- /* AMD 79C973 Ethernet */
- case 11:
- return 1;
- /* Crystal 4281 Sound */
- case 12:
- return 2;
- /* PCI slot 1 to 4 */
- case 18 ... 21:
- return ((slot - 18) + irq_num) & 0x03;
- /* Unknown device, don't do any translation */
- default:
- return irq_num;
- }
-}
-
-static int pci_irq_levels[4];
-
-static void gt64120_pci_set_irq(void *opaque, int irq_num, int level)
-{
- int i, pic_irq, pic_level;
- qemu_irq *pic = opaque;
-
- pci_irq_levels[irq_num] = level;
-
- /* now we change the pic irq level according to the piix irq mappings */
- /* XXX: optimize */
- pic_irq = piix4_dev->config[PIIX_PIRQCA + irq_num];
- if (pic_irq < 16) {
- /* The pic level is the logical OR of all the PCI irqs mapped to it. */
- pic_level = 0;
- for (i = 0; i < 4; i++) {
- if (pic_irq == piix4_dev->config[PIIX_PIRQCA + i]) {
- pic_level |= pci_irq_levels[i];
- }
- }
- qemu_set_irq(pic[pic_irq], pic_level);
- }
-}
-
-
static void gt64120_reset(DeviceState *dev)
{
GT64120State *s = GT64120_PCI_HOST_BRIDGE(dev);
@@ -1202,32 +1150,18 @@ static void gt64120_reset(DeviceState *dev)
static void gt64120_realize(DeviceState *dev, Error **errp)
{
GT64120State *s = GT64120_PCI_HOST_BRIDGE(dev);
+ PCIHostState *phb = PCI_HOST_BRIDGE(dev);
memory_region_init_io(&s->ISD_mem, OBJECT(dev), &isd_mem_ops, s,
"gt64120-isd", 0x1000);
-}
-
-PCIBus *gt64120_register(qemu_irq *pic)
-{
- GT64120State *d;
- PCIHostState *phb;
- DeviceState *dev;
-
- dev = qdev_new(TYPE_GT64120_PCI_HOST_BRIDGE);
- d = GT64120_PCI_HOST_BRIDGE(dev);
- phb = PCI_HOST_BRIDGE(dev);
- memory_region_init(&d->pci0_mem, OBJECT(dev), "pci0-mem", 4 * GiB);
- address_space_init(&d->pci0_mem_as, &d->pci0_mem, "pci0-mem");
- phb->bus = pci_register_root_bus(dev, "pci",
- gt64120_pci_set_irq, gt64120_pci_map_irq,
- pic,
- &d->pci0_mem,
- get_system_io(),
- PCI_DEVFN(18, 0), 4, TYPE_PCI_BUS);
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+ memory_region_init(&s->pci0_mem, OBJECT(dev), "pci0-mem", 4 * GiB);
+ address_space_init(&s->pci0_mem_as, &s->pci0_mem, "pci0-mem");
+ phb->bus = pci_root_bus_new(dev, "pci",
+ &s->pci0_mem,
+ get_system_io(),
+ PCI_DEVFN(18, 0), TYPE_PCI_BUS);
pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "gt64120_pci");
- return phb->bus;
}
static void gt64120_pci_realize(PCIDevice *d, Error **errp)
diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index b770b8d..55037eb 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -97,7 +97,6 @@ struct MaltaState {
Clock *cpuclk;
MIPSCPSState cps;
- qemu_irq i8259[ISA_NUM_IRQS];
};
static struct _loaderparams {
@@ -1391,7 +1390,8 @@ void mips_malta_init(MachineState *machine)
stl_p(memory_region_get_ram_ptr(bios_copy) + 0x10, 0x00000420);
/* Northbridge */
- pci_bus = gt64120_register(s->i8259);
+ dev = sysbus_create_simple("gt64120", -1, NULL);
+ pci_bus = PCI_BUS(qdev_get_child_bus(dev, "pci"));
/*
* The whole address space decoded by the GT-64120A doesn't generate
* exception when accessing invalid memory. Create an empty slot to
@@ -1404,9 +1404,6 @@ void mips_malta_init(MachineState *machine)
/* Interrupt controller */
qdev_connect_gpio_out_named(dev, "intr", 0, i8259_irq);
- for (int i = 0; i < ISA_NUM_IRQS; i++) {
- s->i8259[i] = qdev_get_gpio_in_named(dev, "isa", i);
- }
/* generate SPD EEPROM data */
generate_eeprom_spd(&smbus_eeprom_buf[0 * 256], ram_size);
diff --git a/hw/net/ne2000-isa.c b/hw/net/ne2000-isa.c
index dd6f6e3..6ced677 100644
--- a/hw/net/ne2000-isa.c
+++ b/hw/net/ne2000-isa.c
@@ -68,7 +68,7 @@ static void isa_ne2000_realizefn(DeviceState *dev, Error **errp)
ne2000_setup_io(s, DEVICE(isadev), 0x20);
isa_register_ioport(isadev, &s->io, isa->iobase);
- isa_init_irq(isadev, &s->irq, isa->isairq);
+ s->irq = isa_get_irq(isadev, isa->isairq);
qemu_macaddr_default_if_unset(&s->c.macaddr);
ne2000_reset(s);
diff --git a/hw/rtc/m48t59-isa.c b/hw/rtc/m48t59-isa.c
index dc21fb1..e61f7ec 100644
--- a/hw/rtc/m48t59-isa.c
+++ b/hw/rtc/m48t59-isa.c
@@ -42,6 +42,7 @@ struct M48txxISAState {
ISADevice parent_obj;
M48t59State state;
uint32_t io_base;
+ uint8_t isairq;
MemoryRegion io;
};
@@ -79,6 +80,7 @@ static void m48txx_isa_toggle_lock(Nvram *obj, int lock)
static Property m48t59_isa_properties[] = {
DEFINE_PROP_INT32("base-year", M48txxISAState, state.base_year, 0),
DEFINE_PROP_UINT32("iobase", M48txxISAState, io_base, 0x74),
+ DEFINE_PROP_UINT8("irq", M48txxISAState, isairq, 8),
DEFINE_PROP_END_OF_LIST(),
};
@@ -97,9 +99,14 @@ static void m48t59_isa_realize(DeviceState *dev, Error **errp)
M48txxISAState *d = M48TXX_ISA(dev);
M48t59State *s = &d->state;
+ if (d->isairq >= ISA_NUM_IRQS) {
+ error_setg(errp, "Maximum value for \"irq\" is: %u", ISA_NUM_IRQS - 1);
+ return;
+ }
+
s->model = u->info.model;
s->size = u->info.size;
- isa_init_irq(isadev, &s->IRQ, 8);
+ s->IRQ = isa_get_irq(isadev, d->isairq);
m48t59_realize_common(s, errp);
memory_region_init_io(&d->io, OBJECT(dev), &m48t59_io_ops, s, "m48t59", 4);
if (d->io_base != 0) {
diff --git a/hw/rtc/mc146818rtc.c b/hw/rtc/mc146818rtc.c
index ac9a60c..f235c2d 100644
--- a/hw/rtc/mc146818rtc.c
+++ b/hw/rtc/mc146818rtc.c
@@ -912,6 +912,11 @@ static void rtc_realizefn(DeviceState *dev, Error **errp)
s->base_year = 0;
}
+ if (s->isairq >= ISA_NUM_IRQS) {
+ error_setg(errp, "Maximum value for \"irq\" is: %u", ISA_NUM_IRQS - 1);
+ return;
+ }
+
rtc_set_date_from_host(isadev);
switch (s->lost_tick_policy) {
@@ -957,15 +962,17 @@ ISADevice *mc146818_rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq)
{
DeviceState *dev;
ISADevice *isadev;
+ RTCState *s;
isadev = isa_new(TYPE_MC146818_RTC);
dev = DEVICE(isadev);
+ s = MC146818_RTC(isadev);
qdev_prop_set_int32(dev, "base_year", base_year);
isa_realize_and_unref(isadev, bus, &error_fatal);
if (intercept_irq) {
qdev_connect_gpio_out(dev, 0, intercept_irq);
} else {
- isa_connect_gpio_out(isadev, 0, RTC_ISA_IRQ);
+ isa_connect_gpio_out(isadev, 0, s->isairq);
}
object_property_add_alias(qdev_get_machine(), "rtc-time", OBJECT(isadev),
@@ -976,6 +983,7 @@ ISADevice *mc146818_rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq)
static Property mc146818rtc_properties[] = {
DEFINE_PROP_INT32("base_year", RTCState, base_year, 1980),
+ DEFINE_PROP_UINT8("irq", RTCState, isairq, RTC_ISA_IRQ),
DEFINE_PROP_LOSTTICKPOLICY("lost_tick_policy", RTCState,
lost_tick_policy, LOST_TICK_POLICY_DISCARD),
DEFINE_PROP_END_OF_LIST(),
@@ -1011,6 +1019,7 @@ static void rtc_reset_hold(Object *obj)
static void rtc_build_aml(ISADevice *isadev, Aml *scope)
{
+ RTCState *s = MC146818_RTC(isadev);
Aml *dev;
Aml *crs;
@@ -1021,7 +1030,7 @@ static void rtc_build_aml(ISADevice *isadev, Aml *scope)
crs = aml_resource_template();
aml_append(crs, aml_io(AML_DECODE16, RTC_ISA_BASE, RTC_ISA_BASE,
0x01, 0x08));
- aml_append(crs, aml_irq_no_flags(RTC_ISA_IRQ));
+ aml_append(crs, aml_irq_no_flags(s->isairq));
dev = aml_device("RTC");
aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0B00")));
diff --git a/hw/sensor/Kconfig b/hw/sensor/Kconfig
index 215944d..df392e7 100644
--- a/hw/sensor/Kconfig
+++ b/hw/sensor/Kconfig
@@ -30,3 +30,7 @@ config LSM303DLHC_MAG
bool
depends on I2C
default y if I2C_DEVICES
+
+config ISL_PMBUS_VR
+ bool
+ depends on PMBUS
diff --git a/hw/sensor/isl_pmbus_vr.c b/hw/sensor/isl_pmbus_vr.c
new file mode 100644
index 0000000..e11e028
--- /dev/null
+++ b/hw/sensor/isl_pmbus_vr.c
@@ -0,0 +1,279 @@
+/*
+ * PMBus device for Renesas Digital Multiphase Voltage Regulators
+ *
+ * Copyright 2021 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sensor/isl_pmbus_vr.h"
+#include "hw/qdev-properties.h"
+#include "qapi/visitor.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+
+static uint8_t isl_pmbus_vr_read_byte(PMBusDevice *pmdev)
+{
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: reading from unsupported register: 0x%02x\n",
+ __func__, pmdev->code);
+ return PMBUS_ERR_BYTE;
+}
+
+static int isl_pmbus_vr_write_data(PMBusDevice *pmdev, const uint8_t *buf,
+ uint8_t len)
+{
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: write to unsupported register: 0x%02x\n",
+ __func__, pmdev->code);
+ return PMBUS_ERR_BYTE;
+}
+
+/* TODO: Implement coefficients support in pmbus_device.c for qmp */
+static void isl_pmbus_vr_get(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ visit_type_uint16(v, name, (uint16_t *)opaque, errp);
+}
+
+static void isl_pmbus_vr_set(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ PMBusDevice *pmdev = PMBUS_DEVICE(obj);
+ uint16_t *internal = opaque;
+ uint16_t value;
+ if (!visit_type_uint16(v, name, &value, errp)) {
+ return;
+ }
+
+ *internal = value;
+ pmbus_check_limits(pmdev);
+}
+
+static void isl_pmbus_vr_exit_reset(Object *obj)
+{
+ PMBusDevice *pmdev = PMBUS_DEVICE(obj);
+
+ pmdev->page = 0;
+ pmdev->capability = ISL_CAPABILITY_DEFAULT;
+ for (int i = 0; i < pmdev->num_pages; i++) {
+ pmdev->pages[i].operation = ISL_OPERATION_DEFAULT;
+ pmdev->pages[i].on_off_config = ISL_ON_OFF_CONFIG_DEFAULT;
+ pmdev->pages[i].vout_mode = ISL_VOUT_MODE_DEFAULT;
+ pmdev->pages[i].vout_command = ISL_VOUT_COMMAND_DEFAULT;
+ pmdev->pages[i].vout_max = ISL_VOUT_MAX_DEFAULT;
+ pmdev->pages[i].vout_margin_high = ISL_VOUT_MARGIN_HIGH_DEFAULT;
+ pmdev->pages[i].vout_margin_low = ISL_VOUT_MARGIN_LOW_DEFAULT;
+ pmdev->pages[i].vout_transition_rate = ISL_VOUT_TRANSITION_RATE_DEFAULT;
+ pmdev->pages[i].vout_ov_fault_limit = ISL_VOUT_OV_FAULT_LIMIT_DEFAULT;
+ pmdev->pages[i].ot_fault_limit = ISL_OT_FAULT_LIMIT_DEFAULT;
+ pmdev->pages[i].ot_warn_limit = ISL_OT_WARN_LIMIT_DEFAULT;
+ pmdev->pages[i].vin_ov_warn_limit = ISL_VIN_OV_WARN_LIMIT_DEFAULT;
+ pmdev->pages[i].vin_uv_warn_limit = ISL_VIN_UV_WARN_LIMIT_DEFAULT;
+ pmdev->pages[i].iin_oc_fault_limit = ISL_IIN_OC_FAULT_LIMIT_DEFAULT;
+ pmdev->pages[i].ton_delay = ISL_TON_DELAY_DEFAULT;
+ pmdev->pages[i].ton_rise = ISL_TON_RISE_DEFAULT;
+ pmdev->pages[i].toff_fall = ISL_TOFF_FALL_DEFAULT;
+ pmdev->pages[i].revision = ISL_REVISION_DEFAULT;
+
+ pmdev->pages[i].read_vout = ISL_READ_VOUT_DEFAULT;
+ pmdev->pages[i].read_iout = ISL_READ_IOUT_DEFAULT;
+ pmdev->pages[i].read_pout = ISL_READ_POUT_DEFAULT;
+ pmdev->pages[i].read_vin = ISL_READ_VIN_DEFAULT;
+ pmdev->pages[i].read_iin = ISL_READ_IIN_DEFAULT;
+ pmdev->pages[i].read_pin = ISL_READ_PIN_DEFAULT;
+ pmdev->pages[i].read_temperature_1 = ISL_READ_TEMP_DEFAULT;
+ pmdev->pages[i].read_temperature_2 = ISL_READ_TEMP_DEFAULT;
+ pmdev->pages[i].read_temperature_3 = ISL_READ_TEMP_DEFAULT;
+ }
+}
+
+/* The raa228000 uses different direct mode coefficents from most isl devices */
+static void raa228000_exit_reset(Object *obj)
+{
+ PMBusDevice *pmdev = PMBUS_DEVICE(obj);
+
+ isl_pmbus_vr_exit_reset(obj);
+
+ pmdev->pages[0].read_iout = 0;
+ pmdev->pages[0].read_pout = 0;
+ pmdev->pages[0].read_vout = 0;
+ pmdev->pages[0].read_vin = 0;
+ pmdev->pages[0].read_iin = 0;
+ pmdev->pages[0].read_pin = 0;
+ pmdev->pages[0].read_temperature_1 = 0;
+ pmdev->pages[0].read_temperature_2 = 0;
+ pmdev->pages[0].read_temperature_3 = 0;
+}
+
+static void isl_pmbus_vr_add_props(Object *obj, uint64_t *flags, uint8_t pages)
+{
+ PMBusDevice *pmdev = PMBUS_DEVICE(obj);
+ for (int i = 0; i < pages; i++) {
+ if (flags[i] & PB_HAS_VIN) {
+ object_property_add(obj, "vin[*]", "uint16",
+ isl_pmbus_vr_get,
+ isl_pmbus_vr_set,
+ NULL, &pmdev->pages[i].read_vin);
+ }
+
+ if (flags[i] & PB_HAS_VOUT) {
+ object_property_add(obj, "vout[*]", "uint16",
+ isl_pmbus_vr_get,
+ isl_pmbus_vr_set,
+ NULL, &pmdev->pages[i].read_vout);
+ }
+
+ if (flags[i] & PB_HAS_IIN) {
+ object_property_add(obj, "iin[*]", "uint16",
+ isl_pmbus_vr_get,
+ isl_pmbus_vr_set,
+ NULL, &pmdev->pages[i].read_iin);
+ }
+
+ if (flags[i] & PB_HAS_IOUT) {
+ object_property_add(obj, "iout[*]", "uint16",
+ isl_pmbus_vr_get,
+ isl_pmbus_vr_set,
+ NULL, &pmdev->pages[i].read_iout);
+ }
+
+ if (flags[i] & PB_HAS_PIN) {
+ object_property_add(obj, "pin[*]", "uint16",
+ isl_pmbus_vr_get,
+ isl_pmbus_vr_set,
+ NULL, &pmdev->pages[i].read_pin);
+ }
+
+ if (flags[i] & PB_HAS_POUT) {
+ object_property_add(obj, "pout[*]", "uint16",
+ isl_pmbus_vr_get,
+ isl_pmbus_vr_set,
+ NULL, &pmdev->pages[i].read_pout);
+ }
+
+ if (flags[i] & PB_HAS_TEMPERATURE) {
+ object_property_add(obj, "temp1[*]", "uint16",
+ isl_pmbus_vr_get,
+ isl_pmbus_vr_set,
+ NULL, &pmdev->pages[i].read_temperature_1);
+ }
+
+ if (flags[i] & PB_HAS_TEMP2) {
+ object_property_add(obj, "temp2[*]", "uint16",
+ isl_pmbus_vr_get,
+ isl_pmbus_vr_set,
+ NULL, &pmdev->pages[i].read_temperature_2);
+ }
+
+ if (flags[i] & PB_HAS_TEMP3) {
+ object_property_add(obj, "temp3[*]", "uint16",
+ isl_pmbus_vr_get,
+ isl_pmbus_vr_set,
+ NULL, &pmdev->pages[i].read_temperature_3);
+ }
+ }
+}
+
+static void raa22xx_init(Object *obj)
+{
+ PMBusDevice *pmdev = PMBUS_DEVICE(obj);
+ uint64_t flags[2];
+
+ flags[0] = PB_HAS_VIN | PB_HAS_VOUT | PB_HAS_VOUT_MODE |
+ PB_HAS_VOUT_RATING | PB_HAS_VOUT_MARGIN | PB_HAS_IIN |
+ PB_HAS_IOUT | PB_HAS_PIN | PB_HAS_POUT | PB_HAS_TEMPERATURE |
+ PB_HAS_TEMP2 | PB_HAS_TEMP3 | PB_HAS_STATUS_MFR_SPECIFIC;
+ flags[1] = PB_HAS_IIN | PB_HAS_PIN | PB_HAS_TEMPERATURE | PB_HAS_TEMP3 |
+ PB_HAS_VOUT | PB_HAS_VOUT_MODE | PB_HAS_VOUT_MARGIN |
+ PB_HAS_VOUT_RATING | PB_HAS_IOUT | PB_HAS_POUT |
+ PB_HAS_STATUS_MFR_SPECIFIC;
+
+ pmbus_page_config(pmdev, 0, flags[0]);
+ pmbus_page_config(pmdev, 1, flags[1]);
+ isl_pmbus_vr_add_props(obj, flags, ARRAY_SIZE(flags));
+}
+
+static void raa228000_init(Object *obj)
+{
+ PMBusDevice *pmdev = PMBUS_DEVICE(obj);
+ uint64_t flags[1];
+
+ flags[0] = PB_HAS_VIN | PB_HAS_VOUT | PB_HAS_VOUT_MODE |
+ PB_HAS_VOUT_RATING | PB_HAS_VOUT_MARGIN | PB_HAS_IIN |
+ PB_HAS_IOUT | PB_HAS_PIN | PB_HAS_POUT | PB_HAS_TEMPERATURE |
+ PB_HAS_TEMP2 | PB_HAS_TEMP3 | PB_HAS_STATUS_MFR_SPECIFIC;
+
+ pmbus_page_config(pmdev, 0, flags[0]);
+ isl_pmbus_vr_add_props(obj, flags, 1);
+}
+
+static void isl_pmbus_vr_class_init(ObjectClass *klass, void *data,
+ uint8_t pages)
+{
+ PMBusDeviceClass *k = PMBUS_DEVICE_CLASS(klass);
+ k->write_data = isl_pmbus_vr_write_data;
+ k->receive_byte = isl_pmbus_vr_read_byte;
+ k->device_num_pages = pages;
+}
+
+static void isl69260_class_init(ObjectClass *klass, void *data)
+{
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ dc->desc = "Renesas ISL69260 Digital Multiphase Voltage Regulator";
+ rc->phases.exit = isl_pmbus_vr_exit_reset;
+ isl_pmbus_vr_class_init(klass, data, 2);
+}
+
+static void raa228000_class_init(ObjectClass *klass, void *data)
+{
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ dc->desc = "Renesas 228000 Digital Multiphase Voltage Regulator";
+ rc->phases.exit = raa228000_exit_reset;
+ isl_pmbus_vr_class_init(klass, data, 1);
+}
+
+static void raa229004_class_init(ObjectClass *klass, void *data)
+{
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ dc->desc = "Renesas 229004 Digital Multiphase Voltage Regulator";
+ rc->phases.exit = isl_pmbus_vr_exit_reset;
+ isl_pmbus_vr_class_init(klass, data, 2);
+}
+
+static const TypeInfo isl69260_info = {
+ .name = TYPE_ISL69260,
+ .parent = TYPE_PMBUS_DEVICE,
+ .instance_size = sizeof(ISLState),
+ .instance_init = raa22xx_init,
+ .class_init = isl69260_class_init,
+};
+
+static const TypeInfo raa229004_info = {
+ .name = TYPE_RAA229004,
+ .parent = TYPE_PMBUS_DEVICE,
+ .instance_size = sizeof(ISLState),
+ .instance_init = raa22xx_init,
+ .class_init = raa229004_class_init,
+};
+
+static const TypeInfo raa228000_info = {
+ .name = TYPE_RAA228000,
+ .parent = TYPE_PMBUS_DEVICE,
+ .instance_size = sizeof(ISLState),
+ .instance_init = raa228000_init,
+ .class_init = raa228000_class_init,
+};
+
+static void isl_pmbus_vr_register_types(void)
+{
+ type_register_static(&isl69260_info);
+ type_register_static(&raa228000_info);
+ type_register_static(&raa229004_info);
+}
+
+type_init(isl_pmbus_vr_register_types)
diff --git a/hw/sensor/meson.build b/hw/sensor/meson.build
index d1bba29..12b6992 100644
--- a/hw/sensor/meson.build
+++ b/hw/sensor/meson.build
@@ -5,3 +5,4 @@ softmmu_ss.add(when: 'CONFIG_EMC141X', if_true: files('emc141x.c'))
softmmu_ss.add(when: 'CONFIG_ADM1272', if_true: files('adm1272.c'))
softmmu_ss.add(when: 'CONFIG_MAX34451', if_true: files('max34451.c'))
softmmu_ss.add(when: 'CONFIG_LSM303DLHC_MAG', if_true: files('lsm303dlhc_mag.c'))
+softmmu_ss.add(when: 'CONFIG_ISL_PMBUS_VR', if_true: files('isl_pmbus_vr.c'))
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index d899be1..48305e1 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -224,7 +224,7 @@ static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
AspeedSegments seg;
int i;
- for (i = 0; i < asc->max_peripherals; i++) {
+ for (i = 0; i < asc->cs_num_max; i++) {
if (i == cs) {
continue;
}
@@ -290,7 +290,7 @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
*/
if ((asc->segments == aspeed_2500_spi1_segments ||
asc->segments == aspeed_2500_spi2_segments) &&
- cs == asc->max_peripherals &&
+ cs == asc->cs_num_max &&
seg.addr + seg.size != asc->segments[cs].addr +
asc->segments[cs].size) {
aspeed_smc_error("Tried to change CS%d end address to 0x%"
@@ -327,7 +327,7 @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
static uint64_t aspeed_smc_flash_default_read(void *opaque, hwaddr addr,
unsigned size)
{
- aspeed_smc_error("To 0x%" HWADDR_PRIx " of size %u" PRIx64, addr, size);
+ aspeed_smc_error("To 0x%" HWADDR_PRIx " of size %u", addr, size);
return 0;
}
@@ -693,13 +693,13 @@ static void aspeed_smc_reset(DeviceState *d)
}
/* Unselect all peripherals */
- for (i = 0; i < s->num_cs; ++i) {
+ for (i = 0; i < asc->cs_num_max; ++i) {
s->regs[s->r_ctrl0 + i] |= CTRL_CE_STOP_ACTIVE;
qemu_set_irq(s->cs_lines[i], true);
}
/* setup the default segment register values and regions for all */
- for (i = 0; i < asc->max_peripherals; ++i) {
+ for (i = 0; i < asc->cs_num_max; ++i) {
aspeed_smc_flash_set_segment_region(s, i,
asc->segment_to_reg(s, &asc->segments[i]));
}
@@ -729,8 +729,8 @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
(aspeed_smc_has_dma(asc) && addr == R_DMA_LEN) ||
(aspeed_smc_has_dma(asc) && addr == R_DMA_CHECKSUM) ||
(addr >= R_SEG_ADDR0 &&
- addr < R_SEG_ADDR0 + asc->max_peripherals) ||
- (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + asc->max_peripherals)) {
+ addr < R_SEG_ADDR0 + asc->cs_num_max) ||
+ (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + asc->cs_num_max)) {
trace_aspeed_smc_read(addr << 2, size, s->regs[addr]);
@@ -1042,11 +1042,11 @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
addr < s->r_timings + asc->nregs_timings) ||
addr == s->r_ce_ctrl) {
s->regs[addr] = value;
- } else if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs) {
+ } else if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + asc->cs_num_max) {
int cs = addr - s->r_ctrl0;
aspeed_smc_flash_update_ctrl(&s->flashes[cs], value);
} else if (addr >= R_SEG_ADDR0 &&
- addr < R_SEG_ADDR0 + asc->max_peripherals) {
+ addr < R_SEG_ADDR0 + asc->cs_num_max) {
int cs = addr - R_SEG_ADDR0;
if (value != s->regs[R_SEG_ADDR0 + cs]) {
@@ -1090,7 +1090,7 @@ static void aspeed_smc_instance_init(Object *obj)
AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
int i;
- for (i = 0; i < asc->max_peripherals; i++) {
+ for (i = 0; i < asc->cs_num_max; i++) {
object_initialize_child(obj, "flash[*]", &s->flashes[i],
TYPE_ASPEED_SMC_FLASH);
}
@@ -1127,21 +1127,15 @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
s->r_timings = asc->r_timings;
s->conf_enable_w0 = asc->conf_enable_w0;
- /* Enforce some real HW limits */
- if (s->num_cs > asc->max_peripherals) {
- aspeed_smc_error("num_cs cannot exceed: %d", asc->max_peripherals);
- s->num_cs = asc->max_peripherals;
- }
-
/* DMA irq. Keep it first for the initialization in the SoC */
sysbus_init_irq(sbd, &s->irq);
- s->spi = ssi_create_bus(dev, "spi");
+ s->spi = ssi_create_bus(dev, NULL);
/* Setup cs_lines for peripherals */
- s->cs_lines = g_new0(qemu_irq, s->num_cs);
+ s->cs_lines = g_new0(qemu_irq, asc->cs_num_max);
- for (i = 0; i < s->num_cs; ++i) {
+ for (i = 0; i < asc->cs_num_max; ++i) {
sysbus_init_irq(sbd, &s->cs_lines[i]);
}
@@ -1174,7 +1168,7 @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
* module behind to handle the memory accesses. This depends on
* the board configuration.
*/
- for (i = 0; i < asc->max_peripherals; ++i) {
+ for (i = 0; i < asc->cs_num_max; ++i) {
AspeedSMCFlash *fl = &s->flashes[i];
if (!object_property_set_link(OBJECT(fl), "controller", OBJECT(s),
@@ -1211,7 +1205,6 @@ static const VMStateDescription vmstate_aspeed_smc = {
};
static Property aspeed_smc_properties[] = {
- DEFINE_PROP_UINT32("num-cs", AspeedSMCState, num_cs, 1),
DEFINE_PROP_BOOL("inject-failure", AspeedSMCState, inject_failure, false),
DEFINE_PROP_LINK("dram", AspeedSMCState, dram_mr,
TYPE_MEMORY_REGION, MemoryRegion *),
@@ -1321,7 +1314,7 @@ static void aspeed_2400_smc_class_init(ObjectClass *klass, void *data)
asc->r_timings = R_TIMINGS;
asc->nregs_timings = 1;
asc->conf_enable_w0 = CONF_ENABLE_W0;
- asc->max_peripherals = 1;
+ asc->cs_num_max = 1;
asc->segments = aspeed_2400_smc_segments;
asc->flash_window_base = 0x10000000;
asc->flash_window_size = 0x6000000;
@@ -1366,7 +1359,7 @@ static void aspeed_2400_fmc_class_init(ObjectClass *klass, void *data)
asc->r_timings = R_TIMINGS;
asc->nregs_timings = 1;
asc->conf_enable_w0 = CONF_ENABLE_W0;
- asc->max_peripherals = 5;
+ asc->cs_num_max = 5;
asc->segments = aspeed_2400_fmc_segments;
asc->segment_addr_mask = 0xffff0000;
asc->resets = aspeed_2400_fmc_resets;
@@ -1408,7 +1401,7 @@ static void aspeed_2400_spi1_class_init(ObjectClass *klass, void *data)
asc->r_timings = R_SPI_TIMINGS;
asc->nregs_timings = 1;
asc->conf_enable_w0 = SPI_CONF_ENABLE_W0;
- asc->max_peripherals = 1;
+ asc->cs_num_max = 1;
asc->segments = aspeed_2400_spi1_segments;
asc->flash_window_base = 0x30000000;
asc->flash_window_size = 0x10000000;
@@ -1449,7 +1442,7 @@ static void aspeed_2500_fmc_class_init(ObjectClass *klass, void *data)
asc->r_timings = R_TIMINGS;
asc->nregs_timings = 1;
asc->conf_enable_w0 = CONF_ENABLE_W0;
- asc->max_peripherals = 3;
+ asc->cs_num_max = 3;
asc->segments = aspeed_2500_fmc_segments;
asc->segment_addr_mask = 0xffff0000;
asc->resets = aspeed_2500_fmc_resets;
@@ -1487,7 +1480,7 @@ static void aspeed_2500_spi1_class_init(ObjectClass *klass, void *data)
asc->r_timings = R_TIMINGS;
asc->nregs_timings = 1;
asc->conf_enable_w0 = CONF_ENABLE_W0;
- asc->max_peripherals = 2;
+ asc->cs_num_max = 2;
asc->segments = aspeed_2500_spi1_segments;
asc->segment_addr_mask = 0xffff0000;
asc->flash_window_base = 0x30000000;
@@ -1522,7 +1515,7 @@ static void aspeed_2500_spi2_class_init(ObjectClass *klass, void *data)
asc->r_timings = R_TIMINGS;
asc->nregs_timings = 1;
asc->conf_enable_w0 = CONF_ENABLE_W0;
- asc->max_peripherals = 2;
+ asc->cs_num_max = 2;
asc->segments = aspeed_2500_spi2_segments;
asc->segment_addr_mask = 0xffff0000;
asc->flash_window_base = 0x38000000;
@@ -1604,7 +1597,7 @@ static void aspeed_2600_fmc_class_init(ObjectClass *klass, void *data)
asc->r_timings = R_TIMINGS;
asc->nregs_timings = 1;
asc->conf_enable_w0 = CONF_ENABLE_W0;
- asc->max_peripherals = 3;
+ asc->cs_num_max = 3;
asc->segments = aspeed_2600_fmc_segments;
asc->segment_addr_mask = 0x0ff00ff0;
asc->resets = aspeed_2600_fmc_resets;
@@ -1643,7 +1636,7 @@ static void aspeed_2600_spi1_class_init(ObjectClass *klass, void *data)
asc->r_timings = R_TIMINGS;
asc->nregs_timings = 2;
asc->conf_enable_w0 = CONF_ENABLE_W0;
- asc->max_peripherals = 2;
+ asc->cs_num_max = 2;
asc->segments = aspeed_2600_spi1_segments;
asc->segment_addr_mask = 0x0ff00ff0;
asc->flash_window_base = 0x30000000;
@@ -1682,7 +1675,7 @@ static void aspeed_2600_spi2_class_init(ObjectClass *klass, void *data)
asc->r_timings = R_TIMINGS;
asc->nregs_timings = 3;
asc->conf_enable_w0 = CONF_ENABLE_W0;
- asc->max_peripherals = 3;
+ asc->cs_num_max = 3;
asc->segments = aspeed_2600_spi2_segments;
asc->segment_addr_mask = 0x0ff00ff0;
asc->flash_window_base = 0x50000000;
diff --git a/hw/tpm/tpm_tis_isa.c b/hw/tpm/tpm_tis_isa.c
index 10d8a14..3477afd 100644
--- a/hw/tpm/tpm_tis_isa.c
+++ b/hw/tpm/tpm_tis_isa.c
@@ -127,7 +127,7 @@ static void tpm_tis_isa_realizefn(DeviceState *dev, Error **errp)
return;
}
- isa_init_irq(ISA_DEVICE(dev), &s->irq, s->irq_num);
+ s->irq = isa_get_irq(ISA_DEVICE(dev), s->irq_num);
memory_region_add_subregion(isa_address_space(ISA_DEVICE(dev)),
TPM_TIS_ADDR_BASE, &s->mmio);
diff --git a/include/block/nbd.h b/include/block/nbd.h
index 78d101b..a98eb66 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -415,7 +415,8 @@ NBDClientConnection *nbd_client_connection_new(const SocketAddress *saddr,
bool do_negotiation,
const char *export_name,
const char *x_dirty_bitmap,
- QCryptoTLSCreds *tlscreds);
+ QCryptoTLSCreds *tlscreds,
+ const char *tlshostname);
void nbd_client_connection_release(NBDClientConnection *conn);
QIOChannel *coroutine_fn
diff --git a/include/hw/i2c/pmbus_device.h b/include/hw/i2c/pmbus_device.h
index 62bd38c..0f4d6b3 100644
--- a/include/hw/i2c/pmbus_device.h
+++ b/include/hw/i2c/pmbus_device.h
@@ -43,6 +43,7 @@ enum pmbus_registers {
PMBUS_VOUT_DROOP = 0x28, /* R/W word */
PMBUS_VOUT_SCALE_LOOP = 0x29, /* R/W word */
PMBUS_VOUT_SCALE_MONITOR = 0x2A, /* R/W word */
+ PMBUS_VOUT_MIN = 0x2B, /* R/W word */
PMBUS_COEFFICIENTS = 0x30, /* Read-only block 5 bytes */
PMBUS_POUT_MAX = 0x31, /* R/W word */
PMBUS_MAX_DUTY = 0x32, /* R/W word */
@@ -227,6 +228,8 @@ enum pmbus_registers {
#define PB_MAX_PAGES 0x1F
#define PB_ALL_PAGES 0xFF
+#define PMBUS_ERR_BYTE 0xFF
+
#define TYPE_PMBUS_DEVICE "pmbus-device"
OBJECT_DECLARE_TYPE(PMBusDevice, PMBusDeviceClass,
PMBUS_DEVICE)
@@ -255,6 +258,7 @@ OBJECT_DECLARE_TYPE(PMBusDevice, PMBusDeviceClass,
#define PB_HAS_TEMP3 BIT_ULL(42)
#define PB_HAS_TEMP_RATING BIT_ULL(43)
#define PB_HAS_MFR_INFO BIT_ULL(50)
+#define PB_HAS_STATUS_MFR_SPECIFIC BIT_ULL(51)
struct PMBusDeviceClass {
SMBusDeviceClass parent_class;
@@ -295,6 +299,7 @@ typedef struct PMBusPage {
uint16_t vout_droop; /* R/W word */
uint16_t vout_scale_loop; /* R/W word */
uint16_t vout_scale_monitor; /* R/W word */
+ uint16_t vout_min; /* R/W word */
uint8_t coefficients[5]; /* Read-only block 5 bytes */
uint16_t pout_max; /* R/W word */
uint16_t max_duty; /* R/W word */
@@ -443,7 +448,7 @@ typedef struct PMBusCoefficients {
*
* Y = (m * x - b) * 10^R
*
- * @return uint32_t
+ * @return uint16_t
*/
uint16_t pmbus_data2direct_mode(PMBusCoefficients c, uint32_t value);
@@ -457,6 +462,24 @@ uint16_t pmbus_data2direct_mode(PMBusCoefficients c, uint32_t value);
uint32_t pmbus_direct_mode2data(PMBusCoefficients c, uint16_t value);
/**
+ * Convert sensor values to linear mode format
+ *
+ * L = D * 2^(-e)
+ *
+ * @return uint16
+ */
+uint16_t pmbus_data2linear_mode(uint16_t value, int exp);
+
+/**
+ * Convert linear mode formatted data into sensor reading
+ *
+ * D = L * 2^e
+ *
+ * @return uint16
+ */
+uint16_t pmbus_linear_mode2data(uint16_t value, int exp);
+
+/**
* @brief Send a block of data over PMBus
* Assumes that the bytes in the block are already ordered correctly,
* also assumes the length has been prepended to the block if necessary
diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h
index d4417b3..034d706 100644
--- a/include/hw/isa/isa.h
+++ b/include/hw/isa/isa.h
@@ -83,8 +83,6 @@ struct ISADevice {
DeviceState parent_obj;
/*< public >*/
- int8_t isairq[2]; /* -1 = unassigned */
- int nirqs;
int ioport_id;
};
@@ -92,7 +90,6 @@ ISABus *isa_bus_new(DeviceState *dev, MemoryRegion *address_space,
MemoryRegion *address_space_io, Error **errp);
void isa_bus_irqs(ISABus *bus, qemu_irq *irqs);
qemu_irq isa_get_irq(ISADevice *dev, unsigned isairq);
-void isa_init_irq(ISADevice *dev, qemu_irq *p, unsigned isairq);
void isa_connect_gpio_out(ISADevice *isadev, int gpioirq, unsigned isairq);
void isa_bus_dma(ISABus *bus, IsaDma *dma8, IsaDma *dma16);
IsaDma *isa_get_dma(ISABus *bus, int nchan);
diff --git a/include/hw/mips/mips.h b/include/hw/mips/mips.h
index 6c9c880..101799f 100644
--- a/include/hw/mips/mips.h
+++ b/include/hw/mips/mips.h
@@ -9,9 +9,6 @@
#include "exec/memory.h"
-/* gt64xxx.c */
-PCIBus *gt64120_register(qemu_irq *pic);
-
/* bonito.c */
PCIBus *bonito_init(qemu_irq *pic);
diff --git a/include/hw/rtc/mc146818rtc.h b/include/hw/rtc/mc146818rtc.h
index 5b45b22..deef93f 100644
--- a/include/hw/rtc/mc146818rtc.h
+++ b/include/hw/rtc/mc146818rtc.h
@@ -25,6 +25,7 @@ struct RTCState {
MemoryRegion coalesced_io;
uint8_t cmos_data[128];
uint8_t cmos_index;
+ uint8_t isairq;
int32_t base_year;
uint64_t base_rtc;
uint64_t last_update;
diff --git a/include/hw/sensor/isl_pmbus_vr.h b/include/hw/sensor/isl_pmbus_vr.h
new file mode 100644
index 0000000..3e47ff7
--- /dev/null
+++ b/include/hw/sensor/isl_pmbus_vr.h
@@ -0,0 +1,52 @@
+/*
+ * PMBus device for Renesas Digital Multiphase Voltage Regulators
+ *
+ * Copyright 2022 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_MISC_ISL_PMBUS_VR_H
+#define HW_MISC_ISL_PMBUS_VR_H
+
+#include "hw/i2c/pmbus_device.h"
+#include "qom/object.h"
+
+#define TYPE_ISL69260 "isl69260"
+#define TYPE_RAA228000 "raa228000"
+#define TYPE_RAA229004 "raa229004"
+
+struct ISLState {
+ PMBusDevice parent;
+};
+
+OBJECT_DECLARE_SIMPLE_TYPE(ISLState, ISL69260)
+
+#define ISL_CAPABILITY_DEFAULT 0x40
+#define ISL_OPERATION_DEFAULT 0x80
+#define ISL_ON_OFF_CONFIG_DEFAULT 0x16
+#define ISL_VOUT_MODE_DEFAULT 0x40
+#define ISL_VOUT_COMMAND_DEFAULT 0x0384
+#define ISL_VOUT_MAX_DEFAULT 0x08FC
+#define ISL_VOUT_MARGIN_HIGH_DEFAULT 0x0640
+#define ISL_VOUT_MARGIN_LOW_DEFAULT 0xFA
+#define ISL_VOUT_TRANSITION_RATE_DEFAULT 0x64
+#define ISL_VOUT_OV_FAULT_LIMIT_DEFAULT 0x076C
+#define ISL_OT_FAULT_LIMIT_DEFAULT 0x7D
+#define ISL_OT_WARN_LIMIT_DEFAULT 0x07D0
+#define ISL_VIN_OV_WARN_LIMIT_DEFAULT 0x36B0
+#define ISL_VIN_UV_WARN_LIMIT_DEFAULT 0x1F40
+#define ISL_IIN_OC_FAULT_LIMIT_DEFAULT 0x32
+#define ISL_TON_DELAY_DEFAULT 0x14
+#define ISL_TON_RISE_DEFAULT 0x01F4
+#define ISL_TOFF_FALL_DEFAULT 0x01F4
+#define ISL_REVISION_DEFAULT 0x33
+#define ISL_READ_VOUT_DEFAULT 1000
+#define ISL_READ_IOUT_DEFAULT 40
+#define ISL_READ_POUT_DEFAULT 4
+#define ISL_READ_TEMP_DEFAULT 25
+#define ISL_READ_VIN_DEFAULT 1100
+#define ISL_READ_IIN_DEFAULT 40
+#define ISL_READ_PIN_DEFAULT 4
+
+#endif
diff --git a/include/hw/southbridge/piix.h b/include/hw/southbridge/piix.h
index 6387f2b..f63f83e 100644
--- a/include/hw/southbridge/piix.h
+++ b/include/hw/southbridge/piix.h
@@ -70,8 +70,6 @@ typedef struct PIIXState PIIX3State;
DECLARE_INSTANCE_CHECKER(PIIX3State, PIIX3_PCI_DEVICE,
TYPE_PIIX3_PCI_DEVICE)
-extern PCIDevice *piix4_dev;
-
PIIX3State *piix3_create(PCIBus *pci_bus, ISABus **isa_bus);
DeviceState *piix4_create(PCIBus *pci_bus, ISABus **isa_bus, I2CBus **smbus);
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
index cad73dd..2d5f8f3 100644
--- a/include/hw/ssi/aspeed_smc.h
+++ b/include/hw/ssi/aspeed_smc.h
@@ -57,7 +57,6 @@ struct AspeedSMCState {
qemu_irq irq;
- uint32_t num_cs;
qemu_irq *cs_lines;
bool inject_failure;
@@ -96,7 +95,7 @@ struct AspeedSMCClass {
uint8_t r_timings;
uint8_t nregs_timings;
uint8_t conf_enable_w0;
- uint8_t max_peripherals;
+ uint8_t cs_num_max;
const uint32_t *resets;
const AspeedSegments *segments;
uint32_t segment_addr_mask;
diff --git a/linux-user/ppc/cpu_loop.c b/linux-user/ppc/cpu_loop.c
index c5d8099..b468f19 100644
--- a/linux-user/ppc/cpu_loop.c
+++ b/linux-user/ppc/cpu_loop.c
@@ -181,7 +181,8 @@ void cpu_loop(CPUPPCState *env)
}
break;
case POWERPC_EXCP_TRAP:
- cpu_abort(cs, "Tried to call a TRAP\n");
+ si_signo = TARGET_SIGTRAP;
+ si_code = TARGET_TRAP_BRKPT;
break;
default:
/* Should not happen ! */
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 27a0ff3..2a3f3cc 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -999,7 +999,6 @@ int do_sigaction(int sig, const struct target_sigaction *act,
oact->sa_mask = k->sa_mask;
}
if (act) {
- /* FIXME: This is not threadsafe. */
__get_user(k->_sa_handler, &act->_sa_handler);
__get_user(k->sa_flags, &act->sa_flags);
#ifdef TARGET_ARCH_HAS_SA_RESTORER
@@ -1149,7 +1148,6 @@ void process_pending_signals(CPUArchState *cpu_env)
sigset_t *blocked_set;
while (qatomic_read(&ts->signal_pending)) {
- /* FIXME: This is not threadsafe. */
sigfillset(&set);
sigprocmask(SIG_SETMASK, &set, 0);
diff --git a/nbd/client-connection.c b/nbd/client-connection.c
index 2bda426..2a63293 100644
--- a/nbd/client-connection.c
+++ b/nbd/client-connection.c
@@ -33,6 +33,7 @@ struct NBDClientConnection {
/* Initialization constants, never change */
SocketAddress *saddr; /* address to connect to */
QCryptoTLSCreds *tlscreds;
+ char *tlshostname;
NBDExportInfo initial_info;
bool do_negotiation;
bool do_retry;
@@ -77,7 +78,8 @@ NBDClientConnection *nbd_client_connection_new(const SocketAddress *saddr,
bool do_negotiation,
const char *export_name,
const char *x_dirty_bitmap,
- QCryptoTLSCreds *tlscreds)
+ QCryptoTLSCreds *tlscreds,
+ const char *tlshostname)
{
NBDClientConnection *conn = g_new(NBDClientConnection, 1);
@@ -85,6 +87,7 @@ NBDClientConnection *nbd_client_connection_new(const SocketAddress *saddr,
*conn = (NBDClientConnection) {
.saddr = QAPI_CLONE(SocketAddress, saddr),
.tlscreds = tlscreds,
+ .tlshostname = g_strdup(tlshostname),
.do_negotiation = do_negotiation,
.initial_info.request_sizes = true,
@@ -107,6 +110,7 @@ static void nbd_client_connection_do_free(NBDClientConnection *conn)
}
error_free(conn->err);
qapi_free_SocketAddress(conn->saddr);
+ g_free(conn->tlshostname);
object_unref(OBJECT(conn->tlscreds));
g_free(conn->initial_info.x_dirty_bitmap);
g_free(conn->initial_info.name);
@@ -120,6 +124,7 @@ static void nbd_client_connection_do_free(NBDClientConnection *conn)
*/
static int nbd_connect(QIOChannelSocket *sioc, SocketAddress *addr,
NBDExportInfo *info, QCryptoTLSCreds *tlscreds,
+ const char *tlshostname,
QIOChannel **outioc, Error **errp)
{
int ret;
@@ -140,7 +145,7 @@ static int nbd_connect(QIOChannelSocket *sioc, SocketAddress *addr,
}
ret = nbd_receive_negotiate(NULL, QIO_CHANNEL(sioc), tlscreds,
- tlscreds ? addr->u.inet.host : NULL,
+ tlshostname,
outioc, info, errp);
if (ret < 0) {
/*
@@ -183,7 +188,8 @@ static void *connect_thread_func(void *opaque)
ret = nbd_connect(conn->sioc, conn->saddr,
conn->do_negotiation ? &conn->updated_info : NULL,
- conn->tlscreds, &conn->ioc, &local_err);
+ conn->tlscreds, conn->tlshostname,
+ &conn->ioc, &local_err);
/*
* conn->updated_info will finally be returned to the user. Clear the
diff --git a/nbd/server.c b/nbd/server.c
index 53e68cf..5da884c 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -2085,11 +2085,10 @@ static void nbd_extent_array_convert_to_be(NBDExtentArray *ea)
* Add extent to NBDExtentArray. If extent can't be added (no available space),
* return -1.
* For safety, when returning -1 for the first time, .can_add is set to false,
- * further call to nbd_extent_array_add() will crash.
- * (to avoid the situation, when after failing to add an extent (returned -1),
- * user miss this failure and add another extent, which is successfully added
- * (array is full, but new extent may be squashed into the last one), then we
- * have invalid array with skipped extent)
+ * and further calls to nbd_extent_array_add() will crash.
+ * (this avoids the situation where a caller ignores failure to add one extent,
+ * where adding another extent that would squash into the last array entry
+ * would result in an incorrect range reported to the client)
*/
static int nbd_extent_array_add(NBDExtentArray *ea,
uint32_t length, uint32_t flags)
@@ -2288,7 +2287,7 @@ static int nbd_co_receive_request(NBDRequestData *req, NBDRequest *request,
assert(client->recv_coroutine == qemu_coroutine_self());
ret = nbd_receive_request(client, request, errp);
if (ret < 0) {
- return ret;
+ return ret;
}
trace_nbd_co_receive_request_decode_type(request->handle, request->type,
@@ -2648,7 +2647,7 @@ static coroutine_fn void nbd_trip(void *opaque)
}
if (ret < 0) {
- /* It wans't -EIO, so, according to nbd_co_receive_request()
+ /* It wasn't -EIO, so, according to nbd_co_receive_request()
* semantics, we should return the error to the client. */
Error *export_err = local_err;
diff --git a/pc-bios/openbios-ppc b/pc-bios/openbios-ppc
index 5f35274..d8203a5 100644
--- a/pc-bios/openbios-ppc
+++ b/pc-bios/openbios-ppc
Binary files differ
diff --git a/pc-bios/openbios-sparc32 b/pc-bios/openbios-sparc32
index c9f1f72..118b1cc 100644
--- a/pc-bios/openbios-sparc32
+++ b/pc-bios/openbios-sparc32
Binary files differ
diff --git a/pc-bios/openbios-sparc64 b/pc-bios/openbios-sparc64
index 792905d..846cb48 100644
--- a/pc-bios/openbios-sparc64
+++ b/pc-bios/openbios-sparc64
Binary files differ
diff --git a/qapi/block-core.json b/qapi/block-core.json
index f13b5ff..e89f2df 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -4079,6 +4079,8 @@
#
# @tls-creds: TLS credentials ID
#
+# @tls-hostname: TLS hostname override for certificate validation (Since 7.0)
+#
# @x-dirty-bitmap: A metadata context name such as "qemu:dirty-bitmap:NAME"
# or "qemu:allocation-depth" to query in place of the
# traditional "base:allocation" block status (see
@@ -4109,6 +4111,7 @@
'data': { 'server': 'SocketAddress',
'*export': 'str',
'*tls-creds': 'str',
+ '*tls-hostname': 'str',
'*x-dirty-bitmap': { 'type': 'str', 'features': [ 'unstable' ] },
'*reconnect-delay': 'uint32',
'*open-timeout': 'uint32' } }
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index 633b46c..2f0d8ac 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -604,10 +604,6 @@ static int do_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
.done = false,
};
- if (bytes > INT_MAX) {
- return -ERANGE;
- }
-
co = qemu_coroutine_create(co_pwrite_zeroes_entry, &data);
bdrv_coroutine_enter(blk_bs(blk), co);
while (!data.done) {
@@ -1161,8 +1157,9 @@ static int write_f(BlockBackend *blk, int argc, char **argv)
if (count < 0) {
print_cvtnum_err(count, argv[optind]);
return count;
- } else if (count > BDRV_REQUEST_MAX_BYTES) {
- printf("length cannot exceed %" PRIu64 ", given %s\n",
+ } else if (count > BDRV_REQUEST_MAX_BYTES &&
+ !(flags & BDRV_REQ_NO_FALLBACK)) {
+ printf("length cannot exceed %" PRIu64 " without -n, given %s\n",
(uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
return -EINVAL;
}
@@ -1994,11 +1991,9 @@ static int map_is_allocated(BlockDriverState *bs, int64_t offset,
int64_t bytes, int64_t *pnum)
{
int64_t num;
- int num_checked;
int ret, firstret;
- num_checked = MIN(bytes, BDRV_REQUEST_MAX_BYTES);
- ret = bdrv_is_allocated(bs, offset, num_checked, &num);
+ ret = bdrv_is_allocated(bs, offset, bytes, &num);
if (ret < 0) {
return ret;
}
@@ -2010,8 +2005,7 @@ static int map_is_allocated(BlockDriverState *bs, int64_t offset,
offset += num;
bytes -= num;
- num_checked = MIN(bytes, BDRV_REQUEST_MAX_BYTES);
- ret = bdrv_is_allocated(bs, offset, num_checked, &num);
+ ret = bdrv_is_allocated(bs, offset, bytes, &num);
if (ret == firstret && num) {
*pnum += num;
} else {
diff --git a/qemu-nbd.c b/qemu-nbd.c
index c6c20df..713e755 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -69,6 +69,7 @@
#define QEMU_NBD_OPT_TLSAUTHZ 264
#define QEMU_NBD_OPT_PID_FILE 265
#define QEMU_NBD_OPT_SELINUX_LABEL 266
+#define QEMU_NBD_OPT_TLSHOSTNAME 267
#define MBR_SIZE 512
@@ -542,6 +543,7 @@ int main(int argc, char **argv)
{ "export-name", required_argument, NULL, 'x' },
{ "description", required_argument, NULL, 'D' },
{ "tls-creds", required_argument, NULL, QEMU_NBD_OPT_TLSCREDS },
+ { "tls-hostname", required_argument, NULL, QEMU_NBD_OPT_TLSHOSTNAME },
{ "tls-authz", required_argument, NULL, QEMU_NBD_OPT_TLSAUTHZ },
{ "image-opts", no_argument, NULL, QEMU_NBD_OPT_IMAGE_OPTS },
{ "trace", required_argument, NULL, 'T' },
@@ -568,6 +570,7 @@ int main(int argc, char **argv)
strList *bitmaps = NULL;
bool alloc_depth = false;
const char *tlscredsid = NULL;
+ const char *tlshostname = NULL;
bool imageOpts = false;
bool writethrough = false; /* Client will flush as needed. */
bool fork_process = false;
@@ -747,6 +750,9 @@ int main(int argc, char **argv)
case QEMU_NBD_OPT_TLSCREDS:
tlscredsid = optarg;
break;
+ case QEMU_NBD_OPT_TLSHOSTNAME:
+ tlshostname = optarg;
+ break;
case QEMU_NBD_OPT_IMAGE_OPTS:
imageOpts = true;
break;
@@ -802,7 +808,9 @@ int main(int argc, char **argv)
socket_activation = check_socket_activation();
if (socket_activation == 0) {
- setup_address_and_port(&bindto, &port);
+ if (!sockpath) {
+ setup_address_and_port(&bindto, &port);
+ }
} else {
/* Using socket activation - check user didn't use -p etc. */
const char *err_msg = socket_activation_validate_opts(device, sockpath,
@@ -823,10 +831,6 @@ int main(int argc, char **argv)
}
if (tlscredsid) {
- if (sockpath) {
- error_report("TLS is only supported with IPv4/IPv6");
- exit(EXIT_FAILURE);
- }
if (device) {
error_report("TLS is not supported with a host device");
exit(EXIT_FAILURE);
@@ -835,6 +839,10 @@ int main(int argc, char **argv)
error_report("TLS authorization is incompatible with export list");
exit(EXIT_FAILURE);
}
+ if (tlshostname && !list) {
+ error_report("TLS hostname is only supported with export list");
+ exit(EXIT_FAILURE);
+ }
tlscreds = nbd_get_tls_creds(tlscredsid, list, &local_err);
if (local_err) {
error_reportf_err(local_err, "Failed to get TLS creds: ");
@@ -845,6 +853,10 @@ int main(int argc, char **argv)
error_report("--tls-authz is not permitted without --tls-creds");
exit(EXIT_FAILURE);
}
+ if (tlshostname) {
+ error_report("--tls-hostname is not permitted without --tls-creds");
+ exit(EXIT_FAILURE);
+ }
}
if (selinux_label) {
@@ -861,7 +873,8 @@ int main(int argc, char **argv)
if (list) {
saddr = nbd_build_socket_address(sockpath, bindto, port);
- return qemu_nbd_client_list(saddr, tlscreds, bindto);
+ return qemu_nbd_client_list(saddr, tlscreds,
+ tlshostname ? tlshostname : bindto);
}
#if !HAVE_NBD_DEVICE
diff --git a/roms/openbios b/roms/openbios
-Subproject 04dfc984ac0ad70e2d1f58d1121e3b767090112
+Subproject 0e0afae6579c1efe9f0d85505b75ffe98955413
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 4aae239..af28717 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -434,14 +434,13 @@ static void mips_cpu_disas_set_info(CPUState *s, disassemble_info *info)
* Since commit 6af0bf9c7c3 this model assumes a CPU clocked at 200MHz.
*/
#define CPU_FREQ_HZ_DEFAULT 200000000
-#define CP0_COUNT_RATE_DEFAULT 2
static void mips_cp0_period_set(MIPSCPU *cpu)
{
CPUMIPSState *env = &cpu->env;
env->cp0_count_ns = clock_ticks_to_ns(MIPS_CPU(cpu)->clock,
- cpu->cp0_count_rate);
+ env->cpu_model->CCRes);
assert(env->cp0_count_ns);
}
@@ -514,13 +513,6 @@ static ObjectClass *mips_cpu_class_by_name(const char *cpu_model)
return oc;
}
-static Property mips_cpu_properties[] = {
- /* CP0 timer running at half the clock of the CPU */
- DEFINE_PROP_UINT32("cp0-count-rate", MIPSCPU, cp0_count_rate,
- CP0_COUNT_RATE_DEFAULT),
- DEFINE_PROP_END_OF_LIST()
-};
-
#ifndef CONFIG_USER_ONLY
#include "hw/core/sysemu-cpu-ops.h"
@@ -560,7 +552,6 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
device_class_set_parent_realize(dc, mips_cpu_realizefn,
&mcc->parent_realize);
device_class_set_parent_reset(dc, mips_cpu_reset, &mcc->parent_reset);
- device_class_set_props(dc, mips_cpu_properties);
cc->class_by_name = mips_cpu_class_by_name;
cc->has_work = mips_cpu_has_work;
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 09e98f6..52ce08a 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -1167,7 +1167,6 @@ typedef struct CPUArchState {
* @env: #CPUMIPSState
* @clock: this CPU input clock (may be connected
* to an output clock from another device).
- * @cp0_count_rate: rate at which the coprocessor 0 counter increments
*
* A MIPS CPU.
*/
@@ -1179,14 +1178,6 @@ struct ArchCPU {
Clock *clock;
CPUNegativeOffsetState neg;
CPUMIPSState env;
- /*
- * The Count register acts as a timer, incrementing at a constant rate,
- * whether or not an instruction is executed, retired, or any forward
- * progress is made through the pipeline. The rate at which the counter
- * increments is implementation dependent, and is a function of the
- * pipeline clock of the processor, not the issue width of the processor.
- */
- unsigned cp0_count_rate;
};
diff --git a/target/mips/internal.h b/target/mips/internal.h
index ac6e03e..57b3126 100644
--- a/target/mips/internal.h
+++ b/target/mips/internal.h
@@ -47,6 +47,15 @@ struct mips_def_t {
target_ulong CP0_LLAddr_rw_bitmask;
int CP0_LLAddr_shift;
int32_t SYNCI_Step;
+ /*
+ * @CCRes: rate at which the coprocessor 0 counter increments
+ *
+ * The Count register acts as a timer, incrementing at a constant rate,
+ * whether or not an instruction is executed, retired, or any forward
+ * progress is made through the pipeline. The rate at which the counter
+ * increments is implementation dependent, and is a function of the
+ * pipeline clock of the processor, not the issue width of the processor.
+ */
int32_t CCRes;
int32_t CP0_Status_rw_bitmask;
int32_t CP0_TCStatus_rw_bitmask;
diff --git a/tests/avocado/linux_ssh_mips_malta.py b/tests/avocado/linux_ssh_mips_malta.py
index c0f0be5..0179d8a 100644
--- a/tests/avocado/linux_ssh_mips_malta.py
+++ b/tests/avocado/linux_ssh_mips_malta.py
@@ -23,6 +23,9 @@ from avocado.utils import ssh
@skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout')
@skipUnless(ssh.SSH_CLIENT_BINARY, 'No SSH client available')
class LinuxSSH(QemuSystemTest, LinuxSSHMixIn):
+ """
+ :avocado: tags=accel:tcg
+ """
timeout = 150 # Not for 'configure --enable-debug --enable-debug-tcg'
diff --git a/tests/qemu-iotests/172.out b/tests/qemu-iotests/172.out
index 4cf4d53..9479b92 100644
--- a/tests/qemu-iotests/172.out
+++ b/tests/qemu-iotests/172.out
@@ -15,7 +15,6 @@ Testing:
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
@@ -43,7 +42,6 @@ Testing: -fda TEST_DIR/t.qcow2
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
@@ -81,7 +79,6 @@ Testing: -fdb TEST_DIR/t.qcow2
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
@@ -135,7 +132,6 @@ Testing: -fda TEST_DIR/t.qcow2 -fdb TEST_DIR/t.qcow2.2
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
@@ -190,7 +186,6 @@ Testing: -fdb
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
@@ -230,7 +225,6 @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
@@ -268,7 +262,6 @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2,index=1
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
@@ -322,7 +315,6 @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2 -drive if=floppy,file=TEST_DIR/t
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
@@ -380,7 +372,6 @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
@@ -418,7 +409,6 @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,unit=1
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
@@ -456,7 +446,6 @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qco
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
@@ -520,7 +509,6 @@ Testing: -fda TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2.2 -device fl
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
@@ -575,7 +563,6 @@ Testing: -fda TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2.2 -device fl
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
@@ -630,7 +617,6 @@ Testing: -fdb TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2.2 -device fl
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
@@ -685,7 +671,6 @@ Testing: -fdb TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2.2 -device fl
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
@@ -749,7 +734,6 @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.q
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
@@ -804,7 +788,6 @@ Testing: -drive if=floppy,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.q
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
@@ -865,7 +848,6 @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -global floppy.drive=none0 -device
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
@@ -933,7 +915,6 @@ Testing: -device floppy
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
@@ -958,7 +939,6 @@ Testing: -device floppy,drive-type=120
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
@@ -983,7 +963,6 @@ Testing: -device floppy,drive-type=144
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
@@ -1008,7 +987,6 @@ Testing: -device floppy,drive-type=288
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
@@ -1036,7 +1014,6 @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,drive-t
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
@@ -1074,7 +1051,6 @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,drive-t
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
@@ -1115,7 +1091,6 @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,logical
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
@@ -1153,7 +1128,6 @@ Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,physica
fdtypeA = "auto"
fdtypeB = "auto"
fallback = "288"
- isa irq 6
bus: floppy-bus.0
type floppy-bus
dev: floppy, id ""
diff --git a/tests/qemu-iotests/233 b/tests/qemu-iotests/233
index 9ca7b68..55db5b3 100755
--- a/tests/qemu-iotests/233
+++ b/tests/qemu-iotests/233
@@ -61,11 +61,13 @@ tls_x509_create_server "ca1" "server1"
tls_x509_create_client "ca1" "client1"
tls_x509_create_client "ca2" "client2"
tls_x509_create_client "ca1" "client3"
+tls_psk_create_creds "psk1"
+tls_psk_create_creds "psk2"
echo
echo "== preparing image =="
_make_test_img 64M
-$QEMU_IO -c 'w -P 0x11 1m 1m' "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c 'w -P 0x11 1m 1m' "$TEST_IMG" 2>&1 | _filter_qemu_io
echo
echo "== check TLS client to plain server fails =="
@@ -74,9 +76,9 @@ nbd_server_start_tcp_socket -f $IMGFMT "$TEST_IMG" 2> "$TEST_DIR/server.log"
obj=tls-creds-x509,dir=${tls_dir}/client1,endpoint=client,id=tls0
$QEMU_IMG info --image-opts --object $obj \
driver=nbd,host=$nbd_tcp_addr,port=$nbd_tcp_port,tls-creds=tls0 \
- 2>&1 | sed "s/$nbd_tcp_port/PORT/g"
+ 2>&1 | _filter_nbd
$QEMU_NBD_PROG -L -b $nbd_tcp_addr -p $nbd_tcp_port --object $obj \
- --tls-creds=tls0
+ --tls-creds=tls0 2>&1 | _filter_qemu_nbd_exports
nbd_server_stop
@@ -88,8 +90,10 @@ nbd_server_start_tcp_socket \
--tls-creds tls0 \
-f $IMGFMT "$TEST_IMG" 2>> "$TEST_DIR/server.log"
-$QEMU_IMG info nbd://localhost:$nbd_tcp_port 2>&1 | sed "s/$nbd_tcp_port/PORT/g"
-$QEMU_NBD_PROG -L -b $nbd_tcp_addr -p $nbd_tcp_port
+$QEMU_IMG info nbd://localhost:$nbd_tcp_port \
+ 2>&1 | _filter_nbd
+$QEMU_NBD_PROG -L -b $nbd_tcp_addr -p $nbd_tcp_port \
+ 2>&1 | _filter_qemu_nbd_exports
echo
echo "== check TLS works =="
@@ -97,21 +101,39 @@ obj1=tls-creds-x509,dir=${tls_dir}/client1,endpoint=client,id=tls0
obj2=tls-creds-x509,dir=${tls_dir}/client3,endpoint=client,id=tls0
$QEMU_IMG info --image-opts --object $obj1 \
driver=nbd,host=$nbd_tcp_addr,port=$nbd_tcp_port,tls-creds=tls0 \
- 2>&1 | sed "s/$nbd_tcp_port/PORT/g"
+ 2>&1 | _filter_nbd
$QEMU_IMG info --image-opts --object $obj2 \
driver=nbd,host=$nbd_tcp_addr,port=$nbd_tcp_port,tls-creds=tls0 \
- 2>&1 | sed "s/$nbd_tcp_port/PORT/g"
+ 2>&1 | _filter_nbd
$QEMU_NBD_PROG -L -b $nbd_tcp_addr -p $nbd_tcp_port --object $obj1 \
- --tls-creds=tls0
+ --tls-creds=tls0 2>&1 | _filter_qemu_nbd_exports
+
+echo
+echo "== check TLS fail over TCP with mismatched hostname =="
+obj1=tls-creds-x509,dir=${tls_dir}/client1,endpoint=client,id=tls0
+$QEMU_IMG info --image-opts --object $obj1 \
+ driver=nbd,host=localhost,port=$nbd_tcp_port,tls-creds=tls0 \
+ 2>&1 | _filter_nbd
+$QEMU_NBD_PROG -L -b localhost -p $nbd_tcp_port --object $obj1 \
+ --tls-creds=tls0 | _filter_qemu_nbd_exports
+
+echo
+echo "== check TLS works over TCP with mismatched hostname and override =="
+obj1=tls-creds-x509,dir=${tls_dir}/client1,endpoint=client,id=tls0
+$QEMU_IMG info --image-opts --object $obj1 \
+ driver=nbd,host=localhost,port=$nbd_tcp_port,tls-creds=tls0,tls-hostname=127.0.0.1 \
+ 2>&1 | _filter_nbd
+$QEMU_NBD_PROG -L -b localhost -p $nbd_tcp_port --object $obj1 \
+ --tls-creds=tls0 --tls-hostname=127.0.0.1 | _filter_qemu_nbd_exports
echo
echo "== check TLS with different CA fails =="
obj=tls-creds-x509,dir=${tls_dir}/client2,endpoint=client,id=tls0
$QEMU_IMG info --image-opts --object $obj \
driver=nbd,host=$nbd_tcp_addr,port=$nbd_tcp_port,tls-creds=tls0 \
- 2>&1 | sed "s/$nbd_tcp_port/PORT/g"
+ 2>&1 | _filter_nbd
$QEMU_NBD_PROG -L -b $nbd_tcp_addr -p $nbd_tcp_port --object $obj \
- --tls-creds=tls0
+ --tls-creds=tls0 2>&1 | _filter_qemu_nbd_exports
echo
echo "== perform I/O over TLS =="
@@ -121,7 +143,8 @@ $QEMU_IO -c 'r -P 0x11 1m 1m' -c 'w -P 0x22 1m 1m' --image-opts \
driver=nbd,host=$nbd_tcp_addr,port=$nbd_tcp_port,tls-creds=tls0 \
2>&1 | _filter_qemu_io
-$QEMU_IO -f $IMGFMT -r -U -c 'r -P 0x22 1m 1m' "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -f $IMGFMT -r -U -c 'r -P 0x22 1m 1m' "$TEST_IMG" \
+ 2>&1 | _filter_qemu_io
echo
echo "== check TLS with authorization =="
@@ -139,12 +162,62 @@ nbd_server_start_tcp_socket \
$QEMU_IMG info --image-opts \
--object tls-creds-x509,dir=${tls_dir}/client1,endpoint=client,id=tls0 \
driver=nbd,host=$nbd_tcp_addr,port=$nbd_tcp_port,tls-creds=tls0 \
- 2>&1 | sed "s/$nbd_tcp_port/PORT/g"
+ 2>&1 | _filter_nbd
$QEMU_IMG info --image-opts \
--object tls-creds-x509,dir=${tls_dir}/client3,endpoint=client,id=tls0 \
driver=nbd,host=$nbd_tcp_addr,port=$nbd_tcp_port,tls-creds=tls0 \
- 2>&1 | sed "s/$nbd_tcp_port/PORT/g"
+ 2>&1 | _filter_nbd
+
+nbd_server_stop
+
+nbd_server_start_unix_socket \
+ --object tls-creds-x509,dir=${tls_dir}/server1,endpoint=server,id=tls0,verify-peer=on \
+ --tls-creds tls0 \
+ -f $IMGFMT "$TEST_IMG" 2>> "$TEST_DIR/server.log"
+
+echo
+echo "== check TLS fail over UNIX with no hostname =="
+obj1=tls-creds-x509,dir=${tls_dir}/client1,endpoint=client,id=tls0
+$QEMU_IMG info --image-opts --object $obj1 \
+ driver=nbd,path=$nbd_unix_socket,tls-creds=tls0 2>&1 | _filter_nbd
+$QEMU_NBD_PROG -L -k $nbd_unix_socket --object $obj1 --tls-creds=tls0 \
+ 2>&1 | _filter_qemu_nbd_exports
+
+echo
+echo "== check TLS works over UNIX with hostname override =="
+obj1=tls-creds-x509,dir=${tls_dir}/client1,endpoint=client,id=tls0
+$QEMU_IMG info --image-opts --object $obj1 \
+ driver=nbd,path=$nbd_unix_socket,tls-creds=tls0,tls-hostname=127.0.0.1 \
+ 2>&1 | _filter_nbd
+$QEMU_NBD_PROG -L -k $nbd_unix_socket --object $obj1 \
+ --tls-creds=tls0 --tls-hostname=127.0.0.1 2>&1 | _filter_qemu_nbd_exports
+
+
+echo
+echo "== check TLS works over UNIX with PSK =="
+nbd_server_stop
+
+nbd_server_start_unix_socket \
+ --object tls-creds-psk,dir=${tls_dir}/psk1,endpoint=server,id=tls0,verify-peer=on \
+ --tls-creds tls0 \
+ -f $IMGFMT "$TEST_IMG" 2>> "$TEST_DIR/server.log"
+
+obj1=tls-creds-psk,dir=${tls_dir}/psk1,username=psk1,endpoint=client,id=tls0
+$QEMU_IMG info --image-opts --object $obj1 \
+ driver=nbd,path=$nbd_unix_socket,tls-creds=tls0 \
+ 2>&1 | _filter_nbd
+$QEMU_NBD_PROG -L -k $nbd_unix_socket --object $obj1 \
+ --tls-creds=tls0 2>&1 | _filter_qemu_nbd_exports
+
+echo
+echo "== check TLS fails over UNIX with mismatch PSK =="
+obj1=tls-creds-psk,dir=${tls_dir}/psk2,username=psk2,endpoint=client,id=tls0
+$QEMU_IMG info --image-opts --object $obj1 \
+ driver=nbd,path=$nbd_unix_socket,tls-creds=tls0 \
+ 2>&1 | _filter_nbd
+$QEMU_NBD_PROG -L -k $nbd_unix_socket --object $obj1 \
+ --tls-creds=tls0 2>&1 | _filter_qemu_nbd_exports
echo
echo "== final server log =="
diff --git a/tests/qemu-iotests/233.out b/tests/qemu-iotests/233.out
index 4b1f6a0..237c827 100644
--- a/tests/qemu-iotests/233.out
+++ b/tests/qemu-iotests/233.out
@@ -7,6 +7,8 @@ Generating a signed certificate...
Generating a signed certificate...
Generating a signed certificate...
Generating a signed certificate...
+Generating a random key for user 'psk1'
+Generating a random key for user 'psk2'
== preparing image ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
@@ -17,15 +19,12 @@ wrote 1048576/1048576 bytes at offset 1048576
qemu-img: Could not open 'driver=nbd,host=127.0.0.1,port=PORT,tls-creds=tls0': Denied by server for option 5 (starttls)
server reported: TLS not configured
qemu-nbd: Denied by server for option 5 (starttls)
-server reported: TLS not configured
== check plain client to TLS server fails ==
qemu-img: Could not open 'nbd://localhost:PORT': TLS negotiation required before option 7 (go)
Did you forget a valid tls-creds?
server reported: Option 0x7 not permitted before TLS
qemu-nbd: TLS negotiation required before option 3 (list)
-Did you forget a valid tls-creds?
-server reported: Option 0x3 not permitted before TLS
== check TLS works ==
image: nbd://127.0.0.1:PORT
@@ -39,12 +38,21 @@ disk size: unavailable
exports available: 1
export: ''
size: 67108864
- flags: 0xced ( flush fua trim zeroes df cache fast-zero )
min block: 1
- opt block: 4096
- max block: 33554432
- available meta contexts: 1
- base:allocation
+
+== check TLS fail over TCP with mismatched hostname ==
+qemu-img: Could not open 'driver=nbd,host=localhost,port=PORT,tls-creds=tls0': Certificate does not match the hostname localhost
+qemu-nbd: Certificate does not match the hostname localhost
+
+== check TLS works over TCP with mismatched hostname and override ==
+image: nbd://localhost:PORT
+file format: nbd
+virtual size: 64 MiB (67108864 bytes)
+disk size: unavailable
+exports available: 1
+ export: ''
+ size: 67108864
+ min block: 1
== check TLS with different CA fails ==
qemu-img: Could not open 'driver=nbd,host=127.0.0.1,port=PORT,tls-creds=tls0': The certificate hasn't got a known issuer
@@ -62,9 +70,43 @@ read 1048576/1048576 bytes at offset 1048576
qemu-img: Could not open 'driver=nbd,host=127.0.0.1,port=PORT,tls-creds=tls0': Failed to read option reply: Cannot read from TLS channel: Software caused connection abort
qemu-img: Could not open 'driver=nbd,host=127.0.0.1,port=PORT,tls-creds=tls0': Failed to read option reply: Cannot read from TLS channel: Software caused connection abort
+== check TLS fail over UNIX with no hostname ==
+qemu-img: Could not open 'driver=nbd,path=SOCK_DIR/qemu-nbd.sock,tls-creds=tls0': No hostname for certificate validation
+qemu-nbd: No hostname for certificate validation
+
+== check TLS works over UNIX with hostname override ==
+image: nbd+unix://?socket=SOCK_DIR/qemu-nbd.sock
+file format: nbd
+virtual size: 64 MiB (67108864 bytes)
+disk size: unavailable
+exports available: 1
+ export: ''
+ size: 67108864
+ min block: 1
+
+== check TLS works over UNIX with PSK ==
+image: nbd+unix://?socket=SOCK_DIR/qemu-nbd.sock
+file format: nbd
+virtual size: 64 MiB (67108864 bytes)
+disk size: unavailable
+exports available: 1
+ export: ''
+ size: 67108864
+ min block: 1
+
+== check TLS fails over UNIX with mismatch PSK ==
+qemu-img: Could not open 'driver=nbd,path=SOCK_DIR/qemu-nbd.sock,tls-creds=tls0': TLS handshake failed: The TLS connection was non-properly terminated.
+qemu-nbd: TLS handshake failed: The TLS connection was non-properly terminated.
+
== final server log ==
+qemu-nbd: option negotiation failed: Failed to read opts magic: Cannot read from TLS channel: Software caused connection abort
+qemu-nbd: option negotiation failed: Failed to read opts magic: Cannot read from TLS channel: Software caused connection abort
qemu-nbd: option negotiation failed: Verify failed: No certificate was found.
qemu-nbd: option negotiation failed: Verify failed: No certificate was found.
qemu-nbd: option negotiation failed: TLS x509 authz check for DISTINGUISHED-NAME is denied
qemu-nbd: option negotiation failed: TLS x509 authz check for DISTINGUISHED-NAME is denied
+qemu-nbd: option negotiation failed: Failed to read opts magic: Cannot read from TLS channel: Software caused connection abort
+qemu-nbd: option negotiation failed: Failed to read opts magic: Cannot read from TLS channel: Software caused connection abort
+qemu-nbd: option negotiation failed: TLS handshake failed: An illegal parameter has been received.
+qemu-nbd: option negotiation failed: TLS handshake failed: An illegal parameter has been received.
*** done
diff --git a/tests/qemu-iotests/241 b/tests/qemu-iotests/241
index c962c8b..f196650 100755
--- a/tests/qemu-iotests/241
+++ b/tests/qemu-iotests/241
@@ -58,7 +58,7 @@ echo
nbd_server_start_unix_socket -f $IMGFMT "$TEST_IMG_FILE"
-$QEMU_NBD_PROG --list -k $nbd_unix_socket | grep '\(size\|min\)'
+$QEMU_NBD_PROG --list -k $nbd_unix_socket | _filter_qemu_nbd_exports
$QEMU_IMG map -f raw --output=json "$TEST_IMG" | _filter_qemu_img_map
$QEMU_IO -f raw -c map "$TEST_IMG"
nbd_server_stop
@@ -71,7 +71,7 @@ echo
# sector alignment, here at the server.
nbd_server_start_unix_socket "$TEST_IMG_FILE" 2> "$TEST_DIR/server.log"
-$QEMU_NBD_PROG --list -k $nbd_unix_socket | grep '\(size\|min\)'
+$QEMU_NBD_PROG --list -k $nbd_unix_socket | _filter_qemu_nbd_exports
$QEMU_IMG map -f raw --output=json "$TEST_IMG" | _filter_qemu_img_map
$QEMU_IO -f raw -c map "$TEST_IMG"
nbd_server_stop
@@ -84,7 +84,7 @@ echo
# Now force sector alignment at the client.
nbd_server_start_unix_socket -f $IMGFMT "$TEST_IMG_FILE"
-$QEMU_NBD_PROG --list -k $nbd_unix_socket | grep '\(size\|min\)'
+$QEMU_NBD_PROG --list -k $nbd_unix_socket | _filter_qemu_nbd_exports
$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
$QEMU_IO -c map "$TEST_IMG"
nbd_server_stop
diff --git a/tests/qemu-iotests/241.out b/tests/qemu-iotests/241.out
index 56e95b5..88e8cfc 100644
--- a/tests/qemu-iotests/241.out
+++ b/tests/qemu-iotests/241.out
@@ -2,6 +2,8 @@ QA output created by 241
=== Exporting unaligned raw image, natural alignment ===
+exports available: 1
+ export: ''
size: 1024
min block: 1
[{ "start": 0, "length": 1000, "depth": 0, "present": true, "zero": false, "data": true, "offset": OFFSET},
@@ -10,6 +12,8 @@ QA output created by 241
=== Exporting unaligned raw image, forced server sector alignment ===
+exports available: 1
+ export: ''
size: 1024
min block: 512
[{ "start": 0, "length": 1024, "depth": 0, "present": true, "zero": false, "data": true, "offset": OFFSET}]
@@ -20,6 +24,8 @@ WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed
=== Exporting unaligned raw image, forced client sector alignment ===
+exports available: 1
+ export: ''
size: 1024
min block: 1
[{ "start": 0, "length": 1000, "depth": 0, "present": true, "zero": false, "data": true, "offset": OFFSET},
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
index 21819db..9790411 100644
--- a/tests/qemu-iotests/common.filter
+++ b/tests/qemu-iotests/common.filter
@@ -301,10 +301,19 @@ _filter_nbd()
# Filter out the TCP port number since this changes between runs.
sed -e '/nbd\/.*\.c:/d' \
-e 's#127\.0\.0\.1:[0-9]*#127.0.0.1:PORT#g' \
+ -e 's#localhost:[0-9]*#localhost:PORT#g' \
+ -e 's#host=127\.0\.0\.1,port=[0-9]*#host=127.0.0.1,port=PORT#g' \
+ -e 's#host=localhost,port=[0-9]*#host=localhost,port=PORT#g' \
+ -e "s#path=$SOCK_DIR#path=SOCK_DIR#g" \
-e "s#?socket=$SOCK_DIR#?socket=SOCK_DIR#g" \
-e 's#\(foo\|PORT/\?\|.sock\): Failed to .*$#\1#'
}
+_filter_qemu_nbd_exports()
+{
+ grep '\(exports available\|export\|size\|min block\|qemu-nbd\):'
+}
+
_filter_qmp_empty_return()
{
grep -v '{"return": {}}'
diff --git a/tests/qemu-iotests/common.tls b/tests/qemu-iotests/common.tls
index 6ba28a7..b9c5462 100644
--- a/tests/qemu-iotests/common.tls
+++ b/tests/qemu-iotests/common.tls
@@ -24,6 +24,7 @@ tls_x509_cleanup()
{
rm -f "${tls_dir}"/*.pem
rm -f "${tls_dir}"/*/*.pem
+ rm -f "${tls_dir}"/*/*.psk
rmdir "${tls_dir}"/*
rmdir "${tls_dir}"
}
@@ -40,6 +41,18 @@ tls_certtool()
rm -f "${tls_dir}"/certtool.log
}
+tls_psktool()
+{
+ psktool "$@" 1>"${tls_dir}"/psktool.log 2>&1
+ if test "$?" = 0; then
+ head -1 "${tls_dir}"/psktool.log
+ else
+ cat "${tls_dir}"/psktool.log
+ fi
+ rm -f "${tls_dir}"/psktool.log
+}
+
+
tls_x509_init()
{
(certtool --help) >/dev/null 2>&1 || \
@@ -118,12 +131,13 @@ tls_x509_create_server()
caname=$1
name=$2
+ # We don't include 'localhost' in the cert, as
+ # we want to keep it unlisted to let tests
+ # validate hostname override
mkdir -p "${tls_dir}/$name"
cat > "${tls_dir}/cert.info" <<EOF
organization = Cthulhu Dark Lord Enterprises $name
-cn = localhost
-dns_name = localhost
-dns_name = localhost.localdomain
+cn = iotests.qemu.org
ip_address = 127.0.0.1
ip_address = ::1
tls_www_server
@@ -175,3 +189,14 @@ EOF
rm -f "${tls_dir}/cert.info"
}
+
+tls_psk_create_creds()
+{
+ name=$1
+
+ mkdir -p "${tls_dir}/$name"
+
+ tls_psktool \
+ --pskfile "${tls_dir}/$name/keys.psk" \
+ --username "$name"
+}
diff --git a/tests/qemu-iotests/testrunner.py b/tests/qemu-iotests/testrunner.py
index 41083ff..5c20722 100644
--- a/tests/qemu-iotests/testrunner.py
+++ b/tests/qemu-iotests/testrunner.py
@@ -25,6 +25,7 @@ import subprocess
import contextlib
import json
import termios
+import shutil
import sys
from multiprocessing import Pool
from contextlib import contextmanager
@@ -322,6 +323,11 @@ class TestRunner(ContextManager['TestRunner']):
diff = file_diff(str(f_reference), str(f_bad))
if diff:
+ if os.environ.get("QEMU_IOTESTS_REGEN", None) is not None:
+ shutil.copyfile(str(f_bad), str(f_reference))
+ print("########################################")
+ print("##### REFERENCE FILE UPDATED #####")
+ print("########################################")
return TestResult(status='fail', elapsed=elapsed,
description=f'output mismatch (see {f_bad})',
diff=diff, casenotrun=casenotrun)
diff --git a/tests/qtest/isl_pmbus_vr-test.c b/tests/qtest/isl_pmbus_vr-test.c
new file mode 100644
index 0000000..5553ea4
--- /dev/null
+++ b/tests/qtest/isl_pmbus_vr-test.c
@@ -0,0 +1,474 @@
+/*
+ * QTests for the ISL_PMBUS digital voltage regulators
+ *
+ * Copyright 2021 Google LLC
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+#include "qemu/osdep.h"
+#include <math.h>
+#include "hw/i2c/pmbus_device.h"
+#include "hw/sensor/isl_pmbus_vr.h"
+#include "libqtest-single.h"
+#include "libqos/qgraph.h"
+#include "libqos/i2c.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qnum.h"
+#include "qemu/bitops.h"
+
+#define TEST_ID "isl_pmbus_vr-test"
+#define TEST_ADDR (0x43)
+
+static uint16_t qmp_isl_pmbus_vr_get(const char *id, const char *property)
+{
+ QDict *response;
+ uint64_t ret;
+
+ response = qmp("{ 'execute': 'qom-get', 'arguments': { 'path': %s, "
+ "'property': %s } }", id, property);
+ g_assert(qdict_haskey(response, "return"));
+ ret = qnum_get_uint(qobject_to(QNum, qdict_get(response, "return")));
+ qobject_unref(response);
+ return ret;
+}
+
+static void qmp_isl_pmbus_vr_set(const char *id,
+ const char *property,
+ uint16_t value)
+{
+ QDict *response;
+
+ response = qmp("{ 'execute': 'qom-set', 'arguments': { 'path': %s, "
+ "'property': %s, 'value': %u } }", id, property, value);
+ g_assert(qdict_haskey(response, "return"));
+ qobject_unref(response);
+}
+
+/* PMBus commands are little endian vs i2c_set16 in i2c.h which is big endian */
+static uint16_t isl_pmbus_vr_i2c_get16(QI2CDevice *i2cdev, uint8_t reg)
+{
+ uint8_t resp[2];
+ i2c_read_block(i2cdev, reg, resp, sizeof(resp));
+ return (resp[1] << 8) | resp[0];
+}
+
+/* PMBus commands are little endian vs i2c_set16 in i2c.h which is big endian */
+static void isl_pmbus_vr_i2c_set16(QI2CDevice *i2cdev, uint8_t reg,
+ uint16_t value)
+{
+ uint8_t data[2];
+
+ data[0] = value & 255;
+ data[1] = value >> 8;
+ i2c_write_block(i2cdev, reg, data, sizeof(data));
+}
+
+static void test_defaults(void *obj, void *data, QGuestAllocator *alloc)
+{
+ uint16_t value, i2c_value;
+ QI2CDevice *i2cdev = (QI2CDevice *)obj;
+
+ value = qmp_isl_pmbus_vr_get(TEST_ID, "vout[0]");
+ g_assert_cmpuint(value, ==, ISL_READ_VOUT_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_IOUT);
+ g_assert_cmpuint(i2c_value, ==, ISL_READ_IOUT_DEFAULT);
+
+ value = qmp_isl_pmbus_vr_get(TEST_ID, "pout[0]");
+ g_assert_cmpuint(value, ==, ISL_READ_POUT_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_VIN);
+ g_assert_cmpuint(i2c_value, ==, ISL_READ_VIN_DEFAULT);
+
+ value = qmp_isl_pmbus_vr_get(TEST_ID, "iin[0]");
+ g_assert_cmpuint(value, ==, ISL_READ_IIN_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_PIN);
+ g_assert_cmpuint(i2c_value, ==, ISL_READ_PIN_DEFAULT);
+
+ value = qmp_isl_pmbus_vr_get(TEST_ID, "temp1[0]");
+ g_assert_cmpuint(value, ==, ISL_READ_TEMP_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_TEMPERATURE_2);
+ g_assert_cmpuint(i2c_value, ==, ISL_READ_TEMP_DEFAULT);
+
+ i2c_value = i2c_get8(i2cdev, PMBUS_CAPABILITY);
+ g_assert_cmphex(i2c_value, ==, ISL_CAPABILITY_DEFAULT);
+
+ i2c_value = i2c_get8(i2cdev, PMBUS_OPERATION);
+ g_assert_cmphex(i2c_value, ==, ISL_OPERATION_DEFAULT);
+
+ i2c_value = i2c_get8(i2cdev, PMBUS_ON_OFF_CONFIG);
+ g_assert_cmphex(i2c_value, ==, ISL_ON_OFF_CONFIG_DEFAULT);
+
+ i2c_value = i2c_get8(i2cdev, PMBUS_VOUT_MODE);
+ g_assert_cmphex(i2c_value, ==, ISL_VOUT_MODE_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_COMMAND);
+ g_assert_cmphex(i2c_value, ==, ISL_VOUT_COMMAND_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_MAX);
+ g_assert_cmphex(i2c_value, ==, ISL_VOUT_MAX_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_MARGIN_HIGH);
+ g_assert_cmphex(i2c_value, ==, ISL_VOUT_MARGIN_HIGH_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_MARGIN_LOW);
+ g_assert_cmphex(i2c_value, ==, ISL_VOUT_MARGIN_LOW_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_TRANSITION_RATE);
+ g_assert_cmphex(i2c_value, ==, ISL_VOUT_TRANSITION_RATE_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_OV_FAULT_LIMIT);
+ g_assert_cmphex(i2c_value, ==, ISL_VOUT_OV_FAULT_LIMIT_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_OT_FAULT_LIMIT);
+ g_assert_cmphex(i2c_value, ==, ISL_OT_FAULT_LIMIT_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_OT_WARN_LIMIT);
+ g_assert_cmphex(i2c_value, ==, ISL_OT_WARN_LIMIT_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VIN_OV_WARN_LIMIT);
+ g_assert_cmphex(i2c_value, ==, ISL_VIN_OV_WARN_LIMIT_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VIN_UV_WARN_LIMIT);
+ g_assert_cmphex(i2c_value, ==, ISL_VIN_UV_WARN_LIMIT_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_IIN_OC_FAULT_LIMIT);
+ g_assert_cmphex(i2c_value, ==, ISL_IIN_OC_FAULT_LIMIT_DEFAULT);
+
+ i2c_value = i2c_get8(i2cdev, PMBUS_REVISION);
+ g_assert_cmphex(i2c_value, ==, ISL_REVISION_DEFAULT);
+}
+
+static void raa228000_test_defaults(void *obj, void *data,
+ QGuestAllocator *alloc)
+{
+ uint16_t value, i2c_value;
+ QI2CDevice *i2cdev = (QI2CDevice *)obj;
+
+ value = qmp_isl_pmbus_vr_get(TEST_ID, "vout[0]");
+ g_assert_cmpuint(value, ==, 0);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_IOUT);
+ g_assert_cmpuint(i2c_value, ==, 0);
+
+ value = qmp_isl_pmbus_vr_get(TEST_ID, "pout[0]");
+ g_assert_cmpuint(value, ==, 0);
+
+ i2c_value = i2c_get8(i2cdev, PMBUS_CAPABILITY);
+ g_assert_cmphex(i2c_value, ==, ISL_CAPABILITY_DEFAULT);
+
+ i2c_value = i2c_get8(i2cdev, PMBUS_OPERATION);
+ g_assert_cmphex(i2c_value, ==, ISL_OPERATION_DEFAULT);
+
+ i2c_value = i2c_get8(i2cdev, PMBUS_ON_OFF_CONFIG);
+ g_assert_cmphex(i2c_value, ==, ISL_ON_OFF_CONFIG_DEFAULT);
+
+ i2c_value = i2c_get8(i2cdev, PMBUS_VOUT_MODE);
+ g_assert_cmphex(i2c_value, ==, ISL_VOUT_MODE_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_COMMAND);
+ g_assert_cmphex(i2c_value, ==, ISL_VOUT_COMMAND_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_MAX);
+ g_assert_cmphex(i2c_value, ==, ISL_VOUT_MAX_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_MARGIN_HIGH);
+ g_assert_cmphex(i2c_value, ==, ISL_VOUT_MARGIN_HIGH_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_MARGIN_LOW);
+ g_assert_cmphex(i2c_value, ==, ISL_VOUT_MARGIN_LOW_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_TRANSITION_RATE);
+ g_assert_cmphex(i2c_value, ==, ISL_VOUT_TRANSITION_RATE_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_OV_FAULT_LIMIT);
+ g_assert_cmphex(i2c_value, ==, ISL_VOUT_OV_FAULT_LIMIT_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_OT_FAULT_LIMIT);
+ g_assert_cmphex(i2c_value, ==, ISL_OT_FAULT_LIMIT_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_OT_WARN_LIMIT);
+ g_assert_cmphex(i2c_value, ==, ISL_OT_WARN_LIMIT_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VIN_OV_WARN_LIMIT);
+ g_assert_cmphex(i2c_value, ==, ISL_VIN_OV_WARN_LIMIT_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VIN_UV_WARN_LIMIT);
+ g_assert_cmphex(i2c_value, ==, ISL_VIN_UV_WARN_LIMIT_DEFAULT);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_IIN_OC_FAULT_LIMIT);
+ g_assert_cmphex(i2c_value, ==, ISL_IIN_OC_FAULT_LIMIT_DEFAULT);
+
+ i2c_value = i2c_get8(i2cdev, PMBUS_REVISION);
+ g_assert_cmphex(i2c_value, ==, ISL_REVISION_DEFAULT);
+}
+
+/* test qmp access */
+static void test_tx_rx(void *obj, void *data, QGuestAllocator *alloc)
+{
+ uint16_t i2c_value, value;
+ QI2CDevice *i2cdev = (QI2CDevice *)obj;
+
+ qmp_isl_pmbus_vr_set(TEST_ID, "vin[0]", 200);
+ value = qmp_isl_pmbus_vr_get(TEST_ID, "vin[0]");
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_VIN);
+ g_assert_cmpuint(value, ==, i2c_value);
+
+ qmp_isl_pmbus_vr_set(TEST_ID, "vout[0]", 2500);
+ value = qmp_isl_pmbus_vr_get(TEST_ID, "vout[0]");
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_VOUT);
+ g_assert_cmpuint(value, ==, i2c_value);
+
+ qmp_isl_pmbus_vr_set(TEST_ID, "iin[0]", 300);
+ value = qmp_isl_pmbus_vr_get(TEST_ID, "iin[0]");
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_IIN);
+ g_assert_cmpuint(value, ==, i2c_value);
+
+ qmp_isl_pmbus_vr_set(TEST_ID, "iout[0]", 310);
+ value = qmp_isl_pmbus_vr_get(TEST_ID, "iout[0]");
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_IOUT);
+ g_assert_cmpuint(value, ==, i2c_value);
+
+ qmp_isl_pmbus_vr_set(TEST_ID, "pin[0]", 100);
+ value = qmp_isl_pmbus_vr_get(TEST_ID, "pin[0]");
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_PIN);
+ g_assert_cmpuint(value, ==, i2c_value);
+
+ qmp_isl_pmbus_vr_set(TEST_ID, "pout[0]", 95);
+ value = qmp_isl_pmbus_vr_get(TEST_ID, "pout[0]");
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_POUT);
+ g_assert_cmpuint(value, ==, i2c_value);
+
+ qmp_isl_pmbus_vr_set(TEST_ID, "temp1[0]", 26);
+ value = qmp_isl_pmbus_vr_get(TEST_ID, "temp1[0]");
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_TEMPERATURE_1);
+ g_assert_cmpuint(value, ==, i2c_value);
+
+ qmp_isl_pmbus_vr_set(TEST_ID, "temp2[0]", 27);
+ value = qmp_isl_pmbus_vr_get(TEST_ID, "temp2[0]");
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_TEMPERATURE_2);
+ g_assert_cmpuint(value, ==, i2c_value);
+
+ qmp_isl_pmbus_vr_set(TEST_ID, "temp3[0]", 28);
+ value = qmp_isl_pmbus_vr_get(TEST_ID, "temp3[0]");
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_TEMPERATURE_3);
+ g_assert_cmpuint(value, ==, i2c_value);
+
+}
+
+/* test r/w registers */
+static void test_rw_regs(void *obj, void *data, QGuestAllocator *alloc)
+{
+ uint16_t i2c_value;
+ QI2CDevice *i2cdev = (QI2CDevice *)obj;
+
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VOUT_COMMAND, 0x1234);
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_COMMAND);
+ g_assert_cmphex(i2c_value, ==, 0x1234);
+
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VOUT_TRIM, 0x4567);
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_TRIM);
+ g_assert_cmphex(i2c_value, ==, 0x4567);
+
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VOUT_MAX, 0x9876);
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_MAX);
+ g_assert_cmphex(i2c_value, ==, 0x9876);
+
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VOUT_MARGIN_HIGH, 0xABCD);
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_MARGIN_HIGH);
+ g_assert_cmphex(i2c_value, ==, 0xABCD);
+
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VOUT_MARGIN_LOW, 0xA1B2);
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_MARGIN_LOW);
+ g_assert_cmphex(i2c_value, ==, 0xA1B2);
+
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VOUT_TRANSITION_RATE, 0xDEF1);
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_TRANSITION_RATE);
+ g_assert_cmphex(i2c_value, ==, 0xDEF1);
+
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VOUT_DROOP, 0x5678);
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_DROOP);
+ g_assert_cmphex(i2c_value, ==, 0x5678);
+
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VOUT_MIN, 0x1234);
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_MIN);
+ g_assert_cmphex(i2c_value, ==, 0x1234);
+
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VOUT_OV_FAULT_LIMIT, 0x2345);
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_OV_FAULT_LIMIT);
+ g_assert_cmphex(i2c_value, ==, 0x2345);
+
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VOUT_UV_FAULT_LIMIT, 0xFA12);
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VOUT_UV_FAULT_LIMIT);
+ g_assert_cmphex(i2c_value, ==, 0xFA12);
+
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_OT_FAULT_LIMIT, 0xF077);
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_OT_FAULT_LIMIT);
+ g_assert_cmphex(i2c_value, ==, 0xF077);
+
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_OT_WARN_LIMIT, 0x7137);
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_OT_WARN_LIMIT);
+ g_assert_cmphex(i2c_value, ==, 0x7137);
+
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VIN_OV_FAULT_LIMIT, 0x3456);
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VIN_OV_FAULT_LIMIT);
+ g_assert_cmphex(i2c_value, ==, 0x3456);
+
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VIN_UV_FAULT_LIMIT, 0xBADA);
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_VIN_UV_FAULT_LIMIT);
+ g_assert_cmphex(i2c_value, ==, 0xBADA);
+
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_IIN_OC_FAULT_LIMIT, 0xB1B0);
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_IIN_OC_FAULT_LIMIT);
+ g_assert_cmphex(i2c_value, ==, 0xB1B0);
+
+ i2c_set8(i2cdev, PMBUS_OPERATION, 0xA);
+ i2c_value = i2c_get8(i2cdev, PMBUS_OPERATION);
+ g_assert_cmphex(i2c_value, ==, 0xA);
+
+ i2c_set8(i2cdev, PMBUS_ON_OFF_CONFIG, 0x42);
+ i2c_value = i2c_get8(i2cdev, PMBUS_ON_OFF_CONFIG);
+ g_assert_cmphex(i2c_value, ==, 0x42);
+}
+
+/* test that devices with multiple pages can switch between them */
+static void test_pages_rw(void *obj, void *data, QGuestAllocator *alloc)
+{
+ uint16_t i2c_value;
+ QI2CDevice *i2cdev = (QI2CDevice *)obj;
+
+ i2c_set8(i2cdev, PMBUS_PAGE, 1);
+ i2c_value = i2c_get8(i2cdev, PMBUS_PAGE);
+ g_assert_cmphex(i2c_value, ==, 1);
+
+ i2c_set8(i2cdev, PMBUS_PAGE, 0);
+ i2c_value = i2c_get8(i2cdev, PMBUS_PAGE);
+ g_assert_cmphex(i2c_value, ==, 0);
+}
+
+/* test read-only registers */
+static void test_ro_regs(void *obj, void *data, QGuestAllocator *alloc)
+{
+ uint16_t i2c_init_value, i2c_value;
+ QI2CDevice *i2cdev = (QI2CDevice *)obj;
+
+ i2c_init_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_VIN);
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_READ_VIN, 0xBEEF);
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_VIN);
+ g_assert_cmphex(i2c_init_value, ==, i2c_value);
+
+ i2c_init_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_IIN);
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_READ_IIN, 0xB00F);
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_IIN);
+ g_assert_cmphex(i2c_init_value, ==, i2c_value);
+
+ i2c_init_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_VOUT);
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_READ_VOUT, 0x1234);
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_VOUT);
+ g_assert_cmphex(i2c_init_value, ==, i2c_value);
+
+ i2c_init_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_IOUT);
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_READ_IOUT, 0x6547);
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_IOUT);
+ g_assert_cmphex(i2c_init_value, ==, i2c_value);
+
+ i2c_init_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_TEMPERATURE_1);
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_READ_TEMPERATURE_1, 0x1597);
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_TEMPERATURE_1);
+ g_assert_cmphex(i2c_init_value, ==, i2c_value);
+
+ i2c_init_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_TEMPERATURE_2);
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_READ_TEMPERATURE_2, 0x1897);
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_TEMPERATURE_2);
+ g_assert_cmphex(i2c_init_value, ==, i2c_value);
+
+ i2c_init_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_TEMPERATURE_3);
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_READ_TEMPERATURE_3, 0x1007);
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_TEMPERATURE_3);
+ g_assert_cmphex(i2c_init_value, ==, i2c_value);
+
+ i2c_init_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_PIN);
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_READ_PIN, 0xDEAD);
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_PIN);
+ g_assert_cmphex(i2c_init_value, ==, i2c_value);
+
+ i2c_init_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_POUT);
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_READ_POUT, 0xD00D);
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_READ_POUT);
+ g_assert_cmphex(i2c_init_value, ==, i2c_value);
+}
+
+/* test voltage fault handling */
+static void test_voltage_faults(void *obj, void *data, QGuestAllocator *alloc)
+{
+ uint16_t i2c_value;
+ uint8_t i2c_byte;
+ QI2CDevice *i2cdev = (QI2CDevice *)obj;
+
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VOUT_OV_WARN_LIMIT, 5000);
+ qmp_isl_pmbus_vr_set(TEST_ID, "vout[0]", 5100);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_STATUS_WORD);
+ i2c_byte = i2c_get8(i2cdev, PMBUS_STATUS_VOUT);
+ g_assert_true((i2c_value & PB_STATUS_VOUT) != 0);
+ g_assert_true((i2c_byte & PB_STATUS_VOUT_OV_WARN) != 0);
+
+ qmp_isl_pmbus_vr_set(TEST_ID, "vout[0]", 4500);
+ i2c_set8(i2cdev, PMBUS_CLEAR_FAULTS, 0);
+ i2c_byte = i2c_get8(i2cdev, PMBUS_STATUS_VOUT);
+ g_assert_true((i2c_byte & PB_STATUS_VOUT_OV_WARN) == 0);
+
+ isl_pmbus_vr_i2c_set16(i2cdev, PMBUS_VOUT_UV_WARN_LIMIT, 4600);
+
+ i2c_value = isl_pmbus_vr_i2c_get16(i2cdev, PMBUS_STATUS_WORD);
+ i2c_byte = i2c_get8(i2cdev, PMBUS_STATUS_VOUT);
+ g_assert_true((i2c_value & PB_STATUS_VOUT) != 0);
+ g_assert_true((i2c_byte & PB_STATUS_VOUT_UV_WARN) != 0);
+
+}
+
+static void isl_pmbus_vr_register_nodes(void)
+{
+ QOSGraphEdgeOptions opts = {
+ .extra_device_opts = "id=" TEST_ID ",address=0x43"
+ };
+ add_qi2c_address(&opts, &(QI2CAddress) { TEST_ADDR });
+
+ qos_node_create_driver("isl69260", i2c_device_create);
+ qos_node_consumes("isl69260", "i2c-bus", &opts);
+
+ qos_add_test("test_defaults", "isl69260", test_defaults, NULL);
+ qos_add_test("test_tx_rx", "isl69260", test_tx_rx, NULL);
+ qos_add_test("test_rw_regs", "isl69260", test_rw_regs, NULL);
+ qos_add_test("test_pages_rw", "isl69260", test_pages_rw, NULL);
+ qos_add_test("test_ro_regs", "isl69260", test_ro_regs, NULL);
+ qos_add_test("test_ov_faults", "isl69260", test_voltage_faults, NULL);
+
+ qos_node_create_driver("raa229004", i2c_device_create);
+ qos_node_consumes("raa229004", "i2c-bus", &opts);
+
+ qos_add_test("test_tx_rx", "raa229004", test_tx_rx, NULL);
+ qos_add_test("test_rw_regs", "raa229004", test_rw_regs, NULL);
+ qos_add_test("test_pages_rw", "raa229004", test_pages_rw, NULL);
+ qos_add_test("test_ov_faults", "raa229004", test_voltage_faults, NULL);
+
+ qos_node_create_driver("raa228000", i2c_device_create);
+ qos_node_consumes("raa228000", "i2c-bus", &opts);
+
+ qos_add_test("test_defaults", "raa228000", raa228000_test_defaults, NULL);
+ qos_add_test("test_tx_rx", "raa228000", test_tx_rx, NULL);
+ qos_add_test("test_rw_regs", "raa228000", test_rw_regs, NULL);
+ qos_add_test("test_ov_faults", "raa228000", test_voltage_faults, NULL);
+}
+libqos_init(isl_pmbus_vr_register_nodes);
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 721eafa..7d8c74f 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -245,6 +245,7 @@ qos_test_ss.add(
'es1370-test.c',
'ipoctal232-test.c',
'lsm303dlhc-mag-test.c',
+ 'isl_pmbus_vr-test.c',
'max34451-test.c',
'megasas-test.c',
'ne2000-test.c',
diff --git a/tests/tcg/ppc64le/signal_save_restore_xer.c b/tests/tcg/ppc64le/signal_save_restore_xer.c
index e4f8a07..9227f4f 100644
--- a/tests/tcg/ppc64le/signal_save_restore_xer.c
+++ b/tests/tcg/ppc64le/signal_save_restore_xer.c
@@ -11,7 +11,7 @@
uint64_t saved;
-void sigill_handler(int sig, siginfo_t *si, void *ucontext)
+void sigtrap_handler(int sig, siginfo_t *si, void *ucontext)
{
ucontext_t *uc = ucontext;
uc->uc_mcontext.regs->nip += 4;
@@ -23,14 +23,14 @@ int main(void)
{
uint64_t initial = XER_CA | XER_CA32, restored;
struct sigaction sa = {
- .sa_sigaction = sigill_handler,
+ .sa_sigaction = sigtrap_handler,
.sa_flags = SA_SIGINFO
};
- sigaction(SIGILL, &sa, NULL);
+ sigaction(SIGTRAP, &sa, NULL);
asm("mtspr 1, %1\n\t"
- ".long 0x0\n\t"
+ "trap\n\t"
"mfspr %0, 1\n\t"
: "=r" (restored)
: "r" (initial));