Misc hardware patch queue

HW emulation:
 - PMBus fixes and tests (Titus)
 - IDE fixes and tests (Fiona)
 - New ADM1266 sensor (Titus)
 - Better error propagation in PCI-ISA i82378 (Philippe)
 - Declare SD model QOM types using DEFINE_TYPES macro (Philippe)
 
 Topology:
 - Fix CPUState::nr_cores calculation (Zhuocheng Ding and Zhao Liu)
 
 Monitor:
 - Synchronize CPU state in 'info lapic' (Dongli Zhang)
 
 QOM:
 - Have 'cpu-qom.h' target-agnostic (Philippe)
 - Move ArchCPUClass definition to each target's cpu.h (Philippe)
 - Call object_class_is_abstract once in cpu_class_by_name (Philippe)
 
 UI:
 - Use correct key names in titles on MacOS / SDL2 (Adrian)
 
 MIPS:
 - Fix MSA BZ/BNZ and TX79 LQ/SQ opcodes (Philippe)
 
 Nios2:
 - Create IRQs *after* vCPU is realized (Philippe)
 
 PPC:
 - Restrict KVM objects to system emulation (Philippe)
 - Move target-specific definitions out of 'cpu-qom.h' (Philippe)
 
 S390X:
 - Make hw/s390x/css.h and hw/s390x/sclp.h headers target agnostic (Philippe)
 
 X86:
 - HVF & KVM cleanups (Philippe)
 
 Various targets:
 - Use env_archcpu() to optimize (Philippe)
 
 Misc:
 - Few global variable shadowing removed (Philippe)
 - Introduce cpu_exec_reset_hold and factor tcg_cpu_reset_hold out (Philippe)
 - Remove few more 'softmmu' mentions (Philippe)
 - Fix and cleanup in vl.c (Akihiko & Marc-André)
 - Resource leak fix in dump (Zongmin Zhou)
 - MAINTAINERS updates (Thomas, Daniel)
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmVKKmEACgkQ4+MsLN6t
 wN4xHQ//X/enH4C7K3VP/tSinDiwmXN2o61L9rjqSDQkBaCtktZx4c8qKSDL7V4S
 vwzmvvBn3biMXQwZNVJo9d0oz2qoaF9tI6Ao0XDHAan9ziagfG9YMqWhkCfj077Q
 jLdCqkUuMJBvQgXGB1a6UgCme8PQx7h0oqjbCNfB0ZBls24b5DiEjO87LE4OTbTi
 zKRhYEpZpGwIVcy+1dAsbaBpGFP06sr1doB9Wz4c06eSx7t0kFSPk6U4CyOPrGXh
 ynyCxPwngxIXmarY8gqPs3SBs7oXsH8Q/ZOHr1LbuXhwSuw/0zBQU9aF7Ir8RPan
 DB79JjPrtxTAhICKredWT79v9M18D2/1MpONgg4vtx5K2FzGYoAJULCHyfkHMRSM
 L6/H0ZQPHvf7w72k9EcSQIhd0wPlMqRmfy37/8xcLiw1h4l/USx48QeKaeFWeSEu
 DgwSk+R61HbrKvQz/U0tF98zUEyBaQXNrKmyzht0YE4peAtpbPNBeRHkd0GMae/Z
 HOmkt8QlFQ0T14qSK7mSHaSJTUzRvFGD01cbuCDxVsyCWWsesEikXBACZLG5RCRY
 Rn1WeX1H9eE3kKi9iueLnhzcF9yM5XqFE3f6RnDzY8nkg91lsTMSQgFcIpv6uGyp
 3WOTNSC9SoFyI3x8pCWiKOGytPUb8xk+PnOA85wYvVmT+7j6wus=
 =OVdQ
 -----END PGP SIGNATURE-----

Merge tag 'misc-cpus-20231107' of https://github.com/philmd/qemu into staging

Misc hardware patch queue

HW emulation:
- PMBus fixes and tests (Titus)
- IDE fixes and tests (Fiona)
- New ADM1266 sensor (Titus)
- Better error propagation in PCI-ISA i82378 (Philippe)
- Declare SD model QOM types using DEFINE_TYPES macro (Philippe)

Topology:
- Fix CPUState::nr_cores calculation (Zhuocheng Ding and Zhao Liu)

Monitor:
- Synchronize CPU state in 'info lapic' (Dongli Zhang)

QOM:
- Have 'cpu-qom.h' target-agnostic (Philippe)
- Move ArchCPUClass definition to each target's cpu.h (Philippe)
- Call object_class_is_abstract once in cpu_class_by_name (Philippe)

UI:
- Use correct key names in titles on MacOS / SDL2 (Adrian)

MIPS:
- Fix MSA BZ/BNZ and TX79 LQ/SQ opcodes (Philippe)

Nios2:
- Create IRQs *after* vCPU is realized (Philippe)

PPC:
- Restrict KVM objects to system emulation (Philippe)
- Move target-specific definitions out of 'cpu-qom.h' (Philippe)

S390X:
- Make hw/s390x/css.h and hw/s390x/sclp.h headers target agnostic (Philippe)

X86:
- HVF & KVM cleanups (Philippe)

Various targets:
- Use env_archcpu() to optimize (Philippe)

Misc:
- Few global variable shadowing removed (Philippe)
- Introduce cpu_exec_reset_hold and factor tcg_cpu_reset_hold out (Philippe)
- Remove few more 'softmmu' mentions (Philippe)
- Fix and cleanup in vl.c (Akihiko & Marc-André)
- Resource leak fix in dump (Zongmin Zhou)
- MAINTAINERS updates (Thomas, Daniel)

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmVKKmEACgkQ4+MsLN6t
# wN4xHQ//X/enH4C7K3VP/tSinDiwmXN2o61L9rjqSDQkBaCtktZx4c8qKSDL7V4S
# vwzmvvBn3biMXQwZNVJo9d0oz2qoaF9tI6Ao0XDHAan9ziagfG9YMqWhkCfj077Q
# jLdCqkUuMJBvQgXGB1a6UgCme8PQx7h0oqjbCNfB0ZBls24b5DiEjO87LE4OTbTi
# zKRhYEpZpGwIVcy+1dAsbaBpGFP06sr1doB9Wz4c06eSx7t0kFSPk6U4CyOPrGXh
# ynyCxPwngxIXmarY8gqPs3SBs7oXsH8Q/ZOHr1LbuXhwSuw/0zBQU9aF7Ir8RPan
# DB79JjPrtxTAhICKredWT79v9M18D2/1MpONgg4vtx5K2FzGYoAJULCHyfkHMRSM
# L6/H0ZQPHvf7w72k9EcSQIhd0wPlMqRmfy37/8xcLiw1h4l/USx48QeKaeFWeSEu
# DgwSk+R61HbrKvQz/U0tF98zUEyBaQXNrKmyzht0YE4peAtpbPNBeRHkd0GMae/Z
# HOmkt8QlFQ0T14qSK7mSHaSJTUzRvFGD01cbuCDxVsyCWWsesEikXBACZLG5RCRY
# Rn1WeX1H9eE3kKi9iueLnhzcF9yM5XqFE3f6RnDzY8nkg91lsTMSQgFcIpv6uGyp
# 3WOTNSC9SoFyI3x8pCWiKOGytPUb8xk+PnOA85wYvVmT+7j6wus=
# =OVdQ
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 07 Nov 2023 20:15:29 HKT
# gpg:                using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE
# gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full]
# Primary key fingerprint: FAAB E75E 1291 7221 DCFD  6BB2 E3E3 2C2C DEAD C0DE

* tag 'misc-cpus-20231107' of https://github.com/philmd/qemu: (75 commits)
  dump: Add close fd on error return to avoid resource leak
  ui/sdl2: use correct key names in win title on mac
  MAINTAINERS: Add more guest-agent related files to the corresponding section
  MAINTAINERS: Add include/hw/xtensa/mx_pic.h to the XTFPGA machine section
  MAINTAINERS: update libvirt devel mailing list address
  MAINTAINERS: Add the CAN documentation file to the CAN section
  MAINTAINERS: Add include/hw/timer/tmu012.h to the SH4 R2D section
  hw/sd: Declare QOM types using DEFINE_TYPES() macro
  hw/i2c: pmbus: reset page register for out of range reads
  hw/i2c: pmbus: immediately clear faults on request
  tests/qtest: add tests for ADM1266
  hw/sensor: add ADM1266 device model
  hw/i2c: pmbus: add VCAP register
  hw/i2c: pmbus: add fan support
  hw/i2c: pmbus: add vout mode bitfields
  hw/i2c: pmbus add support for block receive
  tests/qtest: ahci-test: add test exposing reset issue with pending callback
  hw/ide: reset: cancel async DMA operation before resetting state
  hw/cpu: Update the comments of nr_cores and nr_dies
  system/cpus: Fix CPUState.nr_cores' calculation
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi 2023-11-08 08:32:26 +08:00
commit ed1d873caa
134 changed files with 1722 additions and 1085 deletions

View file

@ -491,6 +491,7 @@ config NPCM7XX
default y
depends on TCG && ARM
select A9MPCORE
select ADM1266
select ADM1272
select ARM_GIC
select SMBUS

View file

@ -136,10 +136,7 @@ static void cpu_common_reset_hold(Object *obj)
cpu->crash_occurred = false;
cpu->cflags_next_tb = -1;
if (tcg_enabled()) {
tcg_flush_jmp_cache(cpu);
tcg_flush_softmmu_tlb(cpu);
}
cpu_exec_reset_hold(cpu);
}
static bool cpu_common_has_work(CPUState *cs)
@ -149,10 +146,18 @@ static bool cpu_common_has_work(CPUState *cs)
ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model)
{
CPUClass *cc = CPU_CLASS(object_class_by_name(typename));
ObjectClass *oc;
CPUClass *cc;
assert(cpu_model && cc->class_by_name);
return cc->class_by_name(cpu_model);
oc = object_class_by_name(typename);
cc = CPU_CLASS(oc);
assert(cc->class_by_name);
assert(cpu_model);
oc = cc->class_by_name(cpu_model);
if (oc == NULL || object_class_is_abstract(oc)) {
return NULL;
}
return oc;
}
static void cpu_common_parse_features(const char *typename, char *features,

View file

@ -1070,7 +1070,7 @@ static void *rom_set_mr(Rom *rom, Object *owner, const char *name, bool ro)
ssize_t rom_add_file(const char *file, const char *fw_dir,
hwaddr addr, int32_t bootindex,
bool option_rom, MemoryRegion *mr,
bool has_option_rom, MemoryRegion *mr,
AddressSpace *as)
{
MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
@ -1139,7 +1139,7 @@ ssize_t rom_add_file(const char *file, const char *fw_dir,
basename);
snprintf(devpath, sizeof(devpath), "/rom@%s", fw_file_name);
if ((!option_rom || mc->option_rom_has_mr) && mc->rom_file_has_mr) {
if ((!has_option_rom || mc->option_rom_has_mr) && mc->rom_file_has_mr) {
data = rom_set_mr(rom, OBJECT(fw_cfg), devpath, true);
} else {
data = rom->data;

View file

@ -102,7 +102,6 @@ void pmbus_send_string(PMBusDevice *pmdev, const char *data)
}
size_t len = strlen(data);
g_assert(len > 0);
g_assert(len + pmdev->out_buf_len < SMBUS_DATA_MAX_LEN);
pmdev->out_buf[len + pmdev->out_buf_len] = len;
@ -112,6 +111,35 @@ void pmbus_send_string(PMBusDevice *pmdev, const char *data)
pmdev->out_buf_len += len + 1;
}
uint8_t pmbus_receive_block(PMBusDevice *pmdev, uint8_t *dest, size_t len)
{
/* dest may contain data from previous writes */
memset(dest, 0, len);
/* Exclude command code from return value */
pmdev->in_buf++;
pmdev->in_buf_len--;
/* The byte after the command code denotes the length */
uint8_t sent_len = pmdev->in_buf[0];
if (sent_len != pmdev->in_buf_len - 1) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: length mismatch. Expected %d bytes, got %d bytes\n",
__func__, sent_len, pmdev->in_buf_len - 1);
}
/* exclude length byte */
pmdev->in_buf++;
pmdev->in_buf_len--;
if (pmdev->in_buf_len < len) {
len = pmdev->in_buf_len;
}
memcpy(dest, pmdev->in_buf, len);
return len;
}
static uint64_t pmbus_receive_uint(PMBusDevice *pmdev)
{
@ -472,6 +500,54 @@ static uint8_t pmbus_receive_byte(SMBusDevice *smd)
}
break;
case PMBUS_FAN_CONFIG_1_2: /* R/W byte */
if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
pmbus_send8(pmdev, pmdev->pages[index].fan_config_1_2);
} else {
goto passthough;
}
break;
case PMBUS_FAN_COMMAND_1: /* R/W word */
if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
pmbus_send16(pmdev, pmdev->pages[index].fan_command_1);
} else {
goto passthough;
}
break;
case PMBUS_FAN_COMMAND_2: /* R/W word */
if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
pmbus_send16(pmdev, pmdev->pages[index].fan_command_2);
} else {
goto passthough;
}
break;
case PMBUS_FAN_CONFIG_3_4: /* R/W byte */
if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
pmbus_send8(pmdev, pmdev->pages[index].fan_config_3_4);
} else {
goto passthough;
}
break;
case PMBUS_FAN_COMMAND_3: /* R/W word */
if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
pmbus_send16(pmdev, pmdev->pages[index].fan_command_3);
} else {
goto passthough;
}
break;
case PMBUS_FAN_COMMAND_4: /* R/W word */
if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
pmbus_send16(pmdev, pmdev->pages[index].fan_command_4);
} else {
goto passthough;
}
break;
case PMBUS_VOUT_OV_FAULT_LIMIT: /* R/W word */
if (pmdev->pages[index].page_flags & PB_HAS_VOUT) {
pmbus_send16(pmdev, pmdev->pages[index].vout_ov_fault_limit);
@ -782,6 +858,22 @@ static uint8_t pmbus_receive_byte(SMBusDevice *smd)
pmbus_send8(pmdev, pmdev->pages[index].status_mfr_specific);
break;
case PMBUS_STATUS_FANS_1_2: /* R/W byte */
if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
pmbus_send8(pmdev, pmdev->pages[index].status_fans_1_2);
} else {
goto passthough;
}
break;
case PMBUS_STATUS_FANS_3_4: /* R/W byte */
if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
pmbus_send8(pmdev, pmdev->pages[index].status_fans_3_4);
} else {
goto passthough;
}
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);
@ -814,6 +906,14 @@ static uint8_t pmbus_receive_byte(SMBusDevice *smd)
}
break;
case PMBUS_READ_VCAP: /* Read-Only word */
if (pmdev->pages[index].page_flags & PB_HAS_VCAP) {
pmbus_send16(pmdev, pmdev->pages[index].read_vcap);
} else {
goto passthough;
}
break;
case PMBUS_READ_VOUT: /* Read-Only word */
if (pmdev->pages[index].page_flags & PB_HAS_VOUT) {
pmbus_send16(pmdev, pmdev->pages[index].read_vout);
@ -854,6 +954,54 @@ static uint8_t pmbus_receive_byte(SMBusDevice *smd)
}
break;
case PMBUS_READ_FAN_SPEED_1: /* Read-Only word */
if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
pmbus_send16(pmdev, pmdev->pages[index].read_fan_speed_1);
} else {
goto passthough;
}
break;
case PMBUS_READ_FAN_SPEED_2: /* Read-Only word */
if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
pmbus_send16(pmdev, pmdev->pages[index].read_fan_speed_2);
} else {
goto passthough;
}
break;
case PMBUS_READ_FAN_SPEED_3: /* Read-Only word */
if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
pmbus_send16(pmdev, pmdev->pages[index].read_fan_speed_3);
} else {
goto passthough;
}
break;
case PMBUS_READ_FAN_SPEED_4: /* Read-Only word */
if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
pmbus_send16(pmdev, pmdev->pages[index].read_fan_speed_4);
} else {
goto passthough;
}
break;
case PMBUS_READ_DUTY_CYCLE: /* Read-Only word */
if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
pmbus_send16(pmdev, pmdev->pages[index].read_duty_cycle);
} else {
goto passthough;
}
break;
case PMBUS_READ_FREQUENCY: /* Read-Only word */
if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
pmbus_send16(pmdev, pmdev->pages[index].read_frequency);
} else {
goto passthough;
}
break;
case PMBUS_READ_POUT: /* Read-Only word */
if (pmdev->pages[index].page_flags & PB_HAS_POUT) {
pmbus_send16(pmdev, pmdev->pages[index].read_pout);
@ -1096,12 +1244,26 @@ static int pmbus_write_data(SMBusDevice *smd, uint8_t *buf, uint8_t len)
pmdev->in_buf = buf;
pmdev->code = buf[0]; /* PMBus command code */
if (pmdev->code == PMBUS_CLEAR_FAULTS) {
pmbus_clear_faults(pmdev);
}
if (len == 1) { /* Single length writes are command codes only */
return 0;
}
if (pmdev->code == PMBUS_PAGE) {
pmdev->page = pmbus_receive8(pmdev);
if (pmdev->page > pmdev->num_pages - 1 && pmdev->page != PB_ALL_PAGES) {
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;
}
return 0;
}
@ -1115,15 +1277,6 @@ 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) {
@ -1277,6 +1430,54 @@ static int pmbus_write_data(SMBusDevice *smd, uint8_t *buf, uint8_t len)
}
break;
case PMBUS_FAN_CONFIG_1_2: /* R/W byte */
if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
pmdev->pages[index].fan_config_1_2 = pmbus_receive8(pmdev);
} else {
goto passthrough;
}
break;
case PMBUS_FAN_COMMAND_1: /* R/W word */
if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
pmdev->pages[index].fan_command_1 = pmbus_receive16(pmdev);
} else {
goto passthrough;
}
break;
case PMBUS_FAN_COMMAND_2: /* R/W word */
if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
pmdev->pages[index].fan_command_2 = pmbus_receive16(pmdev);
} else {
goto passthrough;
}
break;
case PMBUS_FAN_CONFIG_3_4: /* R/W byte */
if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
pmdev->pages[index].fan_config_3_4 = pmbus_receive8(pmdev);
} else {
goto passthrough;
}
break;
case PMBUS_FAN_COMMAND_3: /* R/W word */
if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
pmdev->pages[index].fan_command_3 = pmbus_receive16(pmdev);
} else {
goto passthrough;
}
break;
case PMBUS_FAN_COMMAND_4: /* R/W word */
if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
pmdev->pages[index].fan_command_4 = pmbus_receive16(pmdev);
} else {
goto passthrough;
}
break;
case PMBUS_VOUT_OV_FAULT_LIMIT: /* R/W word */
if (pmdev->pages[index].page_flags & PB_HAS_VOUT) {
pmdev->pages[index].vout_ov_fault_limit = pmbus_receive16(pmdev);
@ -1582,6 +1783,22 @@ static int pmbus_write_data(SMBusDevice *smd, uint8_t *buf, uint8_t len)
pmdev->pages[index].status_mfr_specific = pmbus_receive8(pmdev);
break;
case PMBUS_STATUS_FANS_1_2: /* R/W byte */
if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
pmbus_send8(pmdev, pmdev->pages[index].status_fans_1_2);
} else {
goto passthrough;
}
break;
case PMBUS_STATUS_FANS_3_4: /* R/W byte */
if (pmdev->pages[index].page_flags & PB_HAS_FAN) {
pmbus_send8(pmdev, pmdev->pages[index].status_fans_3_4);
} else {
goto passthrough;
}
break;
case PMBUS_PAGE_PLUS_READ: /* Block Read-only */
case PMBUS_CAPABILITY: /* Read-Only byte */
case PMBUS_COEFFICIENTS: /* Read-only block 5 bytes */

View file

@ -2515,19 +2515,19 @@ static void ide_dummy_transfer_stop(IDEState *s)
void ide_bus_reset(IDEBus *bus)
{
bus->unit = 0;
bus->cmd = 0;
ide_reset(&bus->ifs[0]);
ide_reset(&bus->ifs[1]);
ide_clear_hob(bus);
/* pending async DMA */
/* pending async DMA - needs the IDEState before it is reset */
if (bus->dma->aiocb) {
trace_ide_bus_reset_aio();
blk_aio_cancel(bus->dma->aiocb);
bus->dma->aiocb = NULL;
}
bus->unit = 0;
bus->cmd = 0;
ide_reset(&bus->ifs[0]);
ide_reset(&bus->ifs[1]);
ide_clear_hob(bus);
/* reset dma provider too */
if (bus->dma->ops->reset) {
bus->dma->ops->reset(bus->dma);

View file

@ -105,7 +105,9 @@ static void i82378_realize(PCIDevice *pci, Error **errp)
/* speaker */
pcspk = isa_new(TYPE_PC_SPEAKER);
object_property_set_link(OBJECT(pcspk), "pit", OBJECT(pit), &error_fatal);
isa_realize_and_unref(pcspk, isabus, &error_fatal);
if (!isa_realize_and_unref(pcspk, isabus, errp)) {
return;
}
/* 2 82C37 (dma) */
isa_create_simple(isabus, "i82374");

View file

@ -834,6 +834,7 @@ static DeviceState *ppce500_init_mpic_qemu(PPCE500MachineState *pms,
static DeviceState *ppce500_init_mpic_kvm(const PPCE500MachineClass *pmc,
IrqLines *irqs, Error **errp)
{
#ifdef CONFIG_KVM
DeviceState *dev;
CPUState *cs;
@ -854,6 +855,9 @@ static DeviceState *ppce500_init_mpic_kvm(const PPCE500MachineClass *pmc,
}
return dev;
#else
g_assert_not_reached();
#endif
}
static DeviceState *ppce500_init_mpic(PPCE500MachineState *pms,

View file

@ -644,8 +644,9 @@ void css_conditional_io_interrupt(SubchDev *sch)
}
}
int css_do_sic(CPUS390XState *env, uint8_t isc, uint16_t mode)
int css_do_sic(S390CPU *cpu, uint8_t isc, uint16_t mode)
{
CPUS390XState *env = &cpu->env;
S390FLICState *fs = s390_get_flic();
S390FLICStateClass *fsc = s390_get_flic_class(fs);
int r;

View file

@ -269,9 +269,9 @@ static void sclp_execute(SCLPDevice *sclp, SCCB *sccb, uint32_t code)
* service_interrupt call.
*/
#define SCLP_PV_DUMMY_ADDR 0x4000
int sclp_service_call_protected(CPUS390XState *env, uint64_t sccb,
uint32_t code)
int sclp_service_call_protected(S390CPU *cpu, uint64_t sccb, uint32_t code)
{
CPUS390XState *env = &cpu->env;
SCLPDevice *sclp = get_sclp_device();
SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
SCCBHeader header;
@ -296,8 +296,9 @@ out_write:
return 0;
}
int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code)
int sclp_service_call(S390CPU *cpu, uint64_t sccb, uint32_t code)
{
CPUS390XState *env = &cpu->env;
SCLPDevice *sclp = get_sclp_device();
SCLPDeviceClass *sclp_c = SCLP_GET_CLASS(sclp);
SCCBHeader header;

View file

@ -198,16 +198,13 @@ static void aspeed_sdhci_class_init(ObjectClass *classp, void *data)
device_class_set_props(dc, aspeed_sdhci_properties);
}
static const TypeInfo aspeed_sdhci_info = {
.name = TYPE_ASPEED_SDHCI,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(AspeedSDHCIState),
.class_init = aspeed_sdhci_class_init,
static const TypeInfo aspeed_sdhci_types[] = {
{
.name = TYPE_ASPEED_SDHCI,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(AspeedSDHCIState),
.class_init = aspeed_sdhci_class_init,
},
};
static void aspeed_sdhci_register_types(void)
{
type_register_static(&aspeed_sdhci_info);
}
type_init(aspeed_sdhci_register_types)
DEFINE_TYPES(aspeed_sdhci_types)

View file

@ -436,24 +436,19 @@ static void bcm2835_sdhost_class_init(ObjectClass *klass, void *data)
dc->vmsd = &vmstate_bcm2835_sdhost;
}
static const TypeInfo bcm2835_sdhost_info = {
.name = TYPE_BCM2835_SDHOST,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(BCM2835SDHostState),
.class_init = bcm2835_sdhost_class_init,
.instance_init = bcm2835_sdhost_init,
static const TypeInfo bcm2835_sdhost_types[] = {
{
.name = TYPE_BCM2835_SDHOST,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(BCM2835SDHostState),
.class_init = bcm2835_sdhost_class_init,
.instance_init = bcm2835_sdhost_init,
},
{
.name = TYPE_BCM2835_SDHOST_BUS,
.parent = TYPE_SD_BUS,
.instance_size = sizeof(SDBus),
},
};
static const TypeInfo bcm2835_sdhost_bus_info = {
.name = TYPE_BCM2835_SDHOST_BUS,
.parent = TYPE_SD_BUS,
.instance_size = sizeof(SDBus),
};
static void bcm2835_sdhost_register_types(void)
{
type_register_static(&bcm2835_sdhost_info);
type_register_static(&bcm2835_sdhost_bus_info);
}
type_init(bcm2835_sdhost_register_types)
DEFINE_TYPES(bcm2835_sdhost_types)

View file

@ -175,17 +175,14 @@ static void cadence_sdhci_class_init(ObjectClass *classp, void *data)
dc->vmsd = &vmstate_cadence_sdhci;
}
static const TypeInfo cadence_sdhci_info = {
.name = TYPE_CADENCE_SDHCI,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(CadenceSDHCIState),
.instance_init = cadence_sdhci_instance_init,
.class_init = cadence_sdhci_class_init,
static const TypeInfo cadence_sdhci_types[] = {
{
.name = TYPE_CADENCE_SDHCI,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(CadenceSDHCIState),
.instance_init = cadence_sdhci_instance_init,
.class_init = cadence_sdhci_class_init,
},
};
static void cadence_sdhci_register_types(void)
{
type_register_static(&cadence_sdhci_info);
}
type_init(cadence_sdhci_register_types)
DEFINE_TYPES(cadence_sdhci_types)

View file

@ -259,16 +259,13 @@ void sdbus_reparent_card(SDBus *from, SDBus *to)
sdbus_set_readonly(to, readonly);
}
static const TypeInfo sd_bus_info = {
.name = TYPE_SD_BUS,
.parent = TYPE_BUS,
.instance_size = sizeof(SDBus),
.class_size = sizeof(SDBusClass),
static const TypeInfo sd_bus_types[] = {
{
.name = TYPE_SD_BUS,
.parent = TYPE_BUS,
.instance_size = sizeof(SDBus),
.class_size = sizeof(SDBusClass),
},
};
static void sd_bus_register_types(void)
{
type_register_static(&sd_bus_info);
}
type_init(sd_bus_register_types)
DEFINE_TYPES(sd_bus_types)

View file

@ -166,17 +166,14 @@ static void npcm7xx_sdhci_instance_init(Object *obj)
TYPE_SYSBUS_SDHCI);
}
static const TypeInfo npcm7xx_sdhci_info = {
.name = TYPE_NPCM7XX_SDHCI,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(NPCM7xxSDHCIState),
.instance_init = npcm7xx_sdhci_instance_init,
.class_init = npcm7xx_sdhci_class_init,
static const TypeInfo npcm7xx_sdhci_types[] = {
{
.name = TYPE_NPCM7XX_SDHCI,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(NPCM7xxSDHCIState),
.instance_init = npcm7xx_sdhci_instance_init,
.class_init = npcm7xx_sdhci_class_init,
},
};
static void npcm7xx_sdhci_register_types(void)
{
type_register_static(&npcm7xx_sdhci_info);
}
type_init(npcm7xx_sdhci_register_types)
DEFINE_TYPES(npcm7xx_sdhci_types)

View file

@ -519,14 +519,6 @@ static void pl181_class_init(ObjectClass *klass, void *data)
k->user_creatable = false;
}
static const TypeInfo pl181_info = {
.name = TYPE_PL181,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(PL181State),
.instance_init = pl181_init,
.class_init = pl181_class_init,
};
static void pl181_bus_class_init(ObjectClass *klass, void *data)
{
SDBusClass *sbc = SD_BUS_CLASS(klass);
@ -535,17 +527,20 @@ static void pl181_bus_class_init(ObjectClass *klass, void *data)
sbc->set_readonly = pl181_set_readonly;
}
static const TypeInfo pl181_bus_info = {
.name = TYPE_PL181_BUS,
.parent = TYPE_SD_BUS,
.instance_size = sizeof(SDBus),
.class_init = pl181_bus_class_init,
static const TypeInfo pl181_info[] = {
{
.name = TYPE_PL181,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(PL181State),
.instance_init = pl181_init,
.class_init = pl181_class_init,
},
{
.name = TYPE_PL181_BUS,
.parent = TYPE_SD_BUS,
.instance_size = sizeof(SDBus),
.class_init = pl181_bus_class_init,
},
};
static void pl181_register_types(void)
{
type_register_static(&pl181_info);
type_register_static(&pl181_bus_info);
}
type_init(pl181_register_types)
DEFINE_TYPES(pl181_info)

View file

@ -575,25 +575,20 @@ static void pxa2xx_mmci_bus_class_init(ObjectClass *klass, void *data)
sbc->set_readonly = pxa2xx_mmci_set_readonly;
}
static const TypeInfo pxa2xx_mmci_info = {
.name = TYPE_PXA2XX_MMCI,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(PXA2xxMMCIState),
.instance_init = pxa2xx_mmci_instance_init,
.class_init = pxa2xx_mmci_class_init,
static const TypeInfo pxa2xx_mmci_types[] = {
{
.name = TYPE_PXA2XX_MMCI,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(PXA2xxMMCIState),
.instance_init = pxa2xx_mmci_instance_init,
.class_init = pxa2xx_mmci_class_init,
},
{
.name = TYPE_PXA2XX_MMCI_BUS,
.parent = TYPE_SD_BUS,
.instance_size = sizeof(SDBus),
.class_init = pxa2xx_mmci_bus_class_init,
},
};
static const TypeInfo pxa2xx_mmci_bus_info = {
.name = TYPE_PXA2XX_MMCI_BUS,
.parent = TYPE_SD_BUS,
.instance_size = sizeof(SDBus),
.class_init = pxa2xx_mmci_bus_class_init,
};
static void pxa2xx_mmci_register_types(void)
{
type_register_static(&pxa2xx_mmci_info);
type_register_static(&pxa2xx_mmci_bus_info);
}
type_init(pxa2xx_mmci_register_types)
DEFINE_TYPES(pxa2xx_mmci_types)

View file

@ -2278,16 +2278,6 @@ static void sd_class_init(ObjectClass *klass, void *data)
sc->proto = &sd_proto_sd;
}
static const TypeInfo sd_info = {
.name = TYPE_SD_CARD,
.parent = TYPE_DEVICE,
.instance_size = sizeof(SDState),
.class_size = sizeof(SDCardClass),
.class_init = sd_class_init,
.instance_init = sd_instance_init,
.instance_finalize = sd_instance_finalize,
};
/*
* We do not model the chip select pin, so allow the board to select
* whether card should be in SSI or MMC/SD mode. It is also up to the
@ -2303,16 +2293,21 @@ static void sd_spi_class_init(ObjectClass *klass, void *data)
sc->proto = &sd_proto_spi;
}
static const TypeInfo sd_spi_info = {
.name = TYPE_SD_CARD_SPI,
.parent = TYPE_SD_CARD,
.class_init = sd_spi_class_init,
static const TypeInfo sd_types[] = {
{
.name = TYPE_SD_CARD,
.parent = TYPE_DEVICE,
.instance_size = sizeof(SDState),
.class_size = sizeof(SDCardClass),
.class_init = sd_class_init,
.instance_init = sd_instance_init,
.instance_finalize = sd_instance_finalize,
},
{
.name = TYPE_SD_CARD_SPI,
.parent = TYPE_SD_CARD,
.class_init = sd_spi_class_init,
},
};
static void sd_register_types(void)
{
type_register_static(&sd_info);
type_register_static(&sd_spi_info);
}
type_init(sd_register_types)
DEFINE_TYPES(sd_types)

View file

@ -68,20 +68,17 @@ static void sdhci_pci_class_init(ObjectClass *klass, void *data)
sdhci_common_class_init(klass, data);
}
static const TypeInfo sdhci_pci_info = {
.name = TYPE_PCI_SDHCI,
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(SDHCIState),
.class_init = sdhci_pci_class_init,
.interfaces = (InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
{ },
static const TypeInfo sdhci_pci_types[] = {
{
.name = TYPE_PCI_SDHCI,
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(SDHCIState),
.class_init = sdhci_pci_class_init,
.interfaces = (InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
{ },
},
},
};
static void sdhci_pci_register_type(void)
{
type_register_static(&sdhci_pci_info);
}
type_init(sdhci_pci_register_type)
DEFINE_TYPES(sdhci_pci_types)

View file

@ -403,16 +403,13 @@ static void ssi_sd_class_init(ObjectClass *klass, void *data)
dc->user_creatable = false;
}
static const TypeInfo ssi_sd_info = {
.name = TYPE_SSI_SD,
.parent = TYPE_SSI_PERIPHERAL,
.instance_size = sizeof(ssi_sd_state),
.class_init = ssi_sd_class_init,
static const TypeInfo ssi_sd_types[] = {
{
.name = TYPE_SSI_SD,
.parent = TYPE_SSI_PERIPHERAL,
.instance_size = sizeof(ssi_sd_state),
.class_init = ssi_sd_class_init,
},
};
static void ssi_sd_register_types(void)
{
type_register_static(&ssi_sd_info);
}
type_init(ssi_sd_register_types)
DEFINE_TYPES(ssi_sd_types)

View file

@ -22,6 +22,11 @@ config ADM1272
bool
depends on I2C
config ADM1266
bool
depends on PMBUS
default y if PMBUS
config MAX34451
bool
depends on I2C

254
hw/sensor/adm1266.c Normal file
View file

@ -0,0 +1,254 @@
/*
* Analog Devices ADM1266 Cascadable Super Sequencer with Margin Control and
* Fault Recording with PMBus
*
* https://www.analog.com/media/en/technical-documentation/data-sheets/adm1266.pdf
*
* Copyright 2023 Google LLC
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "qemu/osdep.h"
#include "hw/i2c/pmbus_device.h"
#include "hw/irq.h"
#include "migration/vmstate.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "qemu/log.h"
#include "qemu/module.h"
#define TYPE_ADM1266 "adm1266"
OBJECT_DECLARE_SIMPLE_TYPE(ADM1266State, ADM1266)
#define ADM1266_BLACKBOX_CONFIG 0xD3
#define ADM1266_PDIO_CONFIG 0xD4
#define ADM1266_READ_STATE 0xD9
#define ADM1266_READ_BLACKBOX 0xDE
#define ADM1266_SET_RTC 0xDF
#define ADM1266_GPIO_SYNC_CONFIGURATION 0xE1
#define ADM1266_BLACKBOX_INFORMATION 0xE6
#define ADM1266_PDIO_STATUS 0xE9
#define ADM1266_GPIO_STATUS 0xEA
/* Defaults */
#define ADM1266_OPERATION_DEFAULT 0x80
#define ADM1266_CAPABILITY_DEFAULT 0xA0
#define ADM1266_CAPABILITY_NO_PEC 0x20
#define ADM1266_PMBUS_REVISION_DEFAULT 0x22
#define ADM1266_MFR_ID_DEFAULT "ADI"
#define ADM1266_MFR_ID_DEFAULT_LEN 32
#define ADM1266_MFR_MODEL_DEFAULT "ADM1266-A1"
#define ADM1266_MFR_MODEL_DEFAULT_LEN 32
#define ADM1266_MFR_REVISION_DEFAULT "25"
#define ADM1266_MFR_REVISION_DEFAULT_LEN 8
#define ADM1266_NUM_PAGES 17
/**
* PAGE Index
* Page 0 VH1.
* Page 1 VH2.
* Page 2 VH3.
* Page 3 VH4.
* Page 4 VP1.
* Page 5 VP2.
* Page 6 VP3.
* Page 7 VP4.
* Page 8 VP5.
* Page 9 VP6.
* Page 10 VP7.
* Page 11 VP8.
* Page 12 VP9.
* Page 13 VP10.
* Page 14 VP11.
* Page 15 VP12.
* Page 16 VP13.
*/
typedef struct ADM1266State {
PMBusDevice parent;
char mfr_id[32];
char mfr_model[32];
char mfr_rev[8];
} ADM1266State;
static const uint8_t adm1266_ic_device_id[] = {0x03, 0x41, 0x12, 0x66};
static const uint8_t adm1266_ic_device_rev[] = {0x08, 0x01, 0x08, 0x07, 0x0,
0x0, 0x07, 0x41, 0x30};
static void adm1266_exit_reset(Object *obj)
{
ADM1266State *s = ADM1266(obj);
PMBusDevice *pmdev = PMBUS_DEVICE(obj);
pmdev->page = 0;
pmdev->capability = ADM1266_CAPABILITY_NO_PEC;
for (int i = 0; i < ADM1266_NUM_PAGES; i++) {
pmdev->pages[i].operation = ADM1266_OPERATION_DEFAULT;
pmdev->pages[i].revision = ADM1266_PMBUS_REVISION_DEFAULT;
pmdev->pages[i].vout_mode = 0;
pmdev->pages[i].read_vout = pmbus_data2linear_mode(12, 0);
pmdev->pages[i].vout_margin_high = pmbus_data2linear_mode(15, 0);
pmdev->pages[i].vout_margin_low = pmbus_data2linear_mode(3, 0);
pmdev->pages[i].vout_ov_fault_limit = pmbus_data2linear_mode(16, 0);
pmdev->pages[i].revision = ADM1266_PMBUS_REVISION_DEFAULT;
}
strncpy(s->mfr_id, ADM1266_MFR_ID_DEFAULT, 4);
strncpy(s->mfr_model, ADM1266_MFR_MODEL_DEFAULT, 11);
strncpy(s->mfr_rev, ADM1266_MFR_REVISION_DEFAULT, 3);
}
static uint8_t adm1266_read_byte(PMBusDevice *pmdev)
{
ADM1266State *s = ADM1266(pmdev);
switch (pmdev->code) {
case PMBUS_MFR_ID: /* R/W block */
pmbus_send_string(pmdev, s->mfr_id);
break;
case PMBUS_MFR_MODEL: /* R/W block */
pmbus_send_string(pmdev, s->mfr_model);
break;
case PMBUS_MFR_REVISION: /* R/W block */
pmbus_send_string(pmdev, s->mfr_rev);
break;
case PMBUS_IC_DEVICE_ID:
pmbus_send(pmdev, adm1266_ic_device_id, sizeof(adm1266_ic_device_id));
break;
case PMBUS_IC_DEVICE_REV:
pmbus_send(pmdev, adm1266_ic_device_rev, sizeof(adm1266_ic_device_rev));
break;
default:
qemu_log_mask(LOG_UNIMP,
"%s: reading from unimplemented register: 0x%02x\n",
__func__, pmdev->code);
return 0xFF;
}
return 0;
}
static int adm1266_write_data(PMBusDevice *pmdev, const uint8_t *buf,
uint8_t len)
{
ADM1266State *s = ADM1266(pmdev);
switch (pmdev->code) {
case PMBUS_MFR_ID: /* R/W block */
pmbus_receive_block(pmdev, (uint8_t *)s->mfr_id, sizeof(s->mfr_id));
break;
case PMBUS_MFR_MODEL: /* R/W block */
pmbus_receive_block(pmdev, (uint8_t *)s->mfr_model,
sizeof(s->mfr_model));
break;
case PMBUS_MFR_REVISION: /* R/W block*/
pmbus_receive_block(pmdev, (uint8_t *)s->mfr_rev, sizeof(s->mfr_rev));
break;
case ADM1266_SET_RTC: /* do nothing */
break;
default:
qemu_log_mask(LOG_UNIMP,
"%s: writing to unimplemented register: 0x%02x\n",
__func__, pmdev->code);
break;
}
return 0;
}
static void adm1266_get(Object *obj, Visitor *v, const char *name, void *opaque,
Error **errp)
{
uint16_t value;
PMBusDevice *pmdev = PMBUS_DEVICE(obj);
PMBusVoutMode *mode = (PMBusVoutMode *)&pmdev->pages[0].vout_mode;
if (strcmp(name, "vout") == 0) {
value = pmbus_linear_mode2data(*(uint16_t *)opaque, mode->exp);
} else {
value = *(uint16_t *)opaque;
}
visit_type_uint16(v, name, &value, errp);
}
static void adm1266_set(Object *obj, Visitor *v, const char *name, void *opaque,
Error **errp)
{
uint16_t *internal = opaque;
uint16_t value;
PMBusDevice *pmdev = PMBUS_DEVICE(obj);
PMBusVoutMode *mode = (PMBusVoutMode *)&pmdev->pages[0].vout_mode;
if (!visit_type_uint16(v, name, &value, errp)) {
return;
}
*internal = pmbus_data2linear_mode(value, mode->exp);
pmbus_check_limits(pmdev);
}
static const VMStateDescription vmstate_adm1266 = {
.name = "ADM1266",
.version_id = 0,
.minimum_version_id = 0,
.fields = (VMStateField[]){
VMSTATE_PMBUS_DEVICE(parent, ADM1266State),
VMSTATE_END_OF_LIST()
}
};
static void adm1266_init(Object *obj)
{
PMBusDevice *pmdev = PMBUS_DEVICE(obj);
uint64_t flags = PB_HAS_VOUT_MODE | PB_HAS_VOUT | PB_HAS_VOUT_MARGIN |
PB_HAS_VOUT_RATING | PB_HAS_STATUS_MFR_SPECIFIC;
for (int i = 0; i < ADM1266_NUM_PAGES; i++) {
pmbus_page_config(pmdev, i, flags);
object_property_add(obj, "vout[*]", "uint16",
adm1266_get,
adm1266_set, NULL, &pmdev->pages[i].read_vout);
}
}
static void adm1266_class_init(ObjectClass *klass, void *data)
{
ResettableClass *rc = RESETTABLE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
PMBusDeviceClass *k = PMBUS_DEVICE_CLASS(klass);
dc->desc = "Analog Devices ADM1266 Hot Swap controller";
dc->vmsd = &vmstate_adm1266;
k->write_data = adm1266_write_data;
k->receive_byte = adm1266_read_byte;
k->device_num_pages = 17;
rc->phases.exit = adm1266_exit_reset;
}
static const TypeInfo adm1266_info = {
.name = TYPE_ADM1266,
.parent = TYPE_PMBUS_DEVICE,
.instance_size = sizeof(ADM1266State),
.instance_init = adm1266_init,
.class_init = adm1266_class_init,
};
static void adm1266_register_types(void)
{
type_register_static(&adm1266_info);
}
type_init(adm1266_register_types)

View file

@ -2,6 +2,7 @@ system_ss.add(when: 'CONFIG_TMP105', if_true: files('tmp105.c'))
system_ss.add(when: 'CONFIG_TMP421', if_true: files('tmp421.c'))
system_ss.add(when: 'CONFIG_DPS310', if_true: files('dps310.c'))
system_ss.add(when: 'CONFIG_EMC141X', if_true: files('emc141x.c'))
system_ss.add(when: 'CONFIG_ADM1266', if_true: files('adm1266.c'))
system_ss.add(when: 'CONFIG_ADM1272', if_true: files('adm1272.c'))
system_ss.add(when: 'CONFIG_MAX34451', if_true: files('max34451.c'))
system_ss.add(when: 'CONFIG_LSM303DLHC_MAG', if_true: files('lsm303dlhc_mag.c'))