* [PULL 01/41] hw/intc: Remove TCG dependency on ARM_GICV3
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 02/41] hw/misc/pvpanic: Add MMIO interface Philippe Mathieu-Daudé
` (39 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Phil Dennis-Jordan
The TYPE_ARM_GICV3 model doesn't have any particular
dependency on TCG, remove it. Rename the Kconfig selector
ARM_GICV3_TCG -> ARM_GICV3.
Fixes: a8a5546798c ("hw/intc/arm_gicv3: Introduce CONFIG_ARM_GIC_TCG Kconfig selector")
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Phil Dennis-Jordan <phil@philjordan.eu>
Tested-by: Phil Dennis-Jordan <phil@philjordan.eu>
Message-Id: <20241227202435.48055-2-philmd@linaro.org>
---
hw/intc/Kconfig | 6 +++---
hw/intc/meson.build | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index dd405bdb5d2..7547528f2c2 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -23,13 +23,13 @@ config APIC
config ARM_GIC
bool
- select ARM_GICV3_TCG if TCG
+ select ARM_GICV3 if TCG
select ARM_GIC_KVM if KVM
select MSI_NONBROKEN
-config ARM_GICV3_TCG
+config ARM_GICV3
bool
- depends on ARM_GIC && TCG
+ depends on ARM_GIC
config ARM_GIC_KVM
bool
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
index 510fdfb6886..602da304b02 100644
--- a/hw/intc/meson.build
+++ b/hw/intc/meson.build
@@ -6,7 +6,7 @@ system_ss.add(when: 'CONFIG_ARM_GIC', if_true: files(
'arm_gicv3_common.c',
'arm_gicv3_its_common.c',
))
-system_ss.add(when: 'CONFIG_ARM_GICV3_TCG', if_true: files(
+system_ss.add(when: 'CONFIG_ARM_GICV3', if_true: files(
'arm_gicv3.c',
'arm_gicv3_dist.c',
'arm_gicv3_its.c',
@@ -39,7 +39,7 @@ endif
specific_ss.add(when: 'CONFIG_APIC', if_true: files('apic.c', 'apic_common.c'))
specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif_common.c'))
-specific_ss.add(when: 'CONFIG_ARM_GICV3_TCG', if_true: files('arm_gicv3_cpuif.c'))
+specific_ss.add(when: 'CONFIG_ARM_GICV3', if_true: files('arm_gicv3_cpuif.c'))
specific_ss.add(when: 'CONFIG_ARM_GIC_KVM', if_true: files('arm_gic_kvm.c'))
specific_ss.add(when: ['CONFIG_ARM_GIC_KVM', 'TARGET_AARCH64'], if_true: files('arm_gicv3_kvm.c', 'arm_gicv3_its_kvm.c'))
specific_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m_nvic.c'))
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 02/41] hw/misc/pvpanic: Add MMIO interface
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 01/41] hw/intc: Remove TCG dependency on ARM_GICV3 Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 03/41] hw: Add vmapple subdir Philippe Mathieu-Daudé
` (38 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, Philippe Mathieu-Daudé, Phil Dennis-Jordan,
Akihiko Odaki
From: Alexander Graf <graf@amazon.com>
In addition to the ISA and PCI variants of pvpanic, let's add an MMIO
platform device that we can use in embedded arm environments.
Signed-off-by: Alexander Graf <graf@amazon.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Message-ID: <20241223221645.29911-8-phil@philjordan.eu>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
include/hw/misc/pvpanic.h | 1 +
hw/misc/pvpanic-mmio.c | 60 +++++++++++++++++++++++++++++++++++++++
hw/misc/Kconfig | 4 +++
hw/misc/meson.build | 1 +
4 files changed, 66 insertions(+)
create mode 100644 hw/misc/pvpanic-mmio.c
diff --git a/include/hw/misc/pvpanic.h b/include/hw/misc/pvpanic.h
index 9a71a5ad0d7..049a94c1125 100644
--- a/include/hw/misc/pvpanic.h
+++ b/include/hw/misc/pvpanic.h
@@ -26,6 +26,7 @@
#define TYPE_PVPANIC_ISA_DEVICE "pvpanic"
#define TYPE_PVPANIC_PCI_DEVICE "pvpanic-pci"
+#define TYPE_PVPANIC_MMIO_DEVICE "pvpanic-mmio"
#define PVPANIC_IOPORT_PROP "ioport"
diff --git a/hw/misc/pvpanic-mmio.c b/hw/misc/pvpanic-mmio.c
new file mode 100644
index 00000000000..70097cecc74
--- /dev/null
+++ b/hw/misc/pvpanic-mmio.c
@@ -0,0 +1,60 @@
+/*
+ * QEMU simulated pvpanic device (MMIO frontend)
+ *
+ * Copyright © 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/qdev-properties.h"
+#include "hw/misc/pvpanic.h"
+#include "hw/sysbus.h"
+#include "standard-headers/misc/pvpanic.h"
+
+OBJECT_DECLARE_SIMPLE_TYPE(PVPanicMMIOState, PVPANIC_MMIO_DEVICE)
+
+#define PVPANIC_MMIO_SIZE 0x2
+
+struct PVPanicMMIOState {
+ SysBusDevice parent_obj;
+
+ PVPanicState pvpanic;
+};
+
+static void pvpanic_mmio_initfn(Object *obj)
+{
+ PVPanicMMIOState *s = PVPANIC_MMIO_DEVICE(obj);
+
+ pvpanic_setup_io(&s->pvpanic, DEVICE(s), PVPANIC_MMIO_SIZE);
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->pvpanic.mr);
+}
+
+static const Property pvpanic_mmio_properties[] = {
+ DEFINE_PROP_UINT8("events", PVPanicMMIOState, pvpanic.events,
+ PVPANIC_PANICKED | PVPANIC_CRASH_LOADED),
+};
+
+static void pvpanic_mmio_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ device_class_set_props(dc, pvpanic_mmio_properties);
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+}
+
+static const TypeInfo pvpanic_mmio_info = {
+ .name = TYPE_PVPANIC_MMIO_DEVICE,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(PVPanicMMIOState),
+ .instance_init = pvpanic_mmio_initfn,
+ .class_init = pvpanic_mmio_class_init,
+};
+
+static void pvpanic_register_types(void)
+{
+ type_register_static(&pvpanic_mmio_info);
+}
+
+type_init(pvpanic_register_types)
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 82bd68b4bb8..ec0fa5aa9f8 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -148,6 +148,10 @@ config PVPANIC_ISA
depends on ISA_BUS
select PVPANIC_COMMON
+config PVPANIC_MMIO
+ bool
+ select PVPANIC_COMMON
+
config AUX
bool
select I2C
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 0b5187a2f74..6d47de482c5 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -126,6 +126,7 @@ system_ss.add(when: 'CONFIG_ARMSSE_MHU', if_true: files('armsse-mhu.c'))
system_ss.add(when: 'CONFIG_PVPANIC_ISA', if_true: files('pvpanic-isa.c'))
system_ss.add(when: 'CONFIG_PVPANIC_PCI', if_true: files('pvpanic-pci.c'))
+system_ss.add(when: 'CONFIG_PVPANIC_MMIO', if_true: files('pvpanic-mmio.c'))
system_ss.add(when: 'CONFIG_AUX', if_true: files('auxbus.c'))
system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files(
'aspeed_hace.c',
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 03/41] hw: Add vmapple subdir
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 01/41] hw/intc: Remove TCG dependency on ARM_GICV3 Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 02/41] hw/misc/pvpanic: Add MMIO interface Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 04/41] hw/vmapple/aes: Introduce aes engine Philippe Mathieu-Daudé
` (37 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, Phil Dennis-Jordan, Akihiko Odaki,
Philippe Mathieu-Daudé
From: Alexander Graf <graf@amazon.com>
We will introduce a number of devices that are specific to the vmapple
target machine. To keep them all tidily together, let's put them into
a single target directory.
Signed-off-by: Alexander Graf <graf@amazon.com>
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Message-ID: <20241223221645.29911-7-phil@philjordan.eu>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
MAINTAINERS | 7 +++++++
meson.build | 1 +
hw/vmapple/trace.h | 2 ++
hw/Kconfig | 1 +
hw/meson.build | 1 +
hw/vmapple/Kconfig | 1 +
hw/vmapple/meson.build | 1 +
hw/vmapple/trace-events | 2 ++
8 files changed, 16 insertions(+)
create mode 100644 hw/vmapple/trace.h
create mode 100644 hw/vmapple/Kconfig
create mode 100644 hw/vmapple/meson.build
create mode 100644 hw/vmapple/trace-events
diff --git a/MAINTAINERS b/MAINTAINERS
index 2e7fc6fa912..0e160360918 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2820,6 +2820,13 @@ F: hw/misc/ivshmem-flat.c
F: include/hw/misc/ivshmem-flat.h
F: docs/system/devices/ivshmem-flat.rst
+VMapple
+M: Alexander Graf <agraf@csgraf.de>
+M: Phil Dennis-Jordan <phil@philjordan.eu>
+S: Maintained
+F: hw/vmapple/*
+F: include/hw/vmapple/*
+
Subsystems
----------
Overall Audio backends
diff --git a/meson.build b/meson.build
index 0a2c61d2bfa..d1b807aa53f 100644
--- a/meson.build
+++ b/meson.build
@@ -3605,6 +3605,7 @@ if have_system
'hw/usb',
'hw/vfio',
'hw/virtio',
+ 'hw/vmapple',
'hw/watchdog',
'hw/xen',
'hw/gpio',
diff --git a/hw/vmapple/trace.h b/hw/vmapple/trace.h
new file mode 100644
index 00000000000..d099d5ecd9e
--- /dev/null
+++ b/hw/vmapple/trace.h
@@ -0,0 +1,2 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include "trace/trace-hw_vmapple.h"
diff --git a/hw/Kconfig b/hw/Kconfig
index 1b4e9bb07f7..2871784cfdc 100644
--- a/hw/Kconfig
+++ b/hw/Kconfig
@@ -41,6 +41,7 @@ source ufs/Kconfig
source usb/Kconfig
source virtio/Kconfig
source vfio/Kconfig
+source vmapple/Kconfig
source xen/Kconfig
source watchdog/Kconfig
diff --git a/hw/meson.build b/hw/meson.build
index b827c82c5d7..9c4f6d0d636 100644
--- a/hw/meson.build
+++ b/hw/meson.build
@@ -39,6 +39,7 @@ subdir('ufs')
subdir('usb')
subdir('vfio')
subdir('virtio')
+subdir('vmapple')
subdir('watchdog')
subdir('xen')
subdir('xenpv')
diff --git a/hw/vmapple/Kconfig b/hw/vmapple/Kconfig
new file mode 100644
index 00000000000..315c06b689c
--- /dev/null
+++ b/hw/vmapple/Kconfig
@@ -0,0 +1 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
diff --git a/hw/vmapple/meson.build b/hw/vmapple/meson.build
new file mode 100644
index 00000000000..315c06b689c
--- /dev/null
+++ b/hw/vmapple/meson.build
@@ -0,0 +1 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
diff --git a/hw/vmapple/trace-events b/hw/vmapple/trace-events
new file mode 100644
index 00000000000..21125794121
--- /dev/null
+++ b/hw/vmapple/trace-events
@@ -0,0 +1,2 @@
+# See docs/devel/tracing.rst for syntax documentation.
+# SPDX-License-Identifier: GPL-2.0-or-later
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 04/41] hw/vmapple/aes: Introduce aes engine
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (2 preceding siblings ...)
2025-03-05 1:21 ` [PULL 03/41] hw: Add vmapple subdir Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 05/41] hw/vmapple/bdif: Introduce vmapple backdoor interface Philippe Mathieu-Daudé
` (36 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, Phil Dennis-Jordan, Akihiko Odaki,
Philippe Mathieu-Daudé
From: Alexander Graf <graf@amazon.com>
VMApple contains an "aes" engine device that it uses to encrypt and
decrypt its nvram. It has trivial hard coded keys it uses for that
purpose.
Add device emulation for this device model.
Signed-off-by: Alexander Graf <graf@amazon.com>
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Message-ID: <20241223221645.29911-10-phil@philjordan.eu>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
include/hw/vmapple/vmapple.h | 17 +
include/qemu/cutils.h | 15 +
hw/vmapple/aes.c | 581 +++++++++++++++++++++++++++++++++++
util/hexdump.c | 18 ++
hw/vmapple/Kconfig | 3 +
hw/vmapple/meson.build | 2 +
hw/vmapple/trace-events | 14 +
7 files changed, 650 insertions(+)
create mode 100644 include/hw/vmapple/vmapple.h
create mode 100644 hw/vmapple/aes.c
diff --git a/include/hw/vmapple/vmapple.h b/include/hw/vmapple/vmapple.h
new file mode 100644
index 00000000000..6762b6c869f
--- /dev/null
+++ b/include/hw/vmapple/vmapple.h
@@ -0,0 +1,17 @@
+/*
+ * Devices specific to the VMApple machine type
+ *
+ * Copyright © 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_VMAPPLE_VMAPPLE_H
+#define HW_VMAPPLE_VMAPPLE_H
+
+#define TYPE_APPLE_AES "apple-aes"
+
+#endif /* HW_VMAPPLE_VMAPPLE_H */
diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h
index 34a9b9b2204..36c68ce86c5 100644
--- a/include/qemu/cutils.h
+++ b/include/qemu/cutils.h
@@ -302,4 +302,19 @@ GString *qemu_hexdump_line(GString *str, const void *buf, size_t len,
void qemu_hexdump(FILE *fp, const char *prefix,
const void *bufptr, size_t size);
+/**
+ * qemu_hexdump_to_buffer:
+ * @buffer: output string buffer
+ * @buffer_size: amount of available space in buffer. Must be at least
+ * data_size*2+1.
+ * @data: input bytes
+ * @data_size: number of bytes in data
+ *
+ * Converts the @data_size bytes in @data into hex digit pairs, writing them to
+ * @buffer. Finally, a nul terminating character is written; @buffer therefore
+ * needs space for (data_size*2+1) chars.
+ */
+void qemu_hexdump_to_buffer(char *restrict buffer, size_t buffer_size,
+ const uint8_t *restrict data, size_t data_size);
+
#endif
diff --git a/hw/vmapple/aes.c b/hw/vmapple/aes.c
new file mode 100644
index 00000000000..3a7641ab4b0
--- /dev/null
+++ b/hw/vmapple/aes.c
@@ -0,0 +1,581 @@
+/*
+ * QEMU Apple AES device emulation
+ *
+ * Copyright © 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "trace.h"
+#include "crypto/hash.h"
+#include "crypto/aes.h"
+#include "crypto/cipher.h"
+#include "hw/irq.h"
+#include "hw/sysbus.h"
+#include "hw/vmapple/vmapple.h"
+#include "migration/vmstate.h"
+#include "qemu/cutils.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "system/dma.h"
+
+OBJECT_DECLARE_SIMPLE_TYPE(AESState, APPLE_AES)
+
+#define MAX_FIFO_SIZE 9
+
+#define CMD_KEY 0x1
+#define CMD_KEY_CONTEXT_SHIFT 27
+#define CMD_KEY_CONTEXT_MASK (0x1 << CMD_KEY_CONTEXT_SHIFT)
+#define CMD_KEY_SELECT_MAX_IDX 0x7
+#define CMD_KEY_SELECT_SHIFT 24
+#define CMD_KEY_SELECT_MASK (CMD_KEY_SELECT_MAX_IDX << CMD_KEY_SELECT_SHIFT)
+#define CMD_KEY_KEY_LEN_NUM 4u
+#define CMD_KEY_KEY_LEN_SHIFT 22
+#define CMD_KEY_KEY_LEN_MASK ((CMD_KEY_KEY_LEN_NUM - 1u) << CMD_KEY_KEY_LEN_SHIFT)
+#define CMD_KEY_ENCRYPT_SHIFT 20
+#define CMD_KEY_ENCRYPT_MASK (0x1 << CMD_KEY_ENCRYPT_SHIFT)
+#define CMD_KEY_BLOCK_MODE_SHIFT 16
+#define CMD_KEY_BLOCK_MODE_MASK (0x3 << CMD_KEY_BLOCK_MODE_SHIFT)
+#define CMD_IV 0x2
+#define CMD_IV_CONTEXT_SHIFT 26
+#define CMD_IV_CONTEXT_MASK (0x3 << CMD_KEY_CONTEXT_SHIFT)
+#define CMD_DSB 0x3
+#define CMD_SKG 0x4
+#define CMD_DATA 0x5
+#define CMD_DATA_KEY_CTX_SHIFT 27
+#define CMD_DATA_KEY_CTX_MASK (0x1 << CMD_DATA_KEY_CTX_SHIFT)
+#define CMD_DATA_IV_CTX_SHIFT 25
+#define CMD_DATA_IV_CTX_MASK (0x3 << CMD_DATA_IV_CTX_SHIFT)
+#define CMD_DATA_LEN_MASK 0xffffff
+#define CMD_STORE_IV 0x6
+#define CMD_STORE_IV_ADDR_MASK 0xffffff
+#define CMD_WRITE_REG 0x7
+#define CMD_FLAG 0x8
+#define CMD_FLAG_STOP_MASK BIT(26)
+#define CMD_FLAG_RAISE_IRQ_MASK BIT(27)
+#define CMD_FLAG_INFO_MASK 0xff
+#define CMD_MAX 0x10
+
+#define CMD_SHIFT 28
+
+#define REG_STATUS 0xc
+#define REG_STATUS_DMA_READ_RUNNING BIT(0)
+#define REG_STATUS_DMA_READ_PENDING BIT(1)
+#define REG_STATUS_DMA_WRITE_RUNNING BIT(2)
+#define REG_STATUS_DMA_WRITE_PENDING BIT(3)
+#define REG_STATUS_BUSY BIT(4)
+#define REG_STATUS_EXECUTING BIT(5)
+#define REG_STATUS_READY BIT(6)
+#define REG_STATUS_TEXT_DPA_SEEDED BIT(7)
+#define REG_STATUS_UNWRAP_DPA_SEEDED BIT(8)
+
+#define REG_IRQ_STATUS 0x18
+#define REG_IRQ_STATUS_INVALID_CMD BIT(2)
+#define REG_IRQ_STATUS_FLAG BIT(5)
+#define REG_IRQ_ENABLE 0x1c
+#define REG_WATERMARK 0x20
+#define REG_Q_STATUS 0x24
+#define REG_FLAG_INFO 0x30
+#define REG_FIFO 0x200
+
+static const uint32_t key_lens[CMD_KEY_KEY_LEN_NUM] = {
+ [0] = 16,
+ [1] = 24,
+ [2] = 32,
+ [3] = 64,
+};
+
+typedef struct Key {
+ uint32_t key_len;
+ uint8_t key[32];
+} Key;
+
+typedef struct IV {
+ uint32_t iv[4];
+} IV;
+
+static Key builtin_keys[CMD_KEY_SELECT_MAX_IDX + 1] = {
+ [1] = {
+ .key_len = 32,
+ .key = { 0x1 },
+ },
+ [2] = {
+ .key_len = 32,
+ .key = { 0x2 },
+ },
+ [3] = {
+ .key_len = 32,
+ .key = { 0x3 },
+ }
+};
+
+struct AESState {
+ SysBusDevice parent_obj;
+
+ qemu_irq irq;
+ MemoryRegion iomem1;
+ MemoryRegion iomem2;
+ AddressSpace *as;
+
+ uint32_t status;
+ uint32_t q_status;
+ uint32_t irq_status;
+ uint32_t irq_enable;
+ uint32_t watermark;
+ uint32_t flag_info;
+ uint32_t fifo[MAX_FIFO_SIZE];
+ uint32_t fifo_idx;
+ Key key[2];
+ IV iv[4];
+ bool is_encrypt;
+ QCryptoCipherMode block_mode;
+};
+
+static void aes_update_irq(AESState *s)
+{
+ qemu_set_irq(s->irq, !!(s->irq_status & s->irq_enable));
+}
+
+static uint64_t aes1_read(void *opaque, hwaddr offset, unsigned size)
+{
+ AESState *s = opaque;
+ uint64_t res = 0;
+
+ switch (offset) {
+ case REG_STATUS:
+ res = s->status;
+ break;
+ case REG_IRQ_STATUS:
+ res = s->irq_status;
+ break;
+ case REG_IRQ_ENABLE:
+ res = s->irq_enable;
+ break;
+ case REG_WATERMARK:
+ res = s->watermark;
+ break;
+ case REG_Q_STATUS:
+ res = s->q_status;
+ break;
+ case REG_FLAG_INFO:
+ res = s->flag_info;
+ break;
+
+ default:
+ qemu_log_mask(LOG_UNIMP, "%s: Unknown AES MMIO offset %" PRIx64 "\n",
+ __func__, offset);
+ break;
+ }
+
+ trace_aes_read(offset, res);
+
+ return res;
+}
+
+static void fifo_append(AESState *s, uint64_t val)
+{
+ if (s->fifo_idx == MAX_FIFO_SIZE) {
+ /* Exceeded the FIFO. Bail out */
+ return;
+ }
+
+ s->fifo[s->fifo_idx++] = val;
+}
+
+static bool has_payload(AESState *s, uint32_t elems)
+{
+ return s->fifo_idx >= elems + 1;
+}
+
+static bool cmd_key(AESState *s)
+{
+ uint32_t cmd = s->fifo[0];
+ uint32_t key_select = (cmd & CMD_KEY_SELECT_MASK) >> CMD_KEY_SELECT_SHIFT;
+ uint32_t ctxt = (cmd & CMD_KEY_CONTEXT_MASK) >> CMD_KEY_CONTEXT_SHIFT;
+ uint32_t key_len;
+
+ switch ((cmd & CMD_KEY_BLOCK_MODE_MASK) >> CMD_KEY_BLOCK_MODE_SHIFT) {
+ case 0:
+ s->block_mode = QCRYPTO_CIPHER_MODE_ECB;
+ break;
+ case 1:
+ s->block_mode = QCRYPTO_CIPHER_MODE_CBC;
+ break;
+ default:
+ return false;
+ }
+
+ s->is_encrypt = cmd & CMD_KEY_ENCRYPT_MASK;
+ key_len = key_lens[(cmd & CMD_KEY_KEY_LEN_MASK) >> CMD_KEY_KEY_LEN_SHIFT];
+
+ if (key_select) {
+ trace_aes_cmd_key_select_builtin(ctxt, key_select,
+ s->is_encrypt ? "en" : "de",
+ QCryptoCipherMode_str(s->block_mode));
+ s->key[ctxt] = builtin_keys[key_select];
+ } else {
+ trace_aes_cmd_key_select_new(ctxt, key_len,
+ s->is_encrypt ? "en" : "de",
+ QCryptoCipherMode_str(s->block_mode));
+ if (key_len > sizeof(s->key[ctxt].key)) {
+ return false;
+ }
+ if (!has_payload(s, key_len / sizeof(uint32_t))) {
+ /* wait for payload */
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No payload\n", __func__);
+ return false;
+ }
+ memcpy(&s->key[ctxt].key, &s->fifo[1], key_len);
+ s->key[ctxt].key_len = key_len;
+ }
+
+ return true;
+}
+
+static bool cmd_iv(AESState *s)
+{
+ uint32_t cmd = s->fifo[0];
+ uint32_t ctxt = (cmd & CMD_IV_CONTEXT_MASK) >> CMD_IV_CONTEXT_SHIFT;
+
+ if (!has_payload(s, 4)) {
+ /* wait for payload */
+ return false;
+ }
+ memcpy(&s->iv[ctxt].iv, &s->fifo[1], sizeof(s->iv[ctxt].iv));
+ trace_aes_cmd_iv(ctxt, s->fifo[1], s->fifo[2], s->fifo[3], s->fifo[4]);
+
+ return true;
+}
+
+static void dump_data(const char *desc, const void *p, size_t len)
+{
+ static const size_t MAX_LEN = 0x1000;
+ char hex[MAX_LEN * 2 + 1] = "";
+
+ if (len > MAX_LEN) {
+ return;
+ }
+
+ qemu_hexdump_to_buffer(hex, sizeof(hex), p, len);
+ trace_aes_dump_data(desc, hex);
+}
+
+static bool cmd_data(AESState *s)
+{
+ uint32_t cmd = s->fifo[0];
+ uint32_t ctxt_iv = 0;
+ uint32_t ctxt_key = (cmd & CMD_DATA_KEY_CTX_MASK) >> CMD_DATA_KEY_CTX_SHIFT;
+ uint32_t len = cmd & CMD_DATA_LEN_MASK;
+ uint64_t src_addr = s->fifo[2];
+ uint64_t dst_addr = s->fifo[3];
+ QCryptoCipherAlgo alg;
+ g_autoptr(QCryptoCipher) cipher = NULL;
+ g_autoptr(GByteArray) src = NULL;
+ g_autoptr(GByteArray) dst = NULL;
+ MemTxResult r;
+
+ src_addr |= ((uint64_t)s->fifo[1] << 16) & 0xffff00000000ULL;
+ dst_addr |= ((uint64_t)s->fifo[1] << 32) & 0xffff00000000ULL;
+
+ trace_aes_cmd_data(ctxt_key, ctxt_iv, src_addr, dst_addr, len);
+
+ if (!has_payload(s, 3)) {
+ /* wait for payload */
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No payload\n", __func__);
+ return false;
+ }
+
+ if (ctxt_key >= ARRAY_SIZE(s->key) ||
+ ctxt_iv >= ARRAY_SIZE(s->iv)) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid key or iv\n", __func__);
+ return false;
+ }
+
+ src = g_byte_array_sized_new(len);
+ g_byte_array_set_size(src, len);
+ dst = g_byte_array_sized_new(len);
+ g_byte_array_set_size(dst, len);
+
+ r = dma_memory_read(s->as, src_addr, src->data, len, MEMTXATTRS_UNSPECIFIED);
+ if (r != MEMTX_OK) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA read of %"PRIu32" bytes "
+ "from 0x%"PRIx64" failed. (r=%d)\n",
+ __func__, len, src_addr, r);
+ return false;
+ }
+
+ dump_data("cmd_data(): src_data=", src->data, len);
+
+ switch (s->key[ctxt_key].key_len) {
+ case 128 / 8:
+ alg = QCRYPTO_CIPHER_ALGO_AES_128;
+ break;
+ case 192 / 8:
+ alg = QCRYPTO_CIPHER_ALGO_AES_192;
+ break;
+ case 256 / 8:
+ alg = QCRYPTO_CIPHER_ALGO_AES_256;
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid key length\n", __func__);
+ return false;
+ }
+ cipher = qcrypto_cipher_new(alg, s->block_mode,
+ s->key[ctxt_key].key,
+ s->key[ctxt_key].key_len, NULL);
+ if (!cipher) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to create cipher object\n",
+ __func__);
+ return false;
+ }
+ if (s->block_mode != QCRYPTO_CIPHER_MODE_ECB) {
+ if (qcrypto_cipher_setiv(cipher, (void *)s->iv[ctxt_iv].iv,
+ sizeof(s->iv[ctxt_iv].iv), NULL) != 0) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to set IV\n", __func__);
+ return false;
+ }
+ }
+ if (s->is_encrypt) {
+ if (qcrypto_cipher_encrypt(cipher, src->data, dst->data, len, NULL) != 0) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Encryption failed\n", __func__);
+ return false;
+ }
+ } else {
+ if (qcrypto_cipher_decrypt(cipher, src->data, dst->data, len, NULL) != 0) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Decryption failed\n", __func__);
+ return false;
+ }
+ }
+
+ dump_data("cmd_data(): dst_data=", dst->data, len);
+ r = dma_memory_write(s->as, dst_addr, dst->data, len, MEMTXATTRS_UNSPECIFIED);
+ if (r != MEMTX_OK) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA write of %"PRIu32" bytes "
+ "to 0x%"PRIx64" failed. (r=%d)\n",
+ __func__, len, src_addr, r);
+ return false;
+ }
+
+ return true;
+}
+
+static bool cmd_store_iv(AESState *s)
+{
+ uint32_t cmd = s->fifo[0];
+ uint32_t ctxt = (cmd & CMD_IV_CONTEXT_MASK) >> CMD_IV_CONTEXT_SHIFT;
+ uint64_t addr = s->fifo[1];
+ MemTxResult dma_result;
+
+ if (!has_payload(s, 1)) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No payload\n", __func__);
+ return false;
+ }
+
+ if (ctxt >= ARRAY_SIZE(s->iv)) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: Invalid context. ctxt = %u, allowed: 0..%zu\n",
+ __func__, ctxt, ARRAY_SIZE(s->iv) - 1);
+ return false;
+ }
+
+ addr |= ((uint64_t)cmd << 32) & 0xff00000000ULL;
+ dma_result = dma_memory_write(&address_space_memory, addr,
+ &s->iv[ctxt].iv, sizeof(s->iv[ctxt].iv),
+ MEMTXATTRS_UNSPECIFIED);
+
+ trace_aes_cmd_store_iv(ctxt, addr, s->iv[ctxt].iv[0], s->iv[ctxt].iv[1],
+ s->iv[ctxt].iv[2], s->iv[ctxt].iv[3]);
+
+ return dma_result == MEMTX_OK;
+}
+
+static bool cmd_flag(AESState *s)
+{
+ uint32_t cmd = s->fifo[0];
+ uint32_t raise_irq = cmd & CMD_FLAG_RAISE_IRQ_MASK;
+
+ /* We always process data when it's coming in, so fire an IRQ immediately */
+ if (raise_irq) {
+ s->irq_status |= REG_IRQ_STATUS_FLAG;
+ }
+
+ s->flag_info = cmd & CMD_FLAG_INFO_MASK;
+
+ trace_aes_cmd_flag(!!raise_irq, s->flag_info);
+
+ return true;
+}
+
+static void fifo_process(AESState *s)
+{
+ uint32_t cmd = s->fifo[0] >> CMD_SHIFT;
+ bool success = false;
+
+ if (!s->fifo_idx) {
+ return;
+ }
+
+ switch (cmd) {
+ case CMD_KEY:
+ success = cmd_key(s);
+ break;
+ case CMD_IV:
+ success = cmd_iv(s);
+ break;
+ case CMD_DATA:
+ success = cmd_data(s);
+ break;
+ case CMD_STORE_IV:
+ success = cmd_store_iv(s);
+ break;
+ case CMD_FLAG:
+ success = cmd_flag(s);
+ break;
+ default:
+ s->irq_status |= REG_IRQ_STATUS_INVALID_CMD;
+ break;
+ }
+
+ if (success) {
+ s->fifo_idx = 0;
+ }
+
+ trace_aes_fifo_process(cmd, success);
+}
+
+static void aes1_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
+{
+ AESState *s = opaque;
+
+ trace_aes_write(offset, val);
+
+ switch (offset) {
+ case REG_IRQ_STATUS:
+ s->irq_status &= ~val;
+ break;
+ case REG_IRQ_ENABLE:
+ s->irq_enable = val;
+ break;
+ case REG_FIFO:
+ fifo_append(s, val);
+ fifo_process(s);
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP,
+ "%s: Unknown AES MMIO offset %"PRIx64", data %"PRIx64"\n",
+ __func__, offset, val);
+ return;
+ }
+
+ aes_update_irq(s);
+}
+
+static const MemoryRegionOps aes1_ops = {
+ .read = aes1_read,
+ .write = aes1_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 8,
+ },
+ .impl = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ },
+};
+
+static uint64_t aes2_read(void *opaque, hwaddr offset, unsigned size)
+{
+ uint64_t res = 0;
+
+ switch (offset) {
+ case 0:
+ res = 0;
+ break;
+ default:
+ qemu_log_mask(LOG_UNIMP,
+ "%s: Unknown AES MMIO 2 offset %"PRIx64"\n",
+ __func__, offset);
+ break;
+ }
+
+ trace_aes_2_read(offset, res);
+
+ return res;
+}
+
+static void aes2_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
+{
+ trace_aes_2_write(offset, val);
+
+ switch (offset) {
+ default:
+ qemu_log_mask(LOG_UNIMP,
+ "%s: Unknown AES MMIO 2 offset %"PRIx64", data %"PRIx64"\n",
+ __func__, offset, val);
+ return;
+ }
+}
+
+static const MemoryRegionOps aes2_ops = {
+ .read = aes2_read,
+ .write = aes2_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 8,
+ },
+ .impl = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ },
+};
+
+static void aes_reset(Object *obj, ResetType type)
+{
+ AESState *s = APPLE_AES(obj);
+
+ s->status = 0x3f80;
+ s->q_status = 2;
+ s->irq_status = 0;
+ s->irq_enable = 0;
+ s->watermark = 0;
+}
+
+static void aes_init(Object *obj)
+{
+ AESState *s = APPLE_AES(obj);
+
+ memory_region_init_io(&s->iomem1, obj, &aes1_ops, s, TYPE_APPLE_AES, 0x4000);
+ memory_region_init_io(&s->iomem2, obj, &aes2_ops, s, TYPE_APPLE_AES, 0x4000);
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem1);
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem2);
+ sysbus_init_irq(SYS_BUS_DEVICE(s), &s->irq);
+ s->as = &address_space_memory;
+}
+
+static void aes_class_init(ObjectClass *klass, void *data)
+{
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
+
+ rc->phases.hold = aes_reset;
+}
+
+static const TypeInfo aes_info = {
+ .name = TYPE_APPLE_AES,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(AESState),
+ .class_init = aes_class_init,
+ .instance_init = aes_init,
+};
+
+static void aes_register_types(void)
+{
+ type_register_static(&aes_info);
+}
+
+type_init(aes_register_types)
diff --git a/util/hexdump.c b/util/hexdump.c
index ae0d4992dcf..f29ffceb746 100644
--- a/util/hexdump.c
+++ b/util/hexdump.c
@@ -15,6 +15,7 @@
#include "qemu/osdep.h"
#include "qemu/cutils.h"
+#include "qemu/host-utils.h"
static inline char hexdump_nibble(unsigned x)
{
@@ -97,3 +98,20 @@ void qemu_hexdump(FILE *fp, const char *prefix,
}
}
+
+void qemu_hexdump_to_buffer(char *restrict buffer, size_t buffer_size,
+ const uint8_t *restrict data, size_t data_size)
+{
+ size_t i;
+ uint64_t required_buffer_size;
+ bool overflow = umul64_overflow(data_size, 2, &required_buffer_size);
+ overflow |= uadd64_overflow(required_buffer_size, 1, &required_buffer_size);
+ assert(!overflow && buffer_size >= required_buffer_size);
+
+ for (i = 0; i < data_size; i++) {
+ uint8_t val = data[i];
+ *(buffer++) = hexdump_nibble(val >> 4);
+ *(buffer++) = hexdump_nibble(val & 0xf);
+ }
+ *buffer = '\0';
+}
diff --git a/hw/vmapple/Kconfig b/hw/vmapple/Kconfig
index 315c06b689c..b1944d73129 100644
--- a/hw/vmapple/Kconfig
+++ b/hw/vmapple/Kconfig
@@ -1 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-or-later
+
+config VMAPPLE_AES
+ bool
diff --git a/hw/vmapple/meson.build b/hw/vmapple/meson.build
index 315c06b689c..a701d06a39d 100644
--- a/hw/vmapple/meson.build
+++ b/hw/vmapple/meson.build
@@ -1 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-or-later
+
+system_ss.add(when: 'CONFIG_VMAPPLE_AES', if_true: files('aes.c'))
diff --git a/hw/vmapple/trace-events b/hw/vmapple/trace-events
index 21125794121..188547a6ad8 100644
--- a/hw/vmapple/trace-events
+++ b/hw/vmapple/trace-events
@@ -1,2 +1,16 @@
# See docs/devel/tracing.rst for syntax documentation.
# SPDX-License-Identifier: GPL-2.0-or-later
+
+# aes.c
+aes_read(uint64_t offset, uint64_t res) "offset=0x%"PRIx64" res=0x%"PRIx64
+aes_cmd_key_select_builtin(uint32_t ctx, uint32_t key_id, const char *direction, const char *cipher) "[%d] Selecting builtin key %d to %scrypt with %s"
+aes_cmd_key_select_new(uint32_t ctx, uint32_t key_len, const char *direction, const char *cipher) "[%d] Selecting new key size=%d to %scrypt with %s"
+aes_cmd_iv(uint32_t ctx, uint32_t iv0, uint32_t iv1, uint32_t iv2, uint32_t iv3) "[%d] 0x%08x 0x%08x 0x%08x 0x%08x"
+aes_cmd_data(uint32_t key, uint32_t iv, uint64_t src, uint64_t dst, uint32_t len) "[key=%d iv=%d] src=0x%"PRIx64" dst=0x%"PRIx64" len=0x%x"
+aes_cmd_store_iv(uint32_t ctx, uint64_t addr, uint32_t iv0, uint32_t iv1, uint32_t iv2, uint32_t iv3) "[%d] addr=0x%"PRIx64"x -> 0x%08x 0x%08x 0x%08x 0x%08x"
+aes_cmd_flag(uint32_t raise, uint32_t flag_info) "raise=%d flag_info=0x%x"
+aes_fifo_process(uint32_t cmd, bool success) "cmd=%d success=%d"
+aes_write(uint64_t offset, uint64_t val) "offset=0x%"PRIx64" val=0x%"PRIx64
+aes_2_read(uint64_t offset, uint64_t res) "offset=0x%"PRIx64" res=0x%"PRIx64
+aes_2_write(uint64_t offset, uint64_t val) "offset=0x%"PRIx64" val=0x%"PRIx64
+aes_dump_data(const char *desc, const char *hex) "%s%s"
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 05/41] hw/vmapple/bdif: Introduce vmapple backdoor interface
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (3 preceding siblings ...)
2025-03-05 1:21 ` [PULL 04/41] hw/vmapple/aes: Introduce aes engine Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 06/41] hw/vmapple/cfg: Introduce vmapple cfg region Philippe Mathieu-Daudé
` (35 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, Phil Dennis-Jordan, Akihiko Odaki,
Philippe Mathieu-Daudé
From: Alexander Graf <graf@amazon.com>
The VMApple machine exposes AUX and ROOT block devices (as well as USB OTG
emulation) via virtio-pci as well as a special, simple backdoor platform
device.
This patch implements this backdoor platform device to the best of my
understanding. I left out any USB OTG parts; they're only needed for
guest recovery and I don't understand the protocol yet.
Signed-off-by: Alexander Graf <graf@amazon.com>
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Message-ID: <20241223221645.29911-11-phil@philjordan.eu>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
include/hw/vmapple/vmapple.h | 2 +
hw/vmapple/bdif.c | 274 +++++++++++++++++++++++++++++++++++
hw/vmapple/Kconfig | 3 +
hw/vmapple/meson.build | 1 +
hw/vmapple/trace-events | 5 +
5 files changed, 285 insertions(+)
create mode 100644 hw/vmapple/bdif.c
diff --git a/include/hw/vmapple/vmapple.h b/include/hw/vmapple/vmapple.h
index 6762b6c869f..9090e9c5ac8 100644
--- a/include/hw/vmapple/vmapple.h
+++ b/include/hw/vmapple/vmapple.h
@@ -14,4 +14,6 @@
#define TYPE_APPLE_AES "apple-aes"
+#define TYPE_VMAPPLE_BDIF "vmapple-bdif"
+
#endif /* HW_VMAPPLE_VMAPPLE_H */
diff --git a/hw/vmapple/bdif.c b/hw/vmapple/bdif.c
new file mode 100644
index 00000000000..5827dd2aab8
--- /dev/null
+++ b/hw/vmapple/bdif.c
@@ -0,0 +1,274 @@
+/*
+ * VMApple Backdoor Interface
+ *
+ * Copyright © 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "trace.h"
+#include "hw/vmapple/vmapple.h"
+#include "hw/sysbus.h"
+#include "hw/block/block.h"
+#include "qapi/error.h"
+#include "system/block-backend.h"
+#include "system/dma.h"
+
+OBJECT_DECLARE_SIMPLE_TYPE(VMAppleBdifState, VMAPPLE_BDIF)
+
+struct VMAppleBdifState {
+ SysBusDevice parent_obj;
+
+ BlockBackend *aux;
+ BlockBackend *root;
+ MemoryRegion mmio;
+};
+
+#define VMAPPLE_BDIF_SIZE 0x00200000
+
+#define REG_DEVID_MASK 0xffff0000
+#define DEVID_ROOT 0x00000000
+#define DEVID_AUX 0x00010000
+#define DEVID_USB 0x00100000
+
+#define REG_STATUS 0x0
+#define REG_STATUS_ACTIVE BIT(0)
+#define REG_CFG 0x4
+#define REG_CFG_ACTIVE BIT(1)
+#define REG_UNK1 0x8
+#define REG_BUSY 0x10
+#define REG_BUSY_READY BIT(0)
+#define REG_UNK2 0x400
+#define REG_CMD 0x408
+#define REG_NEXT_DEVICE 0x420
+#define REG_UNK3 0x434
+
+typedef struct VblkSector {
+ uint32_t pad;
+ uint32_t pad2;
+ uint32_t sector;
+ uint32_t pad3;
+} VblkSector;
+
+typedef struct VblkReqCmd {
+ uint64_t addr;
+ uint32_t len;
+ uint32_t flags;
+} VblkReqCmd;
+
+typedef struct VblkReq {
+ VblkReqCmd sector;
+ VblkReqCmd data;
+ VblkReqCmd retval;
+} VblkReq;
+
+#define VBLK_DATA_FLAGS_READ 0x00030001
+#define VBLK_DATA_FLAGS_WRITE 0x00010001
+
+#define VBLK_RET_SUCCESS 0
+#define VBLK_RET_FAILED 1
+
+static uint64_t bdif_read(void *opaque, hwaddr offset, unsigned size)
+{
+ uint64_t ret = -1;
+ uint64_t devid = offset & REG_DEVID_MASK;
+
+ switch (offset & ~REG_DEVID_MASK) {
+ case REG_STATUS:
+ ret = REG_STATUS_ACTIVE;
+ break;
+ case REG_CFG:
+ ret = REG_CFG_ACTIVE;
+ break;
+ case REG_UNK1:
+ ret = 0x420;
+ break;
+ case REG_BUSY:
+ ret = REG_BUSY_READY;
+ break;
+ case REG_UNK2:
+ ret = 0x1;
+ break;
+ case REG_UNK3:
+ ret = 0x0;
+ break;
+ case REG_NEXT_DEVICE:
+ switch (devid) {
+ case DEVID_ROOT:
+ ret = 0x8000000;
+ break;
+ case DEVID_AUX:
+ ret = 0x10000;
+ break;
+ }
+ break;
+ }
+
+ trace_bdif_read(offset, size, ret);
+ return ret;
+}
+
+static void le2cpu_sector(VblkSector *sector)
+{
+ sector->sector = le32_to_cpu(sector->sector);
+}
+
+static void le2cpu_reqcmd(VblkReqCmd *cmd)
+{
+ cmd->addr = le64_to_cpu(cmd->addr);
+ cmd->len = le32_to_cpu(cmd->len);
+ cmd->flags = le32_to_cpu(cmd->flags);
+}
+
+static void le2cpu_req(VblkReq *req)
+{
+ le2cpu_reqcmd(&req->sector);
+ le2cpu_reqcmd(&req->data);
+ le2cpu_reqcmd(&req->retval);
+}
+
+static void vblk_cmd(uint64_t devid, BlockBackend *blk, uint64_t gp_addr,
+ uint64_t static_off)
+{
+ VblkReq req;
+ VblkSector sector;
+ uint64_t off = 0;
+ g_autofree char *buf = NULL;
+ uint8_t ret = VBLK_RET_FAILED;
+ int r;
+ MemTxResult dma_result;
+
+ dma_result = dma_memory_read(&address_space_memory, gp_addr,
+ &req, sizeof(req), MEMTXATTRS_UNSPECIFIED);
+ if (dma_result != MEMTX_OK) {
+ goto out;
+ }
+
+ le2cpu_req(&req);
+
+ if (req.sector.len != sizeof(sector)) {
+ goto out;
+ }
+
+ /* Read the vblk command */
+ dma_result = dma_memory_read(&address_space_memory, req.sector.addr,
+ §or, sizeof(sector),
+ MEMTXATTRS_UNSPECIFIED);
+ if (dma_result != MEMTX_OK) {
+ goto out;
+ }
+ le2cpu_sector(§or);
+
+ off = sector.sector * 512ULL + static_off;
+
+ /* Sanity check that we're not allocating bogus sizes */
+ if (req.data.len > 128 * MiB) {
+ goto out;
+ }
+
+ buf = g_malloc0(req.data.len);
+ switch (req.data.flags) {
+ case VBLK_DATA_FLAGS_READ:
+ r = blk_pread(blk, off, req.data.len, buf, 0);
+ trace_bdif_vblk_read(devid == DEVID_AUX ? "aux" : "root",
+ req.data.addr, off, req.data.len, r);
+ if (r < 0) {
+ goto out;
+ }
+ dma_result = dma_memory_write(&address_space_memory, req.data.addr, buf,
+ req.data.len, MEMTXATTRS_UNSPECIFIED);
+ if (dma_result == MEMTX_OK) {
+ ret = VBLK_RET_SUCCESS;
+ }
+ break;
+ case VBLK_DATA_FLAGS_WRITE:
+ /* Not needed, iBoot only reads */
+ break;
+ default:
+ break;
+ }
+
+out:
+ dma_memory_write(&address_space_memory, req.retval.addr, &ret, 1,
+ MEMTXATTRS_UNSPECIFIED);
+}
+
+static void bdif_write(void *opaque, hwaddr offset,
+ uint64_t value, unsigned size)
+{
+ VMAppleBdifState *s = opaque;
+ uint64_t devid = (offset & REG_DEVID_MASK);
+
+ trace_bdif_write(offset, size, value);
+
+ switch (offset & ~REG_DEVID_MASK) {
+ case REG_CMD:
+ switch (devid) {
+ case DEVID_ROOT:
+ vblk_cmd(devid, s->root, value, 0x0);
+ break;
+ case DEVID_AUX:
+ vblk_cmd(devid, s->aux, value, 0x0);
+ break;
+ }
+ break;
+ }
+}
+
+static const MemoryRegionOps bdif_ops = {
+ .read = bdif_read,
+ .write = bdif_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid = {
+ .min_access_size = 1,
+ .max_access_size = 8,
+ },
+ .impl = {
+ .min_access_size = 1,
+ .max_access_size = 8,
+ },
+};
+
+static void bdif_init(Object *obj)
+{
+ VMAppleBdifState *s = VMAPPLE_BDIF(obj);
+
+ memory_region_init_io(&s->mmio, obj, &bdif_ops, obj,
+ "VMApple Backdoor Interface", VMAPPLE_BDIF_SIZE);
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
+}
+
+static const Property bdif_properties[] = {
+ DEFINE_PROP_DRIVE("aux", VMAppleBdifState, aux),
+ DEFINE_PROP_DRIVE("root", VMAppleBdifState, root),
+};
+
+static void bdif_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->desc = "VMApple Backdoor Interface";
+ device_class_set_props(dc, bdif_properties);
+}
+
+static const TypeInfo bdif_info = {
+ .name = TYPE_VMAPPLE_BDIF,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(VMAppleBdifState),
+ .instance_init = bdif_init,
+ .class_init = bdif_class_init,
+};
+
+static void bdif_register_types(void)
+{
+ type_register_static(&bdif_info);
+}
+
+type_init(bdif_register_types)
diff --git a/hw/vmapple/Kconfig b/hw/vmapple/Kconfig
index b1944d73129..ff5f97c292e 100644
--- a/hw/vmapple/Kconfig
+++ b/hw/vmapple/Kconfig
@@ -2,3 +2,6 @@
config VMAPPLE_AES
bool
+
+config VMAPPLE_BDIF
+ bool
diff --git a/hw/vmapple/meson.build b/hw/vmapple/meson.build
index a701d06a39d..e2aca6b7c2b 100644
--- a/hw/vmapple/meson.build
+++ b/hw/vmapple/meson.build
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-or-later
system_ss.add(when: 'CONFIG_VMAPPLE_AES', if_true: files('aes.c'))
+system_ss.add(when: 'CONFIG_VMAPPLE_BDIF', if_true: files('bdif.c'))
diff --git a/hw/vmapple/trace-events b/hw/vmapple/trace-events
index 188547a6ad8..93380ede145 100644
--- a/hw/vmapple/trace-events
+++ b/hw/vmapple/trace-events
@@ -14,3 +14,8 @@ aes_write(uint64_t offset, uint64_t val) "offset=0x%"PRIx64" val=0x%"PRIx64
aes_2_read(uint64_t offset, uint64_t res) "offset=0x%"PRIx64" res=0x%"PRIx64
aes_2_write(uint64_t offset, uint64_t val) "offset=0x%"PRIx64" val=0x%"PRIx64
aes_dump_data(const char *desc, const char *hex) "%s%s"
+
+# bdif.c
+bdif_read(uint64_t offset, uint32_t size, uint64_t value) "offset=0x%"PRIx64" size=0x%x value=0x%"PRIx64
+bdif_write(uint64_t offset, uint32_t size, uint64_t value) "offset=0x%"PRIx64" size=0x%x value=0x%"PRIx64
+bdif_vblk_read(const char *dev, uint64_t addr, uint64_t offset, uint32_t len, int r) "dev=%s addr=0x%"PRIx64" off=0x%"PRIx64" size=0x%x r=%d"
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 06/41] hw/vmapple/cfg: Introduce vmapple cfg region
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (4 preceding siblings ...)
2025-03-05 1:21 ` [PULL 05/41] hw/vmapple/bdif: Introduce vmapple backdoor interface Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 07/41] hw/vmapple/virtio-blk: Add support for apple virtio-blk Philippe Mathieu-Daudé
` (34 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, Phil Dennis-Jordan, Akihiko Odaki,
Philippe Mathieu-Daudé
From: Alexander Graf <graf@amazon.com>
Instead of device tree or other more standardized means, VMApple passes
platform configuration to the first stage boot loader in a binary encoded
format that resides at a dedicated RAM region in physical address space.
This patch models this configuration space as a qdev device which we can
then map at the fixed location in the address space. That way, we can
influence and annotate all configuration fields easily.
Signed-off-by: Alexander Graf <graf@amazon.com>
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Message-ID: <20241223221645.29911-12-phil@philjordan.eu>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
include/hw/vmapple/vmapple.h | 2 +
hw/vmapple/cfg.c | 195 +++++++++++++++++++++++++++++++++++
hw/vmapple/Kconfig | 3 +
hw/vmapple/meson.build | 1 +
4 files changed, 201 insertions(+)
create mode 100644 hw/vmapple/cfg.c
diff --git a/include/hw/vmapple/vmapple.h b/include/hw/vmapple/vmapple.h
index 9090e9c5ac8..3bba59f5ec7 100644
--- a/include/hw/vmapple/vmapple.h
+++ b/include/hw/vmapple/vmapple.h
@@ -16,4 +16,6 @@
#define TYPE_VMAPPLE_BDIF "vmapple-bdif"
+#define TYPE_VMAPPLE_CFG "vmapple-cfg"
+
#endif /* HW_VMAPPLE_VMAPPLE_H */
diff --git a/hw/vmapple/cfg.c b/hw/vmapple/cfg.c
new file mode 100644
index 00000000000..63414d801fe
--- /dev/null
+++ b/hw/vmapple/cfg.c
@@ -0,0 +1,195 @@
+/*
+ * VMApple Configuration Region
+ *
+ * Copyright © 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/vmapple/vmapple.h"
+#include "hw/sysbus.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qapi/error.h"
+#include "net/net.h"
+
+OBJECT_DECLARE_SIMPLE_TYPE(VMAppleCfgState, VMAPPLE_CFG)
+
+#define VMAPPLE_CFG_SIZE 0x00010000
+
+typedef struct VMAppleCfg {
+ uint32_t version; /* 0x000 */
+ uint32_t nr_cpus; /* 0x004 */
+ uint32_t unk1; /* 0x008 */
+ uint32_t unk2; /* 0x00c */
+ uint32_t unk3; /* 0x010 */
+ uint32_t unk4; /* 0x014 */
+ uint64_t ecid; /* 0x018 */
+ uint64_t ram_size; /* 0x020 */
+ uint32_t run_installer1; /* 0x028 */
+ uint32_t unk5; /* 0x02c */
+ uint32_t unk6; /* 0x030 */
+ uint32_t run_installer2; /* 0x034 */
+ uint32_t rnd; /* 0x038 */
+ uint32_t unk7; /* 0x03c */
+ MACAddr mac_en0; /* 0x040 */
+ uint8_t pad1[2];
+ MACAddr mac_en1; /* 0x048 */
+ uint8_t pad2[2];
+ MACAddr mac_wifi0; /* 0x050 */
+ uint8_t pad3[2];
+ MACAddr mac_bt0; /* 0x058 */
+ uint8_t pad4[2];
+ uint8_t reserved[0xa0]; /* 0x060 */
+ uint32_t cpu_ids[0x80]; /* 0x100 */
+ uint8_t scratch[0x200]; /* 0x180 */
+ char serial[32]; /* 0x380 */
+ char unk8[32]; /* 0x3a0 */
+ char model[32]; /* 0x3c0 */
+ uint8_t unk9[32]; /* 0x3e0 */
+ uint32_t unk10; /* 0x400 */
+ char soc_name[32]; /* 0x404 */
+} VMAppleCfg;
+
+struct VMAppleCfgState {
+ SysBusDevice parent_obj;
+ VMAppleCfg cfg;
+
+ MemoryRegion mem;
+ char *serial;
+ char *model;
+ char *soc_name;
+};
+
+static void vmapple_cfg_reset(Object *obj, ResetType type)
+{
+ VMAppleCfgState *s = VMAPPLE_CFG(obj);
+ VMAppleCfg *cfg;
+
+ cfg = memory_region_get_ram_ptr(&s->mem);
+ memset(cfg, 0, VMAPPLE_CFG_SIZE);
+ *cfg = s->cfg;
+}
+
+static bool set_fixlen_property_or_error(char *restrict dst,
+ const char *restrict src,
+ size_t dst_size, Error **errp,
+ const char *property_name)
+{
+ ERRP_GUARD();
+ size_t len;
+
+ len = g_strlcpy(dst, src, dst_size);
+ if (len < dst_size) { /* len does not count nul terminator */
+ return true;
+ }
+
+ error_setg(errp, "Provided value too long for property '%s'", property_name);
+ error_append_hint(errp, "length (%zu) exceeds maximum of %zu\n",
+ len, dst_size - 1);
+ return false;
+}
+
+#define set_fixlen_property_or_return(dst_array, src, errp, property_name) \
+ do { \
+ if (!set_fixlen_property_or_error((dst_array), (src), \
+ ARRAY_SIZE(dst_array), \
+ (errp), (property_name))) { \
+ return; \
+ } \
+ } while (0)
+
+static void vmapple_cfg_realize(DeviceState *dev, Error **errp)
+{
+ VMAppleCfgState *s = VMAPPLE_CFG(dev);
+ uint32_t i;
+
+ if (!s->serial) {
+ s->serial = g_strdup("1234");
+ }
+ if (!s->model) {
+ s->model = g_strdup("VM0001");
+ }
+ if (!s->soc_name) {
+ s->soc_name = g_strdup("Apple M1 (Virtual)");
+ }
+
+ set_fixlen_property_or_return(s->cfg.serial, s->serial, errp, "serial");
+ set_fixlen_property_or_return(s->cfg.model, s->model, errp, "model");
+ set_fixlen_property_or_return(s->cfg.soc_name, s->soc_name, errp, "soc_name");
+ set_fixlen_property_or_return(s->cfg.unk8, "D/A", errp, "unk8");
+ s->cfg.version = 2;
+ s->cfg.unk1 = 1;
+ s->cfg.unk2 = 1;
+ s->cfg.unk3 = 0x20;
+ s->cfg.unk4 = 0;
+ s->cfg.unk5 = 1;
+ s->cfg.unk6 = 1;
+ s->cfg.unk7 = 0;
+ s->cfg.unk10 = 1;
+
+ if (s->cfg.nr_cpus > ARRAY_SIZE(s->cfg.cpu_ids)) {
+ error_setg(errp,
+ "Failed to create %u CPUs, vmapple machine supports %zu max",
+ s->cfg.nr_cpus, ARRAY_SIZE(s->cfg.cpu_ids));
+ return;
+ }
+ for (i = 0; i < s->cfg.nr_cpus; i++) {
+ s->cfg.cpu_ids[i] = i;
+ }
+}
+
+static void vmapple_cfg_init(Object *obj)
+{
+ VMAppleCfgState *s = VMAPPLE_CFG(obj);
+
+ memory_region_init_ram(&s->mem, obj, "VMApple Config", VMAPPLE_CFG_SIZE,
+ &error_fatal);
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mem);
+}
+
+static const Property vmapple_cfg_properties[] = {
+ DEFINE_PROP_UINT32("nr-cpus", VMAppleCfgState, cfg.nr_cpus, 1),
+ DEFINE_PROP_UINT64("ecid", VMAppleCfgState, cfg.ecid, 0),
+ DEFINE_PROP_UINT64("ram-size", VMAppleCfgState, cfg.ram_size, 0),
+ DEFINE_PROP_UINT32("run_installer1", VMAppleCfgState, cfg.run_installer1, 0),
+ DEFINE_PROP_UINT32("run_installer2", VMAppleCfgState, cfg.run_installer2, 0),
+ DEFINE_PROP_UINT32("rnd", VMAppleCfgState, cfg.rnd, 0),
+ DEFINE_PROP_MACADDR("mac-en0", VMAppleCfgState, cfg.mac_en0),
+ DEFINE_PROP_MACADDR("mac-en1", VMAppleCfgState, cfg.mac_en1),
+ DEFINE_PROP_MACADDR("mac-wifi0", VMAppleCfgState, cfg.mac_wifi0),
+ DEFINE_PROP_MACADDR("mac-bt0", VMAppleCfgState, cfg.mac_bt0),
+ DEFINE_PROP_STRING("serial", VMAppleCfgState, serial),
+ DEFINE_PROP_STRING("model", VMAppleCfgState, model),
+ DEFINE_PROP_STRING("soc_name", VMAppleCfgState, soc_name),
+};
+
+static void vmapple_cfg_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
+
+ dc->realize = vmapple_cfg_realize;
+ dc->desc = "VMApple Configuration Region";
+ device_class_set_props(dc, vmapple_cfg_properties);
+ rc->phases.hold = vmapple_cfg_reset;
+}
+
+static const TypeInfo vmapple_cfg_info = {
+ .name = TYPE_VMAPPLE_CFG,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(VMAppleCfgState),
+ .instance_init = vmapple_cfg_init,
+ .class_init = vmapple_cfg_class_init,
+};
+
+static void vmapple_cfg_register_types(void)
+{
+ type_register_static(&vmapple_cfg_info);
+}
+
+type_init(vmapple_cfg_register_types)
diff --git a/hw/vmapple/Kconfig b/hw/vmapple/Kconfig
index ff5f97c292e..f5898661a91 100644
--- a/hw/vmapple/Kconfig
+++ b/hw/vmapple/Kconfig
@@ -5,3 +5,6 @@ config VMAPPLE_AES
config VMAPPLE_BDIF
bool
+
+config VMAPPLE_CFG
+ bool
diff --git a/hw/vmapple/meson.build b/hw/vmapple/meson.build
index e2aca6b7c2b..9e881c7b555 100644
--- a/hw/vmapple/meson.build
+++ b/hw/vmapple/meson.build
@@ -2,3 +2,4 @@
system_ss.add(when: 'CONFIG_VMAPPLE_AES', if_true: files('aes.c'))
system_ss.add(when: 'CONFIG_VMAPPLE_BDIF', if_true: files('bdif.c'))
+system_ss.add(when: 'CONFIG_VMAPPLE_CFG', if_true: files('cfg.c'))
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 07/41] hw/vmapple/virtio-blk: Add support for apple virtio-blk
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (5 preceding siblings ...)
2025-03-05 1:21 ` [PULL 06/41] hw/vmapple/cfg: Introduce vmapple cfg region Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 08/41] hw/usb/hcd-xhci-pci: Adds property for disabling mapping in IRQ mode Philippe Mathieu-Daudé
` (33 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, Phil Dennis-Jordan, Akihiko Odaki,
Michael S. Tsirkin, Philippe Mathieu-Daudé
From: Alexander Graf <graf@amazon.com>
Apple has its own virtio-blk PCI device ID where it deviates from the
official virtio-pci spec slightly: It puts a new "apple type"
field at a static offset in config space and introduces a new barrier
command.
This patch first creates a mechanism for virtio-blk downstream classes to
handle unknown commands. It then creates such a downstream class and a new
vmapple-virtio-blk-pci class which support the additional apple type config
identifier as well as the barrier command.
The 'aux' or 'root' device type are selected using the 'variant' property.
Signed-off-by: Alexander Graf <graf@amazon.com>
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20241223221645.29911-13-phil@philjordan.eu>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
qapi/virtio.json | 14 ++
include/hw/pci/pci_ids.h | 1 +
include/hw/qdev-properties-system.h | 6 +
include/hw/virtio/virtio-blk.h | 11 +-
include/hw/vmapple/vmapple.h | 2 +
hw/block/virtio-blk.c | 17 ++-
hw/core/qdev-properties-system.c | 9 ++
hw/vmapple/virtio-blk.c | 204 ++++++++++++++++++++++++++++
hw/vmapple/Kconfig | 3 +
hw/vmapple/meson.build | 1 +
10 files changed, 264 insertions(+), 4 deletions(-)
create mode 100644 hw/vmapple/virtio-blk.c
diff --git a/qapi/virtio.json b/qapi/virtio.json
index 2529c2d8b20..d351d2166ef 100644
--- a/qapi/virtio.json
+++ b/qapi/virtio.json
@@ -992,3 +992,17 @@
##
{ 'enum': 'GranuleMode',
'data': [ '4k', '8k', '16k', '64k', 'host' ] }
+
+##
+# @VMAppleVirtioBlkVariant:
+#
+# @unspecified: The default, not a valid setting.
+#
+# @root: Block device holding the root volume
+#
+# @aux: Block device holding auxiliary data required for boot
+#
+# Since: 9.2
+##
+{ 'enum': 'VMAppleVirtioBlkVariant',
+ 'data': [ 'unspecified', 'root', 'aux' ] }
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
index f1a53fea8d6..33e2898be95 100644
--- a/include/hw/pci/pci_ids.h
+++ b/include/hw/pci/pci_ids.h
@@ -191,6 +191,7 @@
#define PCI_DEVICE_ID_APPLE_UNI_N_AGP 0x0020
#define PCI_DEVICE_ID_APPLE_U3_AGP 0x004b
#define PCI_DEVICE_ID_APPLE_UNI_N_GMAC 0x0021
+#define PCI_DEVICE_ID_APPLE_VIRTIO_BLK 0x1a00
#define PCI_VENDOR_ID_SUN 0x108e
#define PCI_DEVICE_ID_SUN_EBUS 0x1000
diff --git a/include/hw/qdev-properties-system.h b/include/hw/qdev-properties-system.h
index ead4dfc2f02..b921392c525 100644
--- a/include/hw/qdev-properties-system.h
+++ b/include/hw/qdev-properties-system.h
@@ -31,6 +31,7 @@ extern const PropertyInfo qdev_prop_pcie_link_width;
extern const PropertyInfo qdev_prop_cpus390entitlement;
extern const PropertyInfo qdev_prop_iothread_vq_mapping_list;
extern const PropertyInfo qdev_prop_endian_mode;
+extern const PropertyInfo qdev_prop_vmapple_virtio_blk_variant;
#define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d) \
DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t)
@@ -104,4 +105,9 @@ extern const PropertyInfo qdev_prop_endian_mode;
#define DEFINE_PROP_ENDIAN_NODEFAULT(_name, _state, _field) \
DEFINE_PROP_ENDIAN(_name, _state, _field, ENDIAN_MODE_UNSPECIFIED)
+#define DEFINE_PROP_VMAPPLE_VIRTIO_BLK_VARIANT(_name, _state, _fld, _default) \
+ DEFINE_PROP_UNSIGNED(_name, _state, _fld, _default, \
+ qdev_prop_vmapple_virtio_blk_variant, \
+ VMAppleVirtioBlkVariant)
+
#endif
diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h
index 8a16218c409..3d8dee7ec15 100644
--- a/include/hw/virtio/virtio-blk.h
+++ b/include/hw/virtio/virtio-blk.h
@@ -24,7 +24,7 @@
#include "qapi/qapi-types-virtio.h"
#define TYPE_VIRTIO_BLK "virtio-blk-device"
-OBJECT_DECLARE_SIMPLE_TYPE(VirtIOBlock, VIRTIO_BLK)
+OBJECT_DECLARE_TYPE(VirtIOBlock, VirtIOBlkClass, VIRTIO_BLK)
/* This is the last element of the write scatter-gather list */
struct virtio_blk_inhdr
@@ -100,6 +100,15 @@ typedef struct MultiReqBuffer {
bool is_write;
} MultiReqBuffer;
+typedef struct VirtIOBlkClass {
+ /*< private >*/
+ VirtioDeviceClass parent;
+ /*< public >*/
+ bool (*handle_unknown_request)(VirtIOBlockReq *req, MultiReqBuffer *mrb,
+ uint32_t type);
+} VirtIOBlkClass;
+
void virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq);
+void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status);
#endif
diff --git a/include/hw/vmapple/vmapple.h b/include/hw/vmapple/vmapple.h
index 3bba59f5ec7..9c1ad1bd8c3 100644
--- a/include/hw/vmapple/vmapple.h
+++ b/include/hw/vmapple/vmapple.h
@@ -18,4 +18,6 @@
#define TYPE_VMAPPLE_CFG "vmapple-cfg"
+#define TYPE_VMAPPLE_VIRTIO_BLK_PCI "vmapple-virtio-blk-pci"
+
#endif /* HW_VMAPPLE_VMAPPLE_H */
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index a1829e3abdf..5135b4d8f1e 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -50,7 +50,7 @@ static void virtio_blk_init_request(VirtIOBlock *s, VirtQueue *vq,
req->mr_next = NULL;
}
-static void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status)
+void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status)
{
VirtIOBlock *s = req->dev;
VirtIODevice *vdev = VIRTIO_DEVICE(s);
@@ -961,8 +961,18 @@ static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
break;
}
default:
- virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
- g_free(req);
+ {
+ /*
+ * Give subclasses a chance to handle unknown requests. This way the
+ * class lookup is not in the hot path.
+ */
+ VirtIOBlkClass *vbk = VIRTIO_BLK_GET_CLASS(s);
+ if (!vbk->handle_unknown_request ||
+ !vbk->handle_unknown_request(req, mrb, type)) {
+ virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
+ g_free(req);
+ }
+ }
}
return 0;
}
@@ -2029,6 +2039,7 @@ static const TypeInfo virtio_blk_info = {
.instance_size = sizeof(VirtIOBlock),
.instance_init = virtio_blk_instance_init,
.class_init = virtio_blk_class_init,
+ .class_size = sizeof(VirtIOBlkClass),
};
static void virtio_register_types(void)
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 89f954f569e..a91551a5ee8 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -1294,3 +1294,12 @@ const PropertyInfo qdev_prop_endian_mode = {
.set = qdev_propinfo_set_enum,
.set_default_value = qdev_propinfo_set_default_value_enum,
};
+
+const PropertyInfo qdev_prop_vmapple_virtio_blk_variant = {
+ .name = "VMAppleVirtioBlkVariant",
+ .description = "unspecified/root/aux",
+ .enum_table = &VMAppleVirtioBlkVariant_lookup,
+ .get = qdev_propinfo_get_enum,
+ .set = qdev_propinfo_set_enum,
+ .set_default_value = qdev_propinfo_set_default_value_enum,
+};
diff --git a/hw/vmapple/virtio-blk.c b/hw/vmapple/virtio-blk.c
new file mode 100644
index 00000000000..aa3f18c47db
--- /dev/null
+++ b/hw/vmapple/virtio-blk.c
@@ -0,0 +1,204 @@
+/*
+ * VMApple specific VirtIO Block implementation
+ *
+ * Copyright © 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * VMApple uses almost standard VirtIO Block, but with a few key differences:
+ *
+ * - Different PCI device/vendor ID
+ * - An additional "type" identifier to differentiate AUX and Root volumes
+ * - An additional BARRIER command
+ */
+
+#include "qemu/osdep.h"
+#include "hw/vmapple/vmapple.h"
+#include "hw/virtio/virtio-blk.h"
+#include "hw/virtio/virtio-pci.h"
+#include "qemu/bswap.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qapi/error.h"
+
+#define TYPE_VMAPPLE_VIRTIO_BLK "vmapple-virtio-blk"
+OBJECT_DECLARE_TYPE(VMAppleVirtIOBlk, VMAppleVirtIOBlkClass, VMAPPLE_VIRTIO_BLK)
+
+typedef struct VMAppleVirtIOBlkClass {
+ VirtIOBlkClass parent;
+
+ void (*get_config)(VirtIODevice *vdev, uint8_t *config);
+} VMAppleVirtIOBlkClass;
+
+typedef struct VMAppleVirtIOBlk {
+ VirtIOBlock parent_obj;
+
+ uint32_t apple_type;
+} VMAppleVirtIOBlk;
+
+/*
+ * vmapple-virtio-blk-pci: This extends VirtioPCIProxy.
+ */
+OBJECT_DECLARE_SIMPLE_TYPE(VMAppleVirtIOBlkPCI, VMAPPLE_VIRTIO_BLK_PCI)
+
+#define VIRTIO_BLK_T_APPLE_BARRIER 0x10000
+
+static bool vmapple_virtio_blk_handle_unknown_request(VirtIOBlockReq *req,
+ MultiReqBuffer *mrb,
+ uint32_t type)
+{
+ switch (type) {
+ case VIRTIO_BLK_T_APPLE_BARRIER:
+ qemu_log_mask(LOG_UNIMP, "%s: Barrier requests are currently no-ops\n",
+ __func__);
+ virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
+ g_free(req);
+ return true;
+ default:
+ return false;
+ }
+}
+
+/*
+ * VMApple virtio-blk uses the same config format as normal virtio, with one
+ * exception: It adds an "apple type" specififer at the same location that
+ * the spec reserves for max_secure_erase_sectors. Let's hook into the
+ * get_config code path here, run it as usual and then patch in the apple type.
+ */
+static void vmapple_virtio_blk_get_config(VirtIODevice *vdev, uint8_t *config)
+{
+ VMAppleVirtIOBlk *dev = VMAPPLE_VIRTIO_BLK(vdev);
+ VMAppleVirtIOBlkClass *vvbk = VMAPPLE_VIRTIO_BLK_GET_CLASS(dev);
+ struct virtio_blk_config *blkcfg = (struct virtio_blk_config *)config;
+
+ vvbk->get_config(vdev, config);
+
+ g_assert(dev->parent_obj.config_size >= endof(struct virtio_blk_config, zoned));
+
+ /* Apple abuses the field for max_secure_erase_sectors as type id */
+ stl_he_p(&blkcfg->max_secure_erase_sectors, dev->apple_type);
+}
+
+static void vmapple_virtio_blk_class_init(ObjectClass *klass, void *data)
+{
+ VirtIOBlkClass *vbk = VIRTIO_BLK_CLASS(klass);
+ VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+ VMAppleVirtIOBlkClass *vvbk = VMAPPLE_VIRTIO_BLK_CLASS(klass);
+
+ vbk->handle_unknown_request = vmapple_virtio_blk_handle_unknown_request;
+ vvbk->get_config = vdc->get_config;
+ vdc->get_config = vmapple_virtio_blk_get_config;
+}
+
+static const TypeInfo vmapple_virtio_blk_info = {
+ .name = TYPE_VMAPPLE_VIRTIO_BLK,
+ .parent = TYPE_VIRTIO_BLK,
+ .instance_size = sizeof(VMAppleVirtIOBlk),
+ .class_size = sizeof(VMAppleVirtIOBlkClass),
+ .class_init = vmapple_virtio_blk_class_init,
+};
+
+/* PCI Devices */
+
+struct VMAppleVirtIOBlkPCI {
+ VirtIOPCIProxy parent_obj;
+
+ VMAppleVirtIOBlk vdev;
+ VMAppleVirtioBlkVariant variant;
+};
+
+static const Property vmapple_virtio_blk_pci_properties[] = {
+ DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0),
+ DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
+ VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
+ DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
+ DEV_NVECTORS_UNSPECIFIED),
+ DEFINE_PROP_VMAPPLE_VIRTIO_BLK_VARIANT("variant", VMAppleVirtIOBlkPCI, variant,
+ VM_APPLE_VIRTIO_BLK_VARIANT_UNSPECIFIED),
+};
+
+static void vmapple_virtio_blk_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
+{
+ ERRP_GUARD();
+ VMAppleVirtIOBlkPCI *dev = VMAPPLE_VIRTIO_BLK_PCI(vpci_dev);
+ DeviceState *vdev = DEVICE(&dev->vdev);
+ VirtIOBlkConf *conf = &dev->vdev.parent_obj.conf;
+
+ if (dev->variant == VM_APPLE_VIRTIO_BLK_VARIANT_UNSPECIFIED) {
+ error_setg(errp, "vmapple virtio block device variant unspecified");
+ error_append_hint(errp,
+ "Variant property must be set to 'aux' or 'root'.\n"
+ "Use a regular virtio-blk-pci device instead when "
+ "neither is applicaple.\n");
+ return;
+ }
+
+ if (conf->num_queues == VIRTIO_BLK_AUTO_NUM_QUEUES) {
+ conf->num_queues = virtio_pci_optimal_num_queues(0);
+ }
+
+ if (vpci_dev->nvectors == DEV_NVECTORS_UNSPECIFIED) {
+ vpci_dev->nvectors = conf->num_queues + 1;
+ }
+
+ /*
+ * We don't support zones, but we need the additional config space size.
+ * Let's just expose the feature so the rest of the virtio-blk logic
+ * allocates enough space for us. The guest will ignore zones anyway.
+ */
+ virtio_add_feature(&dev->vdev.parent_obj.host_features, VIRTIO_BLK_F_ZONED);
+ /* Propagate the apple type down to the virtio-blk device */
+ dev->vdev.apple_type = dev->variant;
+ /* and spawn the virtio-blk device */
+ qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
+
+ /*
+ * The virtio-pci machinery adjusts its vendor/device ID based on whether
+ * we support modern or legacy virtio. Let's patch it back to the Apple
+ * identifiers here.
+ */
+ pci_config_set_vendor_id(vpci_dev->pci_dev.config, PCI_VENDOR_ID_APPLE);
+ pci_config_set_device_id(vpci_dev->pci_dev.config,
+ PCI_DEVICE_ID_APPLE_VIRTIO_BLK);
+}
+
+static void vmapple_virtio_blk_pci_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+ PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+
+ set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
+ device_class_set_props(dc, vmapple_virtio_blk_pci_properties);
+ k->realize = vmapple_virtio_blk_pci_realize;
+ pcidev_k->vendor_id = PCI_VENDOR_ID_APPLE;
+ pcidev_k->device_id = PCI_DEVICE_ID_APPLE_VIRTIO_BLK;
+ pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
+ pcidev_k->class_id = PCI_CLASS_STORAGE_SCSI;
+}
+
+static void vmapple_virtio_blk_pci_instance_init(Object *obj)
+{
+ VMAppleVirtIOBlkPCI *dev = VMAPPLE_VIRTIO_BLK_PCI(obj);
+
+ virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
+ TYPE_VMAPPLE_VIRTIO_BLK);
+}
+
+static const VirtioPCIDeviceTypeInfo vmapple_virtio_blk_pci_info = {
+ .generic_name = TYPE_VMAPPLE_VIRTIO_BLK_PCI,
+ .instance_size = sizeof(VMAppleVirtIOBlkPCI),
+ .instance_init = vmapple_virtio_blk_pci_instance_init,
+ .class_init = vmapple_virtio_blk_pci_class_init,
+};
+
+static void vmapple_virtio_blk_register_types(void)
+{
+ type_register_static(&vmapple_virtio_blk_info);
+ virtio_pci_types_register(&vmapple_virtio_blk_pci_info);
+}
+
+type_init(vmapple_virtio_blk_register_types)
diff --git a/hw/vmapple/Kconfig b/hw/vmapple/Kconfig
index f5898661a91..5586fd460b7 100644
--- a/hw/vmapple/Kconfig
+++ b/hw/vmapple/Kconfig
@@ -8,3 +8,6 @@ config VMAPPLE_BDIF
config VMAPPLE_CFG
bool
+
+config VMAPPLE_VIRTIO_BLK
+ bool
diff --git a/hw/vmapple/meson.build b/hw/vmapple/meson.build
index 9e881c7b555..3553ec61518 100644
--- a/hw/vmapple/meson.build
+++ b/hw/vmapple/meson.build
@@ -3,3 +3,4 @@
system_ss.add(when: 'CONFIG_VMAPPLE_AES', if_true: files('aes.c'))
system_ss.add(when: 'CONFIG_VMAPPLE_BDIF', if_true: files('bdif.c'))
system_ss.add(when: 'CONFIG_VMAPPLE_CFG', if_true: files('cfg.c'))
+system_ss.add(when: 'CONFIG_VMAPPLE_VIRTIO_BLK', if_true: files('virtio-blk.c'))
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 08/41] hw/usb/hcd-xhci-pci: Adds property for disabling mapping in IRQ mode
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (6 preceding siblings ...)
2025-03-05 1:21 ` [PULL 07/41] hw/vmapple/virtio-blk: Add support for apple virtio-blk Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 09/41] hw/vmapple/vmapple: Add vmapple machine type Philippe Mathieu-Daudé
` (32 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: Phil Dennis-Jordan, Philippe Mathieu-Daudé
From: Phil Dennis-Jordan <phil@philjordan.eu>
This change addresses an edge case that trips up macOS guest drivers
for PCI based XHCI controllers. The guest driver would attempt to
schedule events to XHCI event rings 1 and 2 even when using PCI
pin-based interrupts. Interrupts would therefore be dropped, and events
only handled on timeout.
So, in addition to disabling interrupter mapping if numintrs is 1, a
callback is added to xhci to check whether interrupter mapping should be
enabled. The PCI XHCI device type now provides an implementation of
this callback if the new "conditional-intr-mapping" property is enabled.
(default: disabled) When enabled, interrupter mapping is only enabled
when MSI-X or MSI is active.
This means that when using pin-based interrupts, events are only
submitted to interrupter 0 regardless of selected target. This allows
the macOS guest drivers to work with the device in those configurations.
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2705
Message-ID: <20241227121336.25838-6-phil@philjordan.eu>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/usb/hcd-xhci-pci.h | 1 +
hw/usb/hcd-xhci.h | 5 +++++
hw/usb/hcd-xhci-pci.c | 24 ++++++++++++++++++++++++
hw/usb/hcd-xhci.c | 3 ++-
4 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/hw/usb/hcd-xhci-pci.h b/hw/usb/hcd-xhci-pci.h
index 08f70ce97cc..5b61ae84555 100644
--- a/hw/usb/hcd-xhci-pci.h
+++ b/hw/usb/hcd-xhci-pci.h
@@ -40,6 +40,7 @@ typedef struct XHCIPciState {
XHCIState xhci;
OnOffAuto msi;
OnOffAuto msix;
+ bool conditional_intr_mapping;
} XHCIPciState;
#endif
diff --git a/hw/usb/hcd-xhci.h b/hw/usb/hcd-xhci.h
index 9609b835141..9c3974f1489 100644
--- a/hw/usb/hcd-xhci.h
+++ b/hw/usb/hcd-xhci.h
@@ -193,6 +193,11 @@ typedef struct XHCIState {
uint32_t max_pstreams_mask;
void (*intr_update)(XHCIState *s, int n, bool enable);
bool (*intr_raise)(XHCIState *s, int n, bool level);
+ /*
+ * Callback for special-casing interrupter mapping support. NULL for most
+ * implementations, for defaulting to enabled mapping unless numintrs == 1.
+ */
+ bool (*intr_mapping_supported)(XHCIState *s);
DeviceState *hostOpaque;
/* Operational Registers */
diff --git a/hw/usb/hcd-xhci-pci.c b/hw/usb/hcd-xhci-pci.c
index 49642aab58e..d908eb787d3 100644
--- a/hw/usb/hcd-xhci-pci.c
+++ b/hw/usb/hcd-xhci-pci.c
@@ -82,6 +82,21 @@ static bool xhci_pci_intr_raise(XHCIState *xhci, int n, bool level)
return false;
}
+static bool xhci_pci_intr_mapping_conditional(XHCIState *xhci)
+{
+ XHCIPciState *s = container_of(xhci, XHCIPciState, xhci);
+ PCIDevice *pci_dev = PCI_DEVICE(s);
+
+ /*
+ * Implementation of the "conditional-intr-mapping" property, which only
+ * enables interrupter mapping if MSI or MSI-X is available and active.
+ * Forces all events onto interrupter/event ring 0 in pin-based IRQ mode.
+ * Provides compatibility with macOS guests on machine types where MSI(-X)
+ * is not available.
+ */
+ return msix_enabled(pci_dev) || msi_enabled(pci_dev);
+}
+
static void xhci_pci_reset(DeviceState *dev)
{
XHCIPciState *s = XHCI_PCI(dev);
@@ -119,6 +134,9 @@ static void usb_xhci_pci_realize(struct PCIDevice *dev, Error **errp)
object_property_set_link(OBJECT(&s->xhci), "host", OBJECT(s), NULL);
s->xhci.intr_update = xhci_pci_intr_update;
s->xhci.intr_raise = xhci_pci_intr_raise;
+ if (s->conditional_intr_mapping) {
+ s->xhci.intr_mapping_supported = xhci_pci_intr_mapping_conditional;
+ }
if (!qdev_realize(DEVICE(&s->xhci), NULL, errp)) {
return;
}
@@ -201,6 +219,8 @@ static void xhci_instance_init(Object *obj)
static const Property xhci_pci_properties[] = {
DEFINE_PROP_ON_OFF_AUTO("msi", XHCIPciState, msi, ON_OFF_AUTO_AUTO),
DEFINE_PROP_ON_OFF_AUTO("msix", XHCIPciState, msix, ON_OFF_AUTO_AUTO),
+ DEFINE_PROP_BOOL("conditional-intr-mapping", XHCIPciState,
+ conditional_intr_mapping, false),
};
static void xhci_class_init(ObjectClass *klass, void *data)
@@ -215,6 +235,10 @@ static void xhci_class_init(ObjectClass *klass, void *data)
k->exit = usb_xhci_pci_exit;
k->class_id = PCI_CLASS_SERIAL_USB;
device_class_set_props(dc, xhci_pci_properties);
+ object_class_property_set_description(klass, "conditional-intr-mapping",
+ "When true, disables interrupter mapping for pin-based IRQ mode. "
+ "Intended to be used with guest drivers with questionable behaviour, "
+ "such as macOS's.");
}
static const TypeInfo xhci_pci_info = {
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 00d5bc37792..64c3a23b9b7 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -644,7 +644,8 @@ static void xhci_event(XHCIState *xhci, XHCIEvent *event, int v)
dma_addr_t erdp;
unsigned int dp_idx;
- if (xhci->numintrs == 1) {
+ if (xhci->numintrs == 1 ||
+ (xhci->intr_mapping_supported && !xhci->intr_mapping_supported(xhci))) {
v = 0;
}
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 09/41] hw/vmapple/vmapple: Add vmapple machine type
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (7 preceding siblings ...)
2025-03-05 1:21 ` [PULL 08/41] hw/usb/hcd-xhci-pci: Adds property for disabling mapping in IRQ mode Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-10 1:22 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 10/41] hw/ppc/spapr: Restrict part of PAGE_INIT hypercall to TCG Philippe Mathieu-Daudé
` (31 subsequent siblings)
40 siblings, 1 reply; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, Phil Dennis-Jordan, Akihiko Odaki,
Philippe Mathieu-Daudé
From: Alexander Graf <graf@amazon.com>
Apple defines a new "vmapple" machine type as part of its proprietary
macOS Virtualization.Framework vmm. This machine type is similar to the
virt one, but with subtle differences in base devices, a few special
vmapple device additions and a vastly different boot chain.
This patch reimplements this machine type in QEMU. To use it, you
have to have a readily installed version of macOS for VMApple,
run on macOS with -accel hvf, pass the Virtualization.Framework
boot rom (AVPBooter) in via -bios, pass the aux and root volume as pflash
and pass aux and root volume as virtio drives. In addition, you also
need to find the machine UUID and pass that as -M vmapple,uuid= parameter:
$ qemu-system-aarch64 -accel hvf -M vmapple,uuid=0x1234 -m 4G \
-bios /System/Library/Frameworks/Virtualization.framework/Versions/A/Resources/AVPBooter.vmapple2.bin
-drive file=aux,if=pflash,format=raw \
-drive file=root,if=pflash,format=raw \
-drive file=aux,if=none,id=aux,format=raw \
-device vmapple-virtio-blk-pci,variant=aux,drive=aux \
-drive file=root,if=none,id=root,format=raw \
-device vmapple-virtio-blk-pci,variant=root,drive=root
With all these in place, you should be able to see macOS booting
successfully.
Known issues:
- Currently only macOS 12 guests are supported. The boot process for
13+ will need further investigation and adjustment.
Signed-off-by: Alexander Graf <graf@amazon.com>
Co-authored-by: Phil Dennis-Jordan <phil@philjordan.eu>
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Message-ID: <20241223221645.29911-15-phil@philjordan.eu>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
MAINTAINERS | 1 +
docs/system/arm/vmapple.rst | 65 ++++
docs/system/target-arm.rst | 1 +
hw/vmapple/vmapple.c | 618 ++++++++++++++++++++++++++++++++++++
contrib/vmapple/uuid.sh | 12 +
hw/vmapple/Kconfig | 21 ++
hw/vmapple/meson.build | 1 +
7 files changed, 719 insertions(+)
create mode 100644 docs/system/arm/vmapple.rst
create mode 100644 hw/vmapple/vmapple.c
create mode 100755 contrib/vmapple/uuid.sh
diff --git a/MAINTAINERS b/MAINTAINERS
index 0e160360918..d1e69539de0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2826,6 +2826,7 @@ M: Phil Dennis-Jordan <phil@philjordan.eu>
S: Maintained
F: hw/vmapple/*
F: include/hw/vmapple/*
+F: docs/system/arm/vmapple.rst
Subsystems
----------
diff --git a/docs/system/arm/vmapple.rst b/docs/system/arm/vmapple.rst
new file mode 100644
index 00000000000..35c329ea5a8
--- /dev/null
+++ b/docs/system/arm/vmapple.rst
@@ -0,0 +1,65 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
+VMApple machine emulation
+========================================================================================
+
+VMApple is the device model that the macOS built-in hypervisor called "Virtualization.framework"
+exposes to Apple Silicon macOS guests. The "vmapple" machine model in QEMU implements the same
+device model, but does not use any code from Virtualization.Framework.
+
+Prerequisites
+-------------
+
+To run the vmapple machine model, you need to
+
+ * Run on Apple Silicon
+ * Run on macOS 12.0 or above
+ * Have an already installed copy of a Virtualization.Framework macOS 12 virtual
+ machine. Note that newer versions than 12.x are currently NOT supported on
+ the guest side. I will assume that you installed it using the
+ `macosvm <https://github.com/s-u/macosvm>`__ CLI.
+
+First, we need to extract the UUID from the virtual machine that you installed. You can do this
+by running the shell script in contrib/vmapple/uuid.sh on the macosvm.json file.
+
+.. code-block:: bash
+ :caption: uuid.sh script to extract the UUID from a macosvm.json file
+
+ $ contrib/vmapple/uuid.sh "path/to/macosvm.json"
+
+Now we also need to trim the aux partition. It contains metadata that we can just discard:
+
+.. code-block:: bash
+ :caption: Command to trim the aux file
+
+ $ dd if="aux.img" of="aux.img.trimmed" bs=$(( 0x4000 )) skip=1
+
+How to run
+----------
+
+Then, we can launch QEMU with the Virtualization.Framework pre-boot environment and the readily
+installed target disk images. I recommend to port forward the VM's ssh and vnc ports to the host
+to get better interactive access into the target system:
+
+.. code-block:: bash
+ :caption: Example execution command line
+
+ $ UUID="$(contrib/vmapple/uuid.sh 'macosvm.json')"
+ $ AVPBOOTER="/System/Library/Frameworks/Virtualization.framework/Resources/AVPBooter.vmapple2.bin"
+ $ AUX="aux.img.trimmed"
+ $ DISK="disk.img"
+ $ qemu-system-aarch64 \
+ -serial mon:stdio \
+ -m 4G \
+ -accel hvf \
+ -M vmapple,uuid="$UUID" \
+ -bios "$AVPBOOTER" \
+ -drive file="$AUX",if=pflash,format=raw \
+ -drive file="$DISK",if=pflash,format=raw \
+ -drive file="$AUX",if=none,id=aux,format=raw \
+ -drive file="$DISK",if=none,id=root,format=raw \
+ -device vmapple-virtio-blk-pci,variant=aux,drive=aux \
+ -device vmapple-virtio-blk-pci,variant=root,drive=root \
+ -netdev user,id=net0,ipv6=off,hostfwd=tcp::2222-:22,hostfwd=tcp::5901-:5900 \
+ -device virtio-net-pci,netdev=net0
+
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
index a43ec8f10e0..b96a05a9206 100644
--- a/docs/system/target-arm.rst
+++ b/docs/system/target-arm.rst
@@ -103,6 +103,7 @@ Board-specific documentation
arm/stellaris
arm/stm32
arm/virt
+ arm/vmapple
arm/xenpvh
arm/xlnx-versal-virt
arm/xlnx-zynq
diff --git a/hw/vmapple/vmapple.c b/hw/vmapple/vmapple.c
new file mode 100644
index 00000000000..fa117bf1511
--- /dev/null
+++ b/hw/vmapple/vmapple.c
@@ -0,0 +1,618 @@
+/*
+ * VMApple machine emulation
+ *
+ * Copyright © 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * VMApple is the device model that the macOS built-in hypervisor called
+ * "Virtualization.framework" exposes to Apple Silicon macOS guests. The
+ * machine model in this file implements the same device model in QEMU, but
+ * does not use any code from Virtualization.Framework.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/bitops.h"
+#include "qemu/datadir.h"
+#include "qemu/error-report.h"
+#include "qemu/guest-random.h"
+#include "qemu/help-texts.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/option.h"
+#include "qemu/units.h"
+#include "monitor/qdev.h"
+#include "hw/boards.h"
+#include "hw/irq.h"
+#include "hw/loader.h"
+#include "hw/qdev-properties.h"
+#include "hw/sysbus.h"
+#include "hw/usb.h"
+#include "hw/arm/boot.h"
+#include "hw/arm/primecell.h"
+#include "hw/char/pl011.h"
+#include "hw/intc/arm_gic.h"
+#include "hw/intc/arm_gicv3_common.h"
+#include "hw/misc/pvpanic.h"
+#include "hw/pci-host/gpex.h"
+#include "hw/usb/hcd-xhci-pci.h"
+#include "hw/virtio/virtio-pci.h"
+#include "hw/vmapple/vmapple.h"
+#include "net/net.h"
+#include "qapi/error.h"
+#include "qapi/visitor.h"
+#include "qapi/qapi-visit-common.h"
+#include "qobject/qlist.h"
+#include "standard-headers/linux/input.h"
+#include "system/hvf.h"
+#include "system/reset.h"
+#include "system/runstate.h"
+#include "system/system.h"
+
+struct VMAppleMachineState {
+ MachineState parent;
+
+ Notifier machine_done;
+ struct arm_boot_info bootinfo;
+ const MemMapEntry *memmap;
+ const int *irqmap;
+ DeviceState *gic;
+ DeviceState *cfg;
+ DeviceState *pvpanic;
+ Notifier powerdown_notifier;
+ PCIBus *bus;
+ MemoryRegion fw_mr;
+ MemoryRegion ecam_alias;
+ uint64_t uuid;
+};
+
+#define TYPE_VMAPPLE_MACHINE MACHINE_TYPE_NAME("vmapple")
+OBJECT_DECLARE_SIMPLE_TYPE(VMAppleMachineState, VMAPPLE_MACHINE)
+
+/* Number of external interrupt lines to configure the GIC with */
+#define NUM_IRQS 256
+
+enum {
+ VMAPPLE_FIRMWARE,
+ VMAPPLE_CONFIG,
+ VMAPPLE_MEM,
+ VMAPPLE_GIC_DIST,
+ VMAPPLE_GIC_REDIST,
+ VMAPPLE_UART,
+ VMAPPLE_RTC,
+ VMAPPLE_PCIE,
+ VMAPPLE_PCIE_MMIO,
+ VMAPPLE_PCIE_ECAM,
+ VMAPPLE_GPIO,
+ VMAPPLE_PVPANIC,
+ VMAPPLE_APV_GFX,
+ VMAPPLE_APV_IOSFC,
+ VMAPPLE_AES_1,
+ VMAPPLE_AES_2,
+ VMAPPLE_BDOOR,
+ VMAPPLE_MEMMAP_LAST,
+};
+
+static const MemMapEntry memmap[] = {
+ [VMAPPLE_FIRMWARE] = { 0x00100000, 0x00100000 },
+ [VMAPPLE_CONFIG] = { 0x00400000, 0x00010000 },
+
+ [VMAPPLE_GIC_DIST] = { 0x10000000, 0x00010000 },
+ [VMAPPLE_GIC_REDIST] = { 0x10010000, 0x00400000 },
+
+ [VMAPPLE_UART] = { 0x20010000, 0x00010000 },
+ [VMAPPLE_RTC] = { 0x20050000, 0x00001000 },
+ [VMAPPLE_GPIO] = { 0x20060000, 0x00001000 },
+ [VMAPPLE_PVPANIC] = { 0x20070000, 0x00000002 },
+ [VMAPPLE_BDOOR] = { 0x30000000, 0x00200000 },
+ [VMAPPLE_APV_GFX] = { 0x30200000, 0x00010000 },
+ [VMAPPLE_APV_IOSFC] = { 0x30210000, 0x00010000 },
+ [VMAPPLE_AES_1] = { 0x30220000, 0x00004000 },
+ [VMAPPLE_AES_2] = { 0x30230000, 0x00004000 },
+ [VMAPPLE_PCIE_ECAM] = { 0x40000000, 0x10000000 },
+ [VMAPPLE_PCIE_MMIO] = { 0x50000000, 0x1fff0000 },
+
+ /* Actual RAM size depends on configuration */
+ [VMAPPLE_MEM] = { 0x70000000ULL, GiB},
+};
+
+static const int irqmap[] = {
+ [VMAPPLE_UART] = 1,
+ [VMAPPLE_RTC] = 2,
+ [VMAPPLE_GPIO] = 0x5,
+ [VMAPPLE_APV_IOSFC] = 0x10,
+ [VMAPPLE_APV_GFX] = 0x11,
+ [VMAPPLE_AES_1] = 0x12,
+ [VMAPPLE_PCIE] = 0x20,
+};
+
+#define GPEX_NUM_IRQS 16
+
+static void create_bdif(VMAppleMachineState *vms, MemoryRegion *mem)
+{
+ DeviceState *bdif;
+ SysBusDevice *bdif_sb;
+ DriveInfo *di_aux = drive_get(IF_PFLASH, 0, 0);
+ DriveInfo *di_root = drive_get(IF_PFLASH, 0, 1);
+
+ if (!di_aux) {
+ error_report("No AUX device. Please specify one as pflash drive.");
+ exit(1);
+ }
+
+ if (!di_root) {
+ /* Fall back to the first IF_VIRTIO device as root device */
+ di_root = drive_get(IF_VIRTIO, 0, 0);
+ }
+
+ if (!di_root) {
+ error_report("No root device. Please specify one as virtio drive.");
+ exit(1);
+ }
+
+ /* PV backdoor device */
+ bdif = qdev_new(TYPE_VMAPPLE_BDIF);
+ bdif_sb = SYS_BUS_DEVICE(bdif);
+ sysbus_mmio_map(bdif_sb, 0, vms->memmap[VMAPPLE_BDOOR].base);
+
+ qdev_prop_set_drive(DEVICE(bdif), "aux", blk_by_legacy_dinfo(di_aux));
+ qdev_prop_set_drive(DEVICE(bdif), "root", blk_by_legacy_dinfo(di_root));
+
+ sysbus_realize_and_unref(bdif_sb, &error_fatal);
+}
+
+static void create_pvpanic(VMAppleMachineState *vms, MemoryRegion *mem)
+{
+ SysBusDevice *pvpanic;
+
+ vms->pvpanic = qdev_new(TYPE_PVPANIC_MMIO_DEVICE);
+ pvpanic = SYS_BUS_DEVICE(vms->pvpanic);
+ sysbus_mmio_map(pvpanic, 0, vms->memmap[VMAPPLE_PVPANIC].base);
+
+ sysbus_realize_and_unref(pvpanic, &error_fatal);
+}
+
+static bool create_cfg(VMAppleMachineState *vms, MemoryRegion *mem,
+ Error **errp)
+{
+ ERRP_GUARD();
+ SysBusDevice *cfg;
+ MachineState *machine = MACHINE(vms);
+ uint32_t rnd = 1;
+
+ vms->cfg = qdev_new(TYPE_VMAPPLE_CFG);
+ cfg = SYS_BUS_DEVICE(vms->cfg);
+ sysbus_mmio_map(cfg, 0, vms->memmap[VMAPPLE_CONFIG].base);
+
+ qemu_guest_getrandom_nofail(&rnd, sizeof(rnd));
+
+ qdev_prop_set_uint32(vms->cfg, "nr-cpus", machine->smp.cpus);
+ qdev_prop_set_uint64(vms->cfg, "ecid", vms->uuid);
+ qdev_prop_set_uint64(vms->cfg, "ram-size", machine->ram_size);
+ qdev_prop_set_uint32(vms->cfg, "rnd", rnd);
+
+ if (!sysbus_realize_and_unref(cfg, errp)) {
+ error_prepend(errp, "Error creating vmapple cfg device: ");
+ return false;
+ }
+
+ return true;
+}
+
+static void create_gfx(VMAppleMachineState *vms, MemoryRegion *mem)
+{
+ int irq_gfx = vms->irqmap[VMAPPLE_APV_GFX];
+ int irq_iosfc = vms->irqmap[VMAPPLE_APV_IOSFC];
+ SysBusDevice *gfx;
+
+ gfx = SYS_BUS_DEVICE(qdev_new("apple-gfx-mmio"));
+ sysbus_mmio_map(gfx, 0, vms->memmap[VMAPPLE_APV_GFX].base);
+ sysbus_mmio_map(gfx, 1, vms->memmap[VMAPPLE_APV_IOSFC].base);
+ sysbus_connect_irq(gfx, 0, qdev_get_gpio_in(vms->gic, irq_gfx));
+ sysbus_connect_irq(gfx, 1, qdev_get_gpio_in(vms->gic, irq_iosfc));
+ sysbus_realize_and_unref(gfx, &error_fatal);
+}
+
+static void create_aes(VMAppleMachineState *vms, MemoryRegion *mem)
+{
+ int irq = vms->irqmap[VMAPPLE_AES_1];
+ SysBusDevice *aes;
+
+ aes = SYS_BUS_DEVICE(qdev_new(TYPE_APPLE_AES));
+ sysbus_mmio_map(aes, 0, vms->memmap[VMAPPLE_AES_1].base);
+ sysbus_mmio_map(aes, 1, vms->memmap[VMAPPLE_AES_2].base);
+ sysbus_connect_irq(aes, 0, qdev_get_gpio_in(vms->gic, irq));
+ sysbus_realize_and_unref(aes, &error_fatal);
+}
+
+static int arm_gic_ppi_index(int cpu_nr, int ppi_index)
+{
+ return NUM_IRQS + cpu_nr * GIC_INTERNAL + ppi_index;
+}
+
+static void create_gic(VMAppleMachineState *vms, MemoryRegion *mem)
+{
+ MachineState *ms = MACHINE(vms);
+ /* We create a standalone GIC */
+ SysBusDevice *gicbusdev;
+ QList *redist_region_count;
+ int i;
+ unsigned int smp_cpus = ms->smp.cpus;
+
+ vms->gic = qdev_new(gicv3_class_name());
+ qdev_prop_set_uint32(vms->gic, "revision", 3);
+ qdev_prop_set_uint32(vms->gic, "num-cpu", smp_cpus);
+ /*
+ * Note that the num-irq property counts both internal and external
+ * interrupts; there are always 32 of the former (mandated by GIC spec).
+ */
+ qdev_prop_set_uint32(vms->gic, "num-irq", NUM_IRQS + 32);
+
+ uint32_t redist0_capacity =
+ vms->memmap[VMAPPLE_GIC_REDIST].size / GICV3_REDIST_SIZE;
+ uint32_t redist0_count = MIN(smp_cpus, redist0_capacity);
+
+ redist_region_count = qlist_new();
+ qlist_append_int(redist_region_count, redist0_count);
+ qdev_prop_set_array(vms->gic, "redist-region-count", redist_region_count);
+
+ gicbusdev = SYS_BUS_DEVICE(vms->gic);
+ sysbus_realize_and_unref(gicbusdev, &error_fatal);
+ sysbus_mmio_map(gicbusdev, 0, vms->memmap[VMAPPLE_GIC_DIST].base);
+ sysbus_mmio_map(gicbusdev, 1, vms->memmap[VMAPPLE_GIC_REDIST].base);
+
+ /*
+ * Wire the outputs from each CPU's generic timer and the GICv3
+ * maintenance interrupt signal to the appropriate GIC PPI inputs,
+ * and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's inputs.
+ */
+ for (i = 0; i < smp_cpus; i++) {
+ DeviceState *cpudev = DEVICE(qemu_get_cpu(i));
+
+ /* Map the virt timer to PPI 27 */
+ qdev_connect_gpio_out(cpudev, GTIMER_VIRT,
+ qdev_get_gpio_in(vms->gic,
+ arm_gic_ppi_index(i, 27)));
+
+ /* Map the GIC IRQ and FIQ lines to CPU */
+ sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
+ sysbus_connect_irq(gicbusdev, i + smp_cpus,
+ qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
+ }
+}
+
+static void create_uart(const VMAppleMachineState *vms, int uart,
+ MemoryRegion *mem, Chardev *chr)
+{
+ hwaddr base = vms->memmap[uart].base;
+ int irq = vms->irqmap[uart];
+ DeviceState *dev = qdev_new(TYPE_PL011);
+ SysBusDevice *s = SYS_BUS_DEVICE(dev);
+
+ qdev_prop_set_chr(dev, "chardev", chr);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+ memory_region_add_subregion(mem, base,
+ sysbus_mmio_get_region(s, 0));
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(vms->gic, irq));
+}
+
+static void create_rtc(const VMAppleMachineState *vms)
+{
+ hwaddr base = vms->memmap[VMAPPLE_RTC].base;
+ int irq = vms->irqmap[VMAPPLE_RTC];
+
+ sysbus_create_simple("pl031", base, qdev_get_gpio_in(vms->gic, irq));
+}
+
+static DeviceState *gpio_key_dev;
+static void vmapple_powerdown_req(Notifier *n, void *opaque)
+{
+ /* use gpio Pin 3 for power button event */
+ qemu_set_irq(qdev_get_gpio_in(gpio_key_dev, 0), 1);
+}
+
+static void create_gpio_devices(const VMAppleMachineState *vms, int gpio,
+ MemoryRegion *mem)
+{
+ DeviceState *pl061_dev;
+ hwaddr base = vms->memmap[gpio].base;
+ int irq = vms->irqmap[gpio];
+ SysBusDevice *s;
+
+ pl061_dev = qdev_new("pl061");
+ /* Pull lines down to 0 if not driven by the PL061 */
+ qdev_prop_set_uint32(pl061_dev, "pullups", 0);
+ qdev_prop_set_uint32(pl061_dev, "pulldowns", 0xff);
+ s = SYS_BUS_DEVICE(pl061_dev);
+ sysbus_realize_and_unref(s, &error_fatal);
+ memory_region_add_subregion(mem, base, sysbus_mmio_get_region(s, 0));
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(vms->gic, irq));
+ gpio_key_dev = sysbus_create_simple("gpio-key", -1,
+ qdev_get_gpio_in(pl061_dev, 3));
+}
+
+static void vmapple_firmware_init(VMAppleMachineState *vms,
+ MemoryRegion *sysmem)
+{
+ hwaddr size = vms->memmap[VMAPPLE_FIRMWARE].size;
+ hwaddr base = vms->memmap[VMAPPLE_FIRMWARE].base;
+ const char *bios_name;
+ int image_size;
+ char *fname;
+
+ bios_name = MACHINE(vms)->firmware;
+ if (!bios_name) {
+ error_report("No firmware specified");
+ exit(1);
+ }
+
+ fname = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+ if (!fname) {
+ error_report("Could not find ROM image '%s'", bios_name);
+ exit(1);
+ }
+
+ memory_region_init_ram(&vms->fw_mr, NULL, "firmware", size, &error_fatal);
+ image_size = load_image_mr(fname, &vms->fw_mr);
+
+ g_free(fname);
+ if (image_size < 0) {
+ error_report("Could not load ROM image '%s'", bios_name);
+ exit(1);
+ }
+
+ memory_region_add_subregion(get_system_memory(), base, &vms->fw_mr);
+}
+
+static void create_pcie(VMAppleMachineState *vms)
+{
+ hwaddr base_mmio = vms->memmap[VMAPPLE_PCIE_MMIO].base;
+ hwaddr size_mmio = vms->memmap[VMAPPLE_PCIE_MMIO].size;
+ hwaddr base_ecam = vms->memmap[VMAPPLE_PCIE_ECAM].base;
+ hwaddr size_ecam = vms->memmap[VMAPPLE_PCIE_ECAM].size;
+ int irq = vms->irqmap[VMAPPLE_PCIE];
+ MemoryRegion *mmio_alias;
+ MemoryRegion *mmio_reg;
+ MemoryRegion *ecam_reg;
+ DeviceState *dev;
+ int i;
+ PCIHostState *pci;
+ DeviceState *usb_controller;
+ USBBus *usb_bus;
+
+ dev = qdev_new(TYPE_GPEX_HOST);
+ qdev_prop_set_uint32(dev, "num-irqs", GPEX_NUM_IRQS);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+
+ /* Map only the first size_ecam bytes of ECAM space */
+ ecam_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
+ memory_region_init_alias(&vms->ecam_alias, OBJECT(dev), "pcie-ecam",
+ ecam_reg, 0, size_ecam);
+ memory_region_add_subregion(get_system_memory(), base_ecam,
+ &vms->ecam_alias);
+
+ /*
+ * Map the MMIO window from [0x50000000-0x7fff0000] in PCI space into
+ * system address space at [0x50000000-0x7fff0000].
+ */
+ mmio_alias = g_new0(MemoryRegion, 1);
+ mmio_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1);
+ memory_region_init_alias(mmio_alias, OBJECT(dev), "pcie-mmio",
+ mmio_reg, base_mmio, size_mmio);
+ memory_region_add_subregion(get_system_memory(), base_mmio, mmio_alias);
+
+ for (i = 0; i < GPEX_NUM_IRQS; i++) {
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
+ qdev_get_gpio_in(vms->gic, irq + i));
+ gpex_set_irq_num(GPEX_HOST(dev), i, irq + i);
+ }
+
+ pci = PCI_HOST_BRIDGE(dev);
+ vms->bus = pci->bus;
+ g_assert(vms->bus);
+
+ while ((dev = qemu_create_nic_device("virtio-net-pci", true, NULL))) {
+ qdev_realize_and_unref(dev, BUS(vms->bus), &error_fatal);
+ }
+
+ if (defaults_enabled()) {
+ usb_controller = qdev_new(TYPE_QEMU_XHCI);
+ qdev_realize_and_unref(usb_controller, BUS(pci->bus), &error_fatal);
+
+ usb_bus = USB_BUS(object_resolve_type_unambiguous(TYPE_USB_BUS,
+ &error_fatal));
+ usb_create_simple(usb_bus, "usb-kbd");
+ usb_create_simple(usb_bus, "usb-tablet");
+ }
+}
+
+static void vmapple_reset(void *opaque)
+{
+ VMAppleMachineState *vms = opaque;
+ hwaddr base = vms->memmap[VMAPPLE_FIRMWARE].base;
+
+ cpu_set_pc(first_cpu, base);
+}
+
+static void mach_vmapple_init(MachineState *machine)
+{
+ VMAppleMachineState *vms = VMAPPLE_MACHINE(machine);
+ MachineClass *mc = MACHINE_GET_CLASS(machine);
+ const CPUArchIdList *possible_cpus;
+ MemoryRegion *sysmem = get_system_memory();
+ int n;
+ unsigned int smp_cpus = machine->smp.cpus;
+ unsigned int max_cpus = machine->smp.max_cpus;
+
+ vms->memmap = memmap;
+ machine->usb = true;
+
+ possible_cpus = mc->possible_cpu_arch_ids(machine);
+ assert(possible_cpus->len == max_cpus);
+ for (n = 0; n < possible_cpus->len; n++) {
+ Object *cpu;
+ CPUState *cs;
+
+ if (n >= smp_cpus) {
+ break;
+ }
+
+ cpu = object_new(possible_cpus->cpus[n].type);
+ object_property_set_int(cpu, "mp-affinity",
+ possible_cpus->cpus[n].arch_id, &error_fatal);
+
+ cs = CPU(cpu);
+ cs->cpu_index = n;
+
+ numa_cpu_pre_plug(&possible_cpus->cpus[cs->cpu_index], DEVICE(cpu),
+ &error_fatal);
+
+ if (object_property_find(cpu, "has_el3")) {
+ object_property_set_bool(cpu, "has_el3", false, &error_fatal);
+ }
+ if (object_property_find(cpu, "has_el2")) {
+ object_property_set_bool(cpu, "has_el2", false, &error_fatal);
+ }
+ object_property_set_int(cpu, "psci-conduit", QEMU_PSCI_CONDUIT_HVC,
+ &error_fatal);
+
+ /* Secondary CPUs start in PSCI powered-down state */
+ if (n > 0) {
+ object_property_set_bool(cpu, "start-powered-off", true,
+ &error_fatal);
+ }
+
+ object_property_set_link(cpu, "memory", OBJECT(sysmem), &error_abort);
+ qdev_realize(DEVICE(cpu), NULL, &error_fatal);
+ object_unref(cpu);
+ }
+
+ memory_region_add_subregion(sysmem, vms->memmap[VMAPPLE_MEM].base,
+ machine->ram);
+
+ create_gic(vms, sysmem);
+ create_bdif(vms, sysmem);
+ create_pvpanic(vms, sysmem);
+ create_aes(vms, sysmem);
+ create_gfx(vms, sysmem);
+ create_uart(vms, VMAPPLE_UART, sysmem, serial_hd(0));
+ create_rtc(vms);
+ create_pcie(vms);
+
+ create_gpio_devices(vms, VMAPPLE_GPIO, sysmem);
+
+ vmapple_firmware_init(vms, sysmem);
+ create_cfg(vms, sysmem, &error_fatal);
+
+ /* connect powerdown request */
+ vms->powerdown_notifier.notify = vmapple_powerdown_req;
+ qemu_register_powerdown_notifier(&vms->powerdown_notifier);
+
+ vms->bootinfo.ram_size = machine->ram_size;
+ vms->bootinfo.board_id = -1;
+ vms->bootinfo.loader_start = vms->memmap[VMAPPLE_MEM].base;
+ vms->bootinfo.skip_dtb_autoload = true;
+ vms->bootinfo.firmware_loaded = true;
+ arm_load_kernel(ARM_CPU(first_cpu), machine, &vms->bootinfo);
+
+ qemu_register_reset(vmapple_reset, vms);
+}
+
+static CpuInstanceProperties
+vmapple_cpu_index_to_props(MachineState *ms, unsigned cpu_index)
+{
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
+ const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms);
+
+ assert(cpu_index < possible_cpus->len);
+ return possible_cpus->cpus[cpu_index].props;
+}
+
+
+static int64_t vmapple_get_default_cpu_node_id(const MachineState *ms, int idx)
+{
+ return idx % ms->numa_state->num_nodes;
+}
+
+static const CPUArchIdList *vmapple_possible_cpu_arch_ids(MachineState *ms)
+{
+ int n;
+ unsigned int max_cpus = ms->smp.max_cpus;
+
+ if (ms->possible_cpus) {
+ assert(ms->possible_cpus->len == max_cpus);
+ return ms->possible_cpus;
+ }
+
+ ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) +
+ sizeof(CPUArchId) * max_cpus);
+ ms->possible_cpus->len = max_cpus;
+ for (n = 0; n < ms->possible_cpus->len; n++) {
+ ms->possible_cpus->cpus[n].type = ms->cpu_type;
+ ms->possible_cpus->cpus[n].arch_id =
+ arm_build_mp_affinity(n, GICV3_TARGETLIST_BITS);
+ ms->possible_cpus->cpus[n].props.has_thread_id = true;
+ ms->possible_cpus->cpus[n].props.thread_id = n;
+ }
+ return ms->possible_cpus;
+}
+
+static GlobalProperty vmapple_compat_defaults[] = {
+ { TYPE_VIRTIO_PCI, "disable-legacy", "on" },
+ /*
+ * macOS XHCI driver attempts to schedule events onto even rings 1 & 2
+ * even when (as here) there is no MSI(-X) support. Disabling interrupter
+ * mapping in the XHCI controller works around the problem.
+ */
+ { TYPE_XHCI_PCI, "conditional-intr-mapping", "on" },
+};
+
+static void vmapple_machine_class_init(ObjectClass *oc, void *data)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
+ mc->init = mach_vmapple_init;
+ mc->max_cpus = 32;
+ mc->block_default_type = IF_VIRTIO;
+ mc->no_cdrom = 1;
+ mc->pci_allow_0_address = true;
+ mc->minimum_page_bits = 12;
+ mc->possible_cpu_arch_ids = vmapple_possible_cpu_arch_ids;
+ mc->cpu_index_to_instance_props = vmapple_cpu_index_to_props;
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("host");
+ mc->get_default_cpu_node_id = vmapple_get_default_cpu_node_id;
+ mc->default_ram_id = "mach-vmapple.ram";
+ mc->desc = "Apple aarch64 Virtual Machine";
+
+ compat_props_add(mc->compat_props, vmapple_compat_defaults,
+ G_N_ELEMENTS(vmapple_compat_defaults));
+}
+
+static void vmapple_instance_init(Object *obj)
+{
+ VMAppleMachineState *vms = VMAPPLE_MACHINE(obj);
+
+ vms->irqmap = irqmap;
+
+ object_property_add_uint64_ptr(obj, "uuid", &vms->uuid,
+ OBJ_PROP_FLAG_READWRITE);
+ object_property_set_description(obj, "uuid", "Machine UUID (SDOM)");
+}
+
+static const TypeInfo vmapple_machine_info = {
+ .name = TYPE_VMAPPLE_MACHINE,
+ .parent = TYPE_MACHINE,
+ .instance_size = sizeof(VMAppleMachineState),
+ .class_init = vmapple_machine_class_init,
+ .instance_init = vmapple_instance_init,
+};
+
+static void machvmapple_machine_init(void)
+{
+ type_register_static(&vmapple_machine_info);
+}
+type_init(machvmapple_machine_init);
+
diff --git a/contrib/vmapple/uuid.sh b/contrib/vmapple/uuid.sh
new file mode 100755
index 00000000000..f5637221d23
--- /dev/null
+++ b/contrib/vmapple/uuid.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+#
+# Used for converting a guest provisioned using Virtualization.framework
+# for use with the QEMU 'vmapple' aarch64 machine type.
+#
+# Extracts the Machine UUID from Virtualization.framework VM JSON file.
+# (as produced by 'macosvm', passed as command line argument)
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+plutil -extract machineId raw "$1" | base64 -d | plutil -extract ECID raw -
+
diff --git a/hw/vmapple/Kconfig b/hw/vmapple/Kconfig
index 5586fd460b7..2382b297672 100644
--- a/hw/vmapple/Kconfig
+++ b/hw/vmapple/Kconfig
@@ -11,3 +11,24 @@ config VMAPPLE_CFG
config VMAPPLE_VIRTIO_BLK
bool
+
+config VMAPPLE
+ bool
+ depends on ARM
+ depends on HVF
+ default y if ARM
+ imply PCI_DEVICES
+ select ARM_GICV3
+ select PLATFORM_BUS
+ select PCI_EXPRESS
+ select PCI_EXPRESS_GENERIC_BRIDGE
+ select PL011 # UART
+ select PL031 # RTC
+ select PL061 # GPIO
+ select GPIO_PWR
+ select PVPANIC_MMIO
+ select VMAPPLE_AES
+ select VMAPPLE_BDIF
+ select VMAPPLE_CFG
+ select MAC_PVG_MMIO
+ select VMAPPLE_VIRTIO_BLK
diff --git a/hw/vmapple/meson.build b/hw/vmapple/meson.build
index 3553ec61518..23bc4c999e3 100644
--- a/hw/vmapple/meson.build
+++ b/hw/vmapple/meson.build
@@ -4,3 +4,4 @@ system_ss.add(when: 'CONFIG_VMAPPLE_AES', if_true: files('aes.c'))
system_ss.add(when: 'CONFIG_VMAPPLE_BDIF', if_true: files('bdif.c'))
system_ss.add(when: 'CONFIG_VMAPPLE_CFG', if_true: files('cfg.c'))
system_ss.add(when: 'CONFIG_VMAPPLE_VIRTIO_BLK', if_true: files('virtio-blk.c'))
+specific_ss.add(when: 'CONFIG_VMAPPLE', if_true: files('vmapple.c'))
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* Re: [PULL 09/41] hw/vmapple/vmapple: Add vmapple machine type
2025-03-05 1:21 ` [PULL 09/41] hw/vmapple/vmapple: Add vmapple machine type Philippe Mathieu-Daudé
@ 2025-03-10 1:22 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-10 1:22 UTC (permalink / raw)
To: qemu-devel, qemu-arm, Thomas Huth, Fabiano Rosas
Cc: Alexander Graf, Phil Dennis-Jordan, Akihiko Odaki
On 5/3/25 02:21, Philippe Mathieu-Daudé wrote:
> From: Alexander Graf <graf@amazon.com>
>
> Apple defines a new "vmapple" machine type as part of its proprietary
> macOS Virtualization.Framework vmm. This machine type is similar to the
> virt one, but with subtle differences in base devices, a few special
> vmapple device additions and a vastly different boot chain.
>
> This patch reimplements this machine type in QEMU. To use it, you
> have to have a readily installed version of macOS for VMApple,
> run on macOS with -accel hvf, pass the Virtualization.Framework
> boot rom (AVPBooter) in via -bios, pass the aux and root volume as pflash
> and pass aux and root volume as virtio drives. In addition, you also
> need to find the machine UUID and pass that as -M vmapple,uuid= parameter:
>
> $ qemu-system-aarch64 -accel hvf -M vmapple,uuid=0x1234 -m 4G \
> -bios /System/Library/Frameworks/Virtualization.framework/Versions/A/Resources/AVPBooter.vmapple2.bin
> -drive file=aux,if=pflash,format=raw \
> -drive file=root,if=pflash,format=raw \
> -drive file=aux,if=none,id=aux,format=raw \
> -device vmapple-virtio-blk-pci,variant=aux,drive=aux \
> -drive file=root,if=none,id=root,format=raw \
> -device vmapple-virtio-blk-pci,variant=root,drive=root
>
> With all these in place, you should be able to see macOS booting
> successfully.
>
> Known issues:
> - Currently only macOS 12 guests are supported. The boot process for
> 13+ will need further investigation and adjustment.
>
> Signed-off-by: Alexander Graf <graf@amazon.com>
> Co-authored-by: Phil Dennis-Jordan <phil@philjordan.eu>
> Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
> Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
> Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
> Message-ID: <20241223221645.29911-15-phil@philjordan.eu>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---
> MAINTAINERS | 1 +
> docs/system/arm/vmapple.rst | 65 ++++
> docs/system/target-arm.rst | 1 +
> hw/vmapple/vmapple.c | 618 ++++++++++++++++++++++++++++++++++++
> contrib/vmapple/uuid.sh | 12 +
> hw/vmapple/Kconfig | 21 ++
> hw/vmapple/meson.build | 1 +
> 7 files changed, 719 insertions(+)
> create mode 100644 docs/system/arm/vmapple.rst
> create mode 100644 hw/vmapple/vmapple.c
> create mode 100755 contrib/vmapple/uuid.sh
> +static void vmapple_machine_class_init(ObjectClass *oc, void *data)
> +{
> + MachineClass *mc = MACHINE_CLASS(oc);
> +
> + mc->init = mach_vmapple_init;
> + mc->max_cpus = 32;
> + mc->block_default_type = IF_VIRTIO;
> + mc->no_cdrom = 1;
> + mc->pci_allow_0_address = true;
> + mc->minimum_page_bits = 12;
> + mc->possible_cpu_arch_ids = vmapple_possible_cpu_arch_ids;
> + mc->cpu_index_to_instance_props = vmapple_cpu_index_to_props;
> + mc->default_cpu_type = ARM_CPU_TYPE_NAME("host");
Not sure how I missed that earlier, but I'm now getting:
$ make check-qtest-aarch64
qemu-system-aarch64: The 'host' CPU type can only be used with KVM or HVF
> + mc->get_default_cpu_node_id = vmapple_get_default_cpu_node_id;
> + mc->default_ram_id = "mach-vmapple.ram";
> + mc->desc = "Apple aarch64 Virtual Machine";
> +
> + compat_props_add(mc->compat_props, vmapple_compat_defaults,
> + G_N_ELEMENTS(vmapple_compat_defaults));
> +}
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PULL 10/41] hw/ppc/spapr: Restrict part of PAGE_INIT hypercall to TCG
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (8 preceding siblings ...)
2025-03-05 1:21 ` [PULL 09/41] hw/vmapple/vmapple: Add vmapple machine type Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 11/41] hw/acpi/ghes: Make ghes_record_cper_errors() static Philippe Mathieu-Daudé
` (30 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Harsh Prateek Bora
Restrict the tb_flush() call to TCG. Assert we are using KVM or TCG.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Message-Id: <20250127102620.39159-3-philmd@linaro.org>
---
hw/ppc/spapr_hcall.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index f8ab7670630..f987ff323f8 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -299,8 +299,10 @@ static target_ulong h_page_init(PowerPCCPU *cpu, SpaprMachineState *spapr,
if (flags & (H_ICACHE_SYNCHRONIZE | H_ICACHE_INVALIDATE)) {
if (kvm_enabled()) {
kvmppc_icbi_range(cpu, pdst, len);
- } else {
+ } else if (tcg_enabled()) {
tb_flush(CPU(cpu));
+ } else {
+ g_assert_not_reached();
}
}
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 11/41] hw/acpi/ghes: Make ghes_record_cper_errors() static
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (9 preceding siblings ...)
2025-03-05 1:21 ` [PULL 10/41] hw/ppc/spapr: Restrict part of PAGE_INIT hypercall to TCG Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-06 22:36 ` Mauro Carvalho Chehab
2025-03-05 1:21 ` [PULL 12/41] hw/arm: Do not expose the virt machine on Xen-only binary Philippe Mathieu-Daudé
` (29 subsequent siblings)
40 siblings, 1 reply; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: Gavin Shan, Philippe Mathieu-Daudé
From: Gavin Shan <gshan@redhat.com>
acpi_ghes_memory_errors() is the only caller, no need to expose
the function. Besides, the last 'return' in this function isn't
necessary and remove it.
No functional changes intended.
Signed-off-by: Gavin Shan <gshan@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20250214041635.608012-2-gshan@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
include/hw/acpi/ghes.h | 2 --
hw/acpi/ghes.c | 6 ++----
2 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/include/hw/acpi/ghes.h b/include/hw/acpi/ghes.h
index 39619a2457c..578a582203c 100644
--- a/include/hw/acpi/ghes.h
+++ b/include/hw/acpi/ghes.h
@@ -75,8 +75,6 @@ void acpi_build_hest(GArray *table_data, GArray *hardware_errors,
void acpi_ghes_add_fw_cfg(AcpiGhesState *vms, FWCfgState *s,
GArray *hardware_errors);
int acpi_ghes_memory_errors(uint16_t source_id, uint64_t error_physical_addr);
-void ghes_record_cper_errors(const void *cper, size_t len,
- uint16_t source_id, Error **errp);
/**
* acpi_ghes_present: Report whether ACPI GHES table is present
diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c
index b709c177cde..b85bb48195a 100644
--- a/hw/acpi/ghes.c
+++ b/hw/acpi/ghes.c
@@ -390,8 +390,8 @@ static void get_hw_error_offsets(uint64_t ghes_addr,
*read_ack_register_addr = ghes_addr + sizeof(uint64_t);
}
-void ghes_record_cper_errors(const void *cper, size_t len,
- uint16_t source_id, Error **errp)
+static void ghes_record_cper_errors(const void *cper, size_t len,
+ uint16_t source_id, Error **errp)
{
uint64_t cper_addr = 0, read_ack_register_addr = 0, read_ack_register;
AcpiGedState *acpi_ged_state;
@@ -440,8 +440,6 @@ void ghes_record_cper_errors(const void *cper, size_t len,
/* Write the generic error data entry into guest memory */
cpu_physical_memory_write(cper_addr, cper, len);
-
- return;
}
int acpi_ghes_memory_errors(uint16_t source_id, uint64_t physical_address)
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* Re: [PULL 11/41] hw/acpi/ghes: Make ghes_record_cper_errors() static
2025-03-05 1:21 ` [PULL 11/41] hw/acpi/ghes: Make ghes_record_cper_errors() static Philippe Mathieu-Daudé
@ 2025-03-06 22:36 ` Mauro Carvalho Chehab
2025-03-07 12:41 ` Philippe Mathieu-Daudé
0 siblings, 1 reply; 45+ messages in thread
From: Mauro Carvalho Chehab @ 2025-03-06 22:36 UTC (permalink / raw)
To: Philippe Mathieu-Daudé
Cc: qemu-devel, Gavin Shan, Michael S. Tsirkin, Igor Mammedov
Em Wed, 5 Mar 2025 02:21:26 +0100
Philippe Mathieu-Daudé <philmd@linaro.org> escreveu:
> From: Gavin Shan <gshan@redhat.com>
>
> acpi_ghes_memory_errors() is the only caller, no need to expose
> the function. Besides, the last 'return' in this function isn't
> necessary and remove it.
>
> No functional changes intended.
Please revert this patch, as ghes_record_cper_errors() was written
to be used for error injection. As agreed last year with some ACPI
maintainers, we ended splitting the error injection series on two parts
to make easier for people to review it.
The followup series:
https://lore.kernel.org/qemu-devel/cover.1740903110.git.mchehab+huawei@kernel.org/
Need this function to be not static, as this will be used by a
QMP caller.
The usage itself is on this patch:
https://lore.kernel.org/qemu-devel/6ef8d6a3f42e3347ed6fd3d1fc29ab5ff2a070df.1740903110.git.mchehab+huawei@kernel.org/
but this one causes conflict since patch 01 of the series.
Regards,
Mauro
>
> Signed-off-by: Gavin Shan <gshan@redhat.com>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Message-ID: <20250214041635.608012-2-gshan@redhat.com>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---
> include/hw/acpi/ghes.h | 2 --
> hw/acpi/ghes.c | 6 ++----
> 2 files changed, 2 insertions(+), 6 deletions(-)
>
> diff --git a/include/hw/acpi/ghes.h b/include/hw/acpi/ghes.h
> index 39619a2457c..578a582203c 100644
> --- a/include/hw/acpi/ghes.h
> +++ b/include/hw/acpi/ghes.h
> @@ -75,8 +75,6 @@ void acpi_build_hest(GArray *table_data, GArray *hardware_errors,
> void acpi_ghes_add_fw_cfg(AcpiGhesState *vms, FWCfgState *s,
> GArray *hardware_errors);
> int acpi_ghes_memory_errors(uint16_t source_id, uint64_t error_physical_addr);
> -void ghes_record_cper_errors(const void *cper, size_t len,
> - uint16_t source_id, Error **errp);
>
> /**
> * acpi_ghes_present: Report whether ACPI GHES table is present
> diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c
> index b709c177cde..b85bb48195a 100644
> --- a/hw/acpi/ghes.c
> +++ b/hw/acpi/ghes.c
> @@ -390,8 +390,8 @@ static void get_hw_error_offsets(uint64_t ghes_addr,
> *read_ack_register_addr = ghes_addr + sizeof(uint64_t);
> }
>
> -void ghes_record_cper_errors(const void *cper, size_t len,
> - uint16_t source_id, Error **errp)
> +static void ghes_record_cper_errors(const void *cper, size_t len,
> + uint16_t source_id, Error **errp)
> {
> uint64_t cper_addr = 0, read_ack_register_addr = 0, read_ack_register;
> AcpiGedState *acpi_ged_state;
> @@ -440,8 +440,6 @@ void ghes_record_cper_errors(const void *cper, size_t len,
>
> /* Write the generic error data entry into guest memory */
> cpu_physical_memory_write(cper_addr, cper, len);
> -
> - return;
> }
>
> int acpi_ghes_memory_errors(uint16_t source_id, uint64_t physical_address)
Thanks,
Mauro
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PULL 11/41] hw/acpi/ghes: Make ghes_record_cper_errors() static
2025-03-06 22:36 ` Mauro Carvalho Chehab
@ 2025-03-07 12:41 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-07 12:41 UTC (permalink / raw)
To: Mauro Carvalho Chehab
Cc: qemu-devel, Gavin Shan, Michael S. Tsirkin, Igor Mammedov
Hi Mauro,
On 6/3/25 23:36, Mauro Carvalho Chehab wrote:
> Em Wed, 5 Mar 2025 02:21:26 +0100
> Philippe Mathieu-Daudé <philmd@linaro.org> escreveu:
>
>> From: Gavin Shan <gshan@redhat.com>
>>
>> acpi_ghes_memory_errors() is the only caller, no need to expose
>> the function. Besides, the last 'return' in this function isn't
>> necessary and remove it.
>>
>> No functional changes intended.
>
> Please revert this patch, as ghes_record_cper_errors() was written
> to be used for error injection. As agreed last year with some ACPI
> maintainers, we ended splitting the error injection series on two parts
> to make easier for people to review it.
>
> The followup series:
>
> https://lore.kernel.org/qemu-devel/cover.1740903110.git.mchehab+huawei@kernel.org/
>
> Need this function to be not static, as this will be used by a
> QMP caller.
>
> The usage itself is on this patch:
>
> https://lore.kernel.org/qemu-devel/6ef8d6a3f42e3347ed6fd3d1fc29ab5ff2a070df.1740903110.git.mchehab+huawei@kernel.org/
>
> but this one causes conflict since patch 01 of the series.
As of this commit this method isn't used elsewhere in the tree,
so the reversion has to happen in the series using it, if it
eventually lands. Otherwise it is too costly to maintain
incomplete features.
Regards,
Phil.
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PULL 12/41] hw/arm: Do not expose the virt machine on Xen-only binary
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (10 preceding siblings ...)
2025-03-05 1:21 ` [PULL 11/41] hw/acpi/ghes: Make ghes_record_cper_errors() static Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 13/41] hw/xen: Link XenPVH with GPEX PCIe bridge Philippe Mathieu-Daudé
` (28 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Edgar E. Iglesias
Since the Virt machine is useless under Xen, do not even
try to build it there.
A Xen-only binary now only offers the XenPVH machine:
$ qemu-system-aarch64 -M help
Supported machines are:
none empty machine
xenpvh Xen PVH ARM machine
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
Message-Id: <20250218162618.46167-3-philmd@linaro.org>
---
hw/arm/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index faa00d1db3b..15200a2d7e7 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -2,6 +2,7 @@ config ARM_VIRT
bool
default y
depends on ARM
+ depends on TCG || KVM || HVF
imply PCI_DEVICES
imply TEST_DEVICES
imply VFIO_AMD_XGBE
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 13/41] hw/xen: Link XenPVH with GPEX PCIe bridge
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (11 preceding siblings ...)
2025-03-05 1:21 ` [PULL 12/41] hw/arm: Do not expose the virt machine on Xen-only binary Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 14/41] hw/xen/xen-pvh: Reduce included headers Philippe Mathieu-Daudé
` (27 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Edgar E. Iglesias
XenPVH requires the PCIe/GPEX device. Add it to Kconfig
to avoid when configuring using --without-default-devices:
/usr/bin/ld: libqemu-aarch64-softmmu.a.p/hw_xen_xen-pvh-common.c.o: in function `xenpvh_gpex_init':
hw/xen/xen-pvh-common.c:174: undefined reference to `gpex_set_irq_num'
/usr/bin/ld: libqemu-aarch64-softmmu.a.p/hw_xen_xen-hvm-common.c.o: in function `pci_dev_bus_num':
include/hw/pci/pci.h:337: undefined reference to `pci_bus_num'
/usr/bin/ld: include/hw/pci/pci.h:337: undefined reference to `pci_bus_num'
/usr/bin/ld: include/hw/pci/pci.h:337: undefined reference to `pci_bus_num'
/usr/bin/ld: include/hw/pci/pci.h:337: undefined reference to `pci_bus_num'
/usr/bin/ld: include/hw/pci/pci.h:337: undefined reference to `pci_bus_num'
/usr/bin/ld: libqemu-aarch64-softmmu.a.p/hw_xen_xen-hvm-common.c.o: in function `cpu_ioreq_config':
hw/xen/xen-hvm-common.c:412: undefined reference to `pci_host_config_read_common'
/usr/bin/ld: hw/xen/xen-hvm-common.c:428: undefined reference to `pci_host_config_read_common'
/usr/bin/ld: hw/xen/xen-hvm-common.c:438: undefined reference to `pci_host_config_write_common'
Fixes: f22e598a72c ("hw/xen: pvh-common: Add support for creating PCIe/GPEX")
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
Message-Id: <20250218162618.46167-2-philmd@linaro.org>
---
accel/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/accel/Kconfig b/accel/Kconfig
index 794e0d18d21..4263cab7227 100644
--- a/accel/Kconfig
+++ b/accel/Kconfig
@@ -16,4 +16,5 @@ config KVM
config XEN
bool
select FSDEV_9P if VIRTFS
+ select PCI_EXPRESS_GENERIC_BRIDGE
select XEN_BUS
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 14/41] hw/xen/xen-pvh: Reduce included headers
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (12 preceding siblings ...)
2025-03-05 1:21 ` [PULL 13/41] hw/xen: Link XenPVH with GPEX PCIe bridge Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 15/41] hw/xen/xen-hvm: " Philippe Mathieu-Daudé
` (26 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Edgar E. Iglesias
Have "hw/xen/xen-pvh-common.h" include the bare minimal set
of headers. Adapt sources to avoid errors when refactoring
unrelated headers such:
hw/i386/xen/xen-pvh.c: In function ‘xen_pvh_machine_class_init’:
hw/i386/xen/xen-pvh.c:84:28: error: ‘TARGET_DEFAULT_CPU_TYPE’ undeclared (first use in this function)
84 | mc->default_cpu_type = TARGET_DEFAULT_CPU_TYPE;
| ^~~~~~~~~~~~~~~~~~~~~~~
hw/xen/xen-pvh-common.c: In function ‘xen_pvh_init’:
hw/xen/xen-pvh-common.c:217:43: error: ‘MiB’ undeclared (first use in this function)
217 | if (s->cfg.pci_ecam.size != 256 * MiB) {
| ^~~
hw/xen/xen-hvm-common.c:18:6: error: no previous prototype for ‘xen_mr_is_memory’ [-Werror=missing-prototypes]
18 | bool xen_mr_is_memory(MemoryRegion *mr)
| ^~~~~~~~~~~~~~~~
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
Message-Id: <20250218162618.46167-5-philmd@linaro.org>
---
include/hw/xen/xen-pvh-common.h | 8 ++++----
hw/i386/xen/xen-pvh.c | 1 +
hw/xen/xen-pvh-common.c | 5 ++---
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/include/hw/xen/xen-pvh-common.h b/include/hw/xen/xen-pvh-common.h
index 5cdd23c2f4d..17c5a58a5a4 100644
--- a/include/hw/xen/xen-pvh-common.h
+++ b/include/hw/xen/xen-pvh-common.h
@@ -9,11 +9,11 @@
#ifndef XEN_PVH_COMMON_H__
#define XEN_PVH_COMMON_H__
-#include <assert.h>
-#include "hw/sysbus.h"
-#include "hw/hw.h"
-#include "hw/xen/xen-hvm-common.h"
+#include "exec/memory.h"
+#include "qom/object.h"
+#include "hw/boards.h"
#include "hw/pci-host/gpex.h"
+#include "hw/xen/xen-hvm-common.h"
#define TYPE_XEN_PVH_MACHINE MACHINE_TYPE_NAME("xen-pvh-base")
OBJECT_DECLARE_TYPE(XenPVHMachineState, XenPVHMachineClass,
diff --git a/hw/i386/xen/xen-pvh.c b/hw/i386/xen/xen-pvh.c
index 33c10279763..f6356f2a7ed 100644
--- a/hw/i386/xen/xen-pvh.c
+++ b/hw/i386/xen/xen-pvh.c
@@ -14,6 +14,7 @@
#include "hw/xen/arch_hvm.h"
#include <xen/hvm/hvm_info_table.h>
#include "hw/xen/xen-pvh-common.h"
+#include "target/i386/cpu.h"
#define TYPE_XEN_PVH_X86 MACHINE_TYPE_NAME("xenpvh")
OBJECT_DECLARE_SIMPLE_TYPE(XenPVHx86State, XEN_PVH_X86)
diff --git a/hw/xen/xen-pvh-common.c b/hw/xen/xen-pvh-common.c
index 9c21fa858d3..d675f7a8aeb 100644
--- a/hw/xen/xen-pvh-common.c
+++ b/hw/xen/xen-pvh-common.c
@@ -8,14 +8,13 @@
#include "qemu/osdep.h"
#include "qemu/error-report.h"
-#include "qapi/error.h"
+#include "qemu/units.h"
#include "qapi/visitor.h"
#include "hw/boards.h"
#include "hw/irq.h"
-#include "hw/sysbus.h"
-#include "system/system.h"
#include "system/tpm.h"
#include "system/tpm_backend.h"
+#include "system/runstate.h"
#include "hw/xen/xen-pvh-common.h"
#include "trace.h"
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 15/41] hw/xen/xen-hvm: Reduce included headers
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (13 preceding siblings ...)
2025-03-05 1:21 ` [PULL 14/41] hw/xen/xen-pvh: Reduce included headers Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 16/41] hw/xen/xen-bus: " Philippe Mathieu-Daudé
` (25 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Anthony PERARD
Have "hw/xen/xen-hvm-common.h" include the bare minimal set
of headers. Adapt sources to avoid errors when refactoring
unrelated headers such:
include/hw/xen/xen-hvm-common.h:71:5: error: unknown type name ‘xenevtchn_handle’
71 | xenevtchn_handle *xce_handle;
| ^~~~~~~~~~~~~~~~
hw/xen/xen-hvm-common.c: In function ‘cpu_get_ioreq’:
hw/xen/xen-hvm-common.c:227:13: error: implicit declaration of function ‘hw_error’
227 | hw_error("Fatal error while trying to get io event!\n");
| ^~~~~~~~
| herror
hw/xen/xen-hvm-common.c: In function ‘handle_ioreq’:
hw/xen/xen-hvm-common.c:446:34: error: ‘target_ulong’ undeclared (first use in this function)
446 | (req->size < sizeof (target_ulong))) {
| ^~~~~~~~~~~~
hw/i386/xen/xen-hvm.c: In function ‘xen_add_to_physmap’:
hw/i386/xen/xen-hvm.c:298:22: error: implicit declaration of function ‘xen_replace_cache_entry’
298 | uint8_t *p = xen_replace_cache_entry(phys_offset, start_addr, size);
| ^~~~~~~~~~~~~~~~~~~~~~~
hw/i386/xen/xen-hvm.c:314:9: error: implicit declaration of function 'error_report' is invalid in C99
314 | error_report("relocate_memory %lu pages from GFN %"HWADDR_PRIx
^~~~~~~~~~~~
hw/i386/xen/xen-hvm.c: In function ‘xen_log_global_start’:
hw/i386/xen/xen-hvm.c:465:9: error: implicit declaration of function ‘xen_enabled’
465 | if (xen_enabled()) {
| ^~~~~~~~~~~
hw/i386/xen/xen-hvm.c: In function ‘regs_to_cpu’:
hw/i386/xen/xen-hvm.c:487:5: error: unknown type name ‘X86CPU’
487 | X86CPU *cpu;
| ^~~~~~
hw/i386/xen/xen-hvm.c:492:15: error: ‘R_EAX’ undeclared (first use in this function)
492 | env->regs[R_EAX] = req->data;
| ^~~~~
| REG_RAX
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Anthony PERARD <anthony.perard@vates.tech>
Message-Id: <20250218162618.46167-6-philmd@linaro.org>
---
include/hw/xen/xen-hvm-common.h | 14 +++-----------
hw/arm/xen-stubs.c | 5 ++---
hw/i386/xen/xen-hvm.c | 6 ++++++
hw/xen/xen-hvm-common.c | 7 +++++++
4 files changed, 18 insertions(+), 14 deletions(-)
diff --git a/include/hw/xen/xen-hvm-common.h b/include/hw/xen/xen-hvm-common.h
index c1ea2c0d787..19df5600a39 100644
--- a/include/hw/xen/xen-hvm-common.h
+++ b/include/hw/xen/xen-hvm-common.h
@@ -1,18 +1,10 @@
#ifndef HW_XEN_HVM_COMMON_H
#define HW_XEN_HVM_COMMON_H
-#include "qemu/units.h"
-
-#include "cpu.h"
-#include "hw/pci/pci.h"
-#include "hw/hw.h"
+#include "qemu/queue.h"
+#include "exec/hwaddr.h"
#include "hw/xen/xen_native.h"
-#include "hw/xen/xen-legacy-backend.h"
-#include "system/runstate.h"
-#include "system/system.h"
-#include "system/xen.h"
-#include "system/xen-mapcache.h"
-#include "qemu/error-report.h"
+#include "hw/xen/xen_backend_ops.h"
#include <xen/hvm/ioreq.h>
extern MemoryRegion xen_memory;
diff --git a/hw/arm/xen-stubs.c b/hw/arm/xen-stubs.c
index 34beb8b08cb..5551584dc20 100644
--- a/hw/arm/xen-stubs.c
+++ b/hw/arm/xen-stubs.c
@@ -5,10 +5,9 @@
*/
#include "qemu/osdep.h"
-#include "qemu/error-report.h"
#include "qapi/qapi-commands-migration.h"
-#include "hw/boards.h"
-#include "system/system.h"
+#include "system/xen.h"
+#include "hw/hw.h"
#include "hw/xen/xen-hvm-common.h"
#include "hw/xen/arch_hvm.h"
diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
index d3df488c483..d4516acec69 100644
--- a/hw/i386/xen/xen-hvm.c
+++ b/hw/i386/xen/xen-hvm.c
@@ -10,10 +10,12 @@
#include "qemu/osdep.h"
#include "qemu/units.h"
+#include "qemu/error-report.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-migration.h"
#include "trace.h"
+#include "hw/hw.h"
#include "hw/i386/pc.h"
#include "hw/irq.h"
#include "hw/i386/apic-msidef.h"
@@ -24,6 +26,10 @@
#include "hw/xen/arch_hvm.h"
#include <xen/hvm/e820.h>
#include "exec/target_page.h"
+#include "target/i386/cpu.h"
+#include "system/runstate.h"
+#include "system/xen-mapcache.h"
+#include "system/xen.h"
static MemoryRegion ram_640k, ram_lo, ram_hi;
static MemoryRegion *framebuffer;
diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c
index 7ffbbfea23b..9a677e8ed74 100644
--- a/hw/xen/xen-hvm-common.c
+++ b/hw/xen/xen-hvm-common.c
@@ -1,14 +1,21 @@
#include "qemu/osdep.h"
#include "qemu/units.h"
+#include "qemu/error-report.h"
#include "qapi/error.h"
+#include "exec/target_long.h"
#include "exec/target_page.h"
#include "trace.h"
+#include "hw/hw.h"
#include "hw/pci/pci_host.h"
#include "hw/xen/xen-hvm-common.h"
#include "hw/xen/xen-bus.h"
#include "hw/boards.h"
#include "hw/xen/arch_hvm.h"
+#include "system/runstate.h"
+#include "system/system.h"
+#include "system/xen.h"
+#include "system/xen-mapcache.h"
MemoryRegion xen_memory, xen_grants;
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 16/41] hw/xen/xen-bus: Reduce included headers
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (14 preceding siblings ...)
2025-03-05 1:21 ` [PULL 15/41] hw/xen/xen-hvm: " Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 17/41] hw/xen/xen-legacy-backend: Remove unused 'net/net.h' header Philippe Mathieu-Daudé
` (24 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Anthony PERARD
Have "hw/xen/xen-bus" include the bare minimal set of headers.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Anthony PERARD <anthony.perard@vates.tech>
Message-Id: <20250218162618.46167-7-philmd@linaro.org>
---
include/hw/xen/xen-bus.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h
index 2adb2af8391..bdbf1ed6fd0 100644
--- a/include/hw/xen/xen-bus.h
+++ b/include/hw/xen/xen-bus.h
@@ -8,9 +8,10 @@
#ifndef HW_XEN_BUS_H
#define HW_XEN_BUS_H
+#include "hw/qdev-core.h"
#include "hw/xen/xen_backend_ops.h"
-#include "hw/sysbus.h"
#include "qemu/notify.h"
+#include "qemu/queue.h"
#include "qom/object.h"
typedef struct XenEventChannel XenEventChannel;
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 17/41] hw/xen/xen-legacy-backend: Remove unused 'net/net.h' header
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (15 preceding siblings ...)
2025-03-05 1:21 ` [PULL 16/41] hw/xen/xen-bus: " Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 18/41] hw/net/fsl_etsec: Set eTSEC device description and category Philippe Mathieu-Daudé
` (23 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Anthony PERARD
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Anthony PERARD <anthony.perard@vates.tech>
Message-Id: <20250218162618.46167-8-philmd@linaro.org>
---
include/hw/xen/xen-legacy-backend.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/include/hw/xen/xen-legacy-backend.h b/include/hw/xen/xen-legacy-backend.h
index e198b120c5d..2d0cbfecade 100644
--- a/include/hw/xen/xen-legacy-backend.h
+++ b/include/hw/xen/xen-legacy-backend.h
@@ -3,7 +3,6 @@
#include "hw/xen/xen_backend_ops.h"
#include "hw/xen/xen_pvdev.h"
-#include "net/net.h"
#include "qom/object.h"
#define TYPE_XENSYSDEV "xen-sysdev"
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 18/41] hw/net/fsl_etsec: Set eTSEC device description and category
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (16 preceding siblings ...)
2025-03-05 1:21 ` [PULL 17/41] hw/xen/xen-legacy-backend: Remove unused 'net/net.h' header Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 19/41] hw/char/pl011: Warn when using disabled receiver Philippe Mathieu-Daudé
` (22 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: BALATON Zoltan, Bernhard Beschow, Philippe Mathieu-Daudé
From: BALATON Zoltan <balaton@eik.bme.hu>
Add description and set category for eTSEC device so it shows up
better in -device help.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Bernhard Beschow <shentey@gmail.com>
Message-ID: <20250218155407.838774E600E@zero.eik.bme.hu>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/net/fsl_etsec/etsec.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/hw/net/fsl_etsec/etsec.c b/hw/net/fsl_etsec/etsec.c
index 3ce4fa2662d..adde6448926 100644
--- a/hw/net/fsl_etsec/etsec.c
+++ b/hw/net/fsl_etsec/etsec.c
@@ -423,8 +423,10 @@ static void etsec_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = etsec_realize;
+ dc->desc = "Freescale Enhanced Three-Speed Ethernet Controller";
device_class_set_legacy_reset(dc, etsec_reset);
device_class_set_props(dc, etsec_properties);
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
}
static const TypeInfo etsec_types[] = {
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 19/41] hw/char/pl011: Warn when using disabled receiver
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (17 preceding siblings ...)
2025-03-05 1:21 ` [PULL 18/41] hw/net/fsl_etsec: Set eTSEC device description and category Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 20/41] hw/char/pl011: Simplify a bit pl011_can_receive() Philippe Mathieu-Daudé
` (21 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Richard Henderson, Luc Michel
We shouldn't receive characters when the full UART or its
receiver is disabled. However we don't want to break the
possibly incomplete "my first bare metal assembly program"s,
so we choose to simply display a warning when this occurs.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Luc Michel <luc.michel@amd.com>
Message-Id: <20250220092903.3726-2-philmd@linaro.org>
---
hw/char/pl011.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
index 06ce851044d..12a2d4bc7bd 100644
--- a/hw/char/pl011.c
+++ b/hw/char/pl011.c
@@ -85,6 +85,7 @@ DeviceState *pl011_create(hwaddr addr, qemu_irq irq, Chardev *chr)
#define CR_OUT1 (1 << 12)
#define CR_RTS (1 << 11)
#define CR_DTR (1 << 10)
+#define CR_RXE (1 << 9)
#define CR_TXE (1 << 8)
#define CR_LBE (1 << 7)
#define CR_UARTEN (1 << 0)
@@ -487,6 +488,14 @@ static int pl011_can_receive(void *opaque)
PL011State *s = (PL011State *)opaque;
int r;
+ if (!(s->cr & CR_UARTEN)) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "PL011 receiving data on disabled UART\n");
+ }
+ if (!(s->cr & CR_RXE)) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "PL011 receiving data on disabled RX UART\n");
+ }
r = s->read_count < pl011_get_fifo_depth(s);
trace_pl011_can_receive(s->lcr, s->read_count, r);
return r;
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 20/41] hw/char/pl011: Simplify a bit pl011_can_receive()
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (18 preceding siblings ...)
2025-03-05 1:21 ` [PULL 19/41] hw/char/pl011: Warn when using disabled receiver Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 21/41] hw/char/pl011: Improve RX flow tracing events Philippe Mathieu-Daudé
` (20 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Luc Michel, Richard Henderson
Introduce 'fifo_depth' and 'fifo_available' local variables
to better express the 'r' variable use.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Luc Michel <luc.michel@amd.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20250220092903.3726-3-philmd@linaro.org>
---
hw/char/pl011.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
index 12a2d4bc7bd..5bb83c54216 100644
--- a/hw/char/pl011.c
+++ b/hw/char/pl011.c
@@ -486,7 +486,9 @@ static void pl011_write(void *opaque, hwaddr offset,
static int pl011_can_receive(void *opaque)
{
PL011State *s = (PL011State *)opaque;
- int r;
+ unsigned fifo_depth = pl011_get_fifo_depth(s);
+ unsigned fifo_available = fifo_depth - s->read_count;
+ int r = fifo_available ? 1 : 0;
if (!(s->cr & CR_UARTEN)) {
qemu_log_mask(LOG_GUEST_ERROR,
@@ -496,7 +498,6 @@ static int pl011_can_receive(void *opaque)
qemu_log_mask(LOG_GUEST_ERROR,
"PL011 receiving data on disabled RX UART\n");
}
- r = s->read_count < pl011_get_fifo_depth(s);
trace_pl011_can_receive(s->lcr, s->read_count, r);
return r;
}
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 21/41] hw/char/pl011: Improve RX flow tracing events
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (19 preceding siblings ...)
2025-03-05 1:21 ` [PULL 20/41] hw/char/pl011: Simplify a bit pl011_can_receive() Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 22/41] hw/char/pl011: Really use RX FIFO depth Philippe Mathieu-Daudé
` (19 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Alex Bennée, Luc Michel,
Richard Henderson
Log FIFO use (availability and depth).
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Luc Michel <luc.michel@amd.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20250220092903.3726-4-philmd@linaro.org>
---
hw/char/pl011.c | 10 ++++++----
hw/char/trace-events | 7 ++++---
2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
index 5bb83c54216..f7485e7c541 100644
--- a/hw/char/pl011.c
+++ b/hw/char/pl011.c
@@ -185,7 +185,7 @@ static void pl011_fifo_rx_put(void *opaque, uint32_t value)
s->read_fifo[slot] = value;
s->read_count++;
s->flags &= ~PL011_FLAG_RXFE;
- trace_pl011_fifo_rx_put(value, s->read_count);
+ trace_pl011_fifo_rx_put(value, s->read_count, pipe_depth);
if (s->read_count == pipe_depth) {
trace_pl011_fifo_rx_full();
s->flags |= PL011_FLAG_RXFF;
@@ -248,12 +248,13 @@ static void pl011_write_txdata(PL011State *s, uint8_t data)
static uint32_t pl011_read_rxdata(PL011State *s)
{
uint32_t c;
+ unsigned fifo_depth = pl011_get_fifo_depth(s);
s->flags &= ~PL011_FLAG_RXFF;
c = s->read_fifo[s->read_pos];
if (s->read_count > 0) {
s->read_count--;
- s->read_pos = (s->read_pos + 1) & (pl011_get_fifo_depth(s) - 1);
+ s->read_pos = (s->read_pos + 1) & (fifo_depth - 1);
}
if (s->read_count == 0) {
s->flags |= PL011_FLAG_RXFE;
@@ -261,7 +262,7 @@ static uint32_t pl011_read_rxdata(PL011State *s)
if (s->read_count == s->read_trigger - 1) {
s->int_level &= ~INT_RX;
}
- trace_pl011_read_fifo(s->read_count);
+ trace_pl011_read_fifo(s->read_count, fifo_depth);
s->rsr = c >> 8;
pl011_update(s);
qemu_chr_fe_accept_input(&s->chr);
@@ -498,12 +499,13 @@ static int pl011_can_receive(void *opaque)
qemu_log_mask(LOG_GUEST_ERROR,
"PL011 receiving data on disabled RX UART\n");
}
- trace_pl011_can_receive(s->lcr, s->read_count, r);
+ trace_pl011_can_receive(s->lcr, s->read_count, fifo_depth, fifo_available);
return r;
}
static void pl011_receive(void *opaque, const uint8_t *buf, int size)
{
+ trace_pl011_receive(size);
/*
* In loopback mode, the RX input signal is internally disconnected
* from the entire receiving logics; thus, all inputs are ignored,
diff --git a/hw/char/trace-events b/hw/char/trace-events
index b2e3d25ae34..05a33036c12 100644
--- a/hw/char/trace-events
+++ b/hw/char/trace-events
@@ -60,12 +60,13 @@ imx_serial_put_data(const char *chrname, uint32_t value) "%s: 0x%" PRIx32
# pl011.c
pl011_irq_state(int level) "irq state %d"
pl011_read(uint32_t addr, uint32_t value, const char *regname) "addr 0x%03x value 0x%08x reg %s"
-pl011_read_fifo(int read_count) "FIFO read, read_count now %d"
+pl011_read_fifo(unsigned rx_fifo_used, size_t rx_fifo_depth) "RX FIFO read, used %u/%zu"
pl011_write(uint32_t addr, uint32_t value, const char *regname) "addr 0x%03x value 0x%08x reg %s"
-pl011_can_receive(uint32_t lcr, int read_count, int r) "LCR 0x%08x read_count %d returning %d"
-pl011_fifo_rx_put(uint32_t c, int read_count) "new char 0x%02x read_count now %d"
+pl011_can_receive(uint32_t lcr, unsigned rx_fifo_used, size_t rx_fifo_depth, unsigned rx_fifo_available) "LCR 0x%02x, RX FIFO used %u/%zu, can_receive %u chars"
+pl011_fifo_rx_put(uint32_t c, unsigned read_count, size_t rx_fifo_depth) "RX FIFO push char [0x%02x] %d/%zu depth used"
pl011_fifo_rx_full(void) "RX FIFO now full, RXFF set"
pl011_baudrate_change(unsigned int baudrate, uint64_t clock, uint32_t ibrd, uint32_t fbrd) "new baudrate %u (clk: %" PRIu64 "hz, ibrd: %" PRIu32 ", fbrd: %" PRIu32 ")"
+pl011_receive(int size) "recv %d chars"
# cmsdk-apb-uart.c
cmsdk_apb_uart_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB UART read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 22/41] hw/char/pl011: Really use RX FIFO depth
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (20 preceding siblings ...)
2025-03-05 1:21 ` [PULL 21/41] hw/char/pl011: Improve RX flow tracing events Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 23/41] hw/char/bcm2835_aux: " Philippe Mathieu-Daudé
` (18 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Peter Maydell, Luc Michel,
Richard Henderson
While we model a 16-elements RX FIFO since the PL011 model was
introduced in commit cdbdb648b7c ("ARM Versatile Platform Baseboard
emulation"), we only read 1 char at a time!
Have the IOCanReadHandler handler return how many elements are
available, and use that in the IOReadHandler handler.
Example of FIFO better used by enabling the pl011 tracing events
and running the tests/functional/test_aarch64_virt.py tests:
pl011_can_receive LCR 0x70, RX FIFO used 0/16, can_receive 16 chars
pl011_receive recv 5 chars
pl011_fifo_rx_put RX FIFO push char [0x72] 1/16 depth used
pl011_irq_state irq state 1
pl011_fifo_rx_put RX FIFO push char [0x6f] 2/16 depth used
pl011_fifo_rx_put RX FIFO push char [0x6f] 3/16 depth used
pl011_fifo_rx_put RX FIFO push char [0x74] 4/16 depth used
pl011_fifo_rx_put RX FIFO push char [0x0d] 5/16 depth used
pl011_can_receive LCR 0x70, RX FIFO used 5/16, can_receive 11 chars
pl011_can_receive LCR 0x70, RX FIFO used 5/16, can_receive 11 chars
pl011_write addr 0x038 value 0x00000050 reg IMSC
pl011_irq_state irq state 1
pl011_can_receive LCR 0x70, RX FIFO used 5/16, can_receive 11 chars
pl011_read addr 0x03c value 0x00000030 reg RIS
pl011_write addr 0x044 value 0x00000000 reg ICR
pl011_irq_state irq state 1
pl011_read addr 0x018 value 0x00000080 reg FR
pl011_read_fifo RX FIFO read, used 4/16
pl011_irq_state irq state 1
pl011_read addr 0x000 value 0x00000072 reg DR
pl011_can_receive LCR 0x70, RX FIFO used 4/16, can_receive 12 chars
pl011_read addr 0x018 value 0x00000080 reg FR
pl011_read_fifo RX FIFO read, used 3/16
pl011_irq_state irq state 1
pl011_read addr 0x000 value 0x0000006f reg DR
pl011_can_receive LCR 0x70, RX FIFO used 3/16, can_receive 13 chars
pl011_read addr 0x018 value 0x00000080 reg FR
pl011_read_fifo RX FIFO read, used 2/16
pl011_irq_state irq state 1
pl011_read addr 0x000 value 0x0000006f reg DR
pl011_can_receive LCR 0x70, RX FIFO used 2/16, can_receive 14 chars
pl011_read addr 0x018 value 0x00000080 reg FR
pl011_read_fifo RX FIFO read, used 1/16
pl011_irq_state irq state 1
pl011_read addr 0x000 value 0x00000074 reg DR
pl011_can_receive LCR 0x70, RX FIFO used 1/16, can_receive 15 chars
pl011_read addr 0x018 value 0x00000080 reg FR
pl011_read_fifo RX FIFO read, used 0/16
pl011_irq_state irq state 0
pl011_read addr 0x000 value 0x0000000d reg DR
pl011_can_receive LCR 0x70, RX FIFO used 0/16, can_receive 16 chars
pl011_read addr 0x018 value 0x00000090 reg FR
pl011_read addr 0x03c value 0x00000020 reg RIS
pl011_write addr 0x038 value 0x00000050 reg IMSC
pl011_irq_state irq state 0
pl011_can_receive LCR 0x70, RX FIFO used 0/16, can_receive 16 chars
pl011_can_receive LCR 0x70, RX FIFO used 0/16, can_receive 16 chars
pl011_read addr 0x018 value 0x00000090 reg FR
pl011_write addr 0x000 value 0x00000072 reg DR
Inspired-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Luc Michel <luc.michel@amd.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20250220092903.3726-5-philmd@linaro.org>
---
hw/char/pl011.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
index f7485e7c541..23a9db8c57c 100644
--- a/hw/char/pl011.c
+++ b/hw/char/pl011.c
@@ -489,7 +489,6 @@ static int pl011_can_receive(void *opaque)
PL011State *s = (PL011State *)opaque;
unsigned fifo_depth = pl011_get_fifo_depth(s);
unsigned fifo_available = fifo_depth - s->read_count;
- int r = fifo_available ? 1 : 0;
if (!(s->cr & CR_UARTEN)) {
qemu_log_mask(LOG_GUEST_ERROR,
@@ -500,7 +499,8 @@ static int pl011_can_receive(void *opaque)
"PL011 receiving data on disabled RX UART\n");
}
trace_pl011_can_receive(s->lcr, s->read_count, fifo_depth, fifo_available);
- return r;
+
+ return fifo_available;
}
static void pl011_receive(void *opaque, const uint8_t *buf, int size)
@@ -515,7 +515,9 @@ static void pl011_receive(void *opaque, const uint8_t *buf, int size)
return;
}
- pl011_fifo_rx_put(opaque, *buf);
+ for (int i = 0; i < size; i++) {
+ pl011_fifo_rx_put(opaque, buf[i]);
+ }
}
static void pl011_event(void *opaque, QEMUChrEvent event)
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 23/41] hw/char/bcm2835_aux: Really use RX FIFO depth
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (21 preceding siblings ...)
2025-03-05 1:21 ` [PULL 22/41] hw/char/pl011: Really use RX FIFO depth Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 24/41] hw/char/imx_serial: " Philippe Mathieu-Daudé
` (17 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Luc Michel, Richard Henderson
While we model a 8-elements RX FIFO since the BCM2835 AUX model
was introduced in commit 97398d900ca ("bcm2835_aux: add emulation
of BCM2835 AUX block") we only read 1 char at a time!
Have the IOCanReadHandler handler return how many elements are
available, and use that in the IOReadHandler handler.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Luc Michel <luc.michel@amd.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20250220092903.3726-6-philmd@linaro.org>
---
hw/char/bcm2835_aux.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/hw/char/bcm2835_aux.c b/hw/char/bcm2835_aux.c
index 73ad5934067..c6e7eccf7dd 100644
--- a/hw/char/bcm2835_aux.c
+++ b/hw/char/bcm2835_aux.c
@@ -221,7 +221,7 @@ static int bcm2835_aux_can_receive(void *opaque)
{
BCM2835AuxState *s = opaque;
- return s->read_count < BCM2835_AUX_RX_FIFO_LEN;
+ return BCM2835_AUX_RX_FIFO_LEN - s->read_count;
}
static void bcm2835_aux_put_fifo(void *opaque, uint8_t value)
@@ -243,7 +243,9 @@ static void bcm2835_aux_put_fifo(void *opaque, uint8_t value)
static void bcm2835_aux_receive(void *opaque, const uint8_t *buf, int size)
{
- bcm2835_aux_put_fifo(opaque, *buf);
+ for (int i = 0; i < size; i++) {
+ bcm2835_aux_put_fifo(opaque, buf[i]);
+ }
}
static const MemoryRegionOps bcm2835_aux_ops = {
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 24/41] hw/char/imx_serial: Really use RX FIFO depth
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (22 preceding siblings ...)
2025-03-05 1:21 ` [PULL 23/41] hw/char/bcm2835_aux: " Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 25/41] hw/char/mcf_uart: Use FIFO_DEPTH definition instead of magic values Philippe Mathieu-Daudé
` (16 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Luc Michel, Richard Henderson,
Bernhard Beschow
While we model a 32-elements RX FIFO since the IMX serial
model was introduced in commit 988f2442971 ("hw/char/imx_serial:
Implement receive FIFO and ageing timer") we only read 1 char
at a time!
Have the IOCanReadHandler handler return how many elements are
available, and use that in the IOReadHandler handler.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Luc Michel <luc.michel@amd.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Bernhard Beschow <shentey@gmail.com>
Message-Id: <20250220092903.3726-7-philmd@linaro.org>
---
hw/char/imx_serial.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
index 38b4865157e..6f14f8403a9 100644
--- a/hw/char/imx_serial.c
+++ b/hw/char/imx_serial.c
@@ -386,7 +386,8 @@ static void imx_serial_write(void *opaque, hwaddr offset,
static int imx_can_receive(void *opaque)
{
IMXSerialState *s = (IMXSerialState *)opaque;
- return s->ucr2 & UCR2_RXEN && fifo32_num_used(&s->rx_fifo) < FIFO_SIZE;
+
+ return s->ucr2 & UCR2_RXEN ? fifo32_num_free(&s->rx_fifo) : 0;
}
static void imx_put_data(void *opaque, uint32_t value)
@@ -417,7 +418,10 @@ static void imx_receive(void *opaque, const uint8_t *buf, int size)
IMXSerialState *s = (IMXSerialState *)opaque;
s->usr2 |= USR2_WAKE;
- imx_put_data(opaque, *buf);
+
+ for (int i = 0; i < size; i++) {
+ imx_put_data(opaque, buf[i]);
+ }
}
static void imx_event(void *opaque, QEMUChrEvent event)
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 25/41] hw/char/mcf_uart: Use FIFO_DEPTH definition instead of magic values
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (23 preceding siblings ...)
2025-03-05 1:21 ` [PULL 24/41] hw/char/imx_serial: " Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 26/41] hw/char/mcf_uart: Really use RX FIFO depth Philippe Mathieu-Daudé
` (15 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Luc Michel, Thomas Huth,
Richard Henderson
Defines FIFO_DEPTH and use it, fixing coding style.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Luc Michel <luc.michel@amd.com>
Reviewed-by: Thomas Huth <huth@tuxfamily.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20250220092903.3726-8-philmd@linaro.org>
---
hw/char/mcf_uart.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/hw/char/mcf_uart.c b/hw/char/mcf_uart.c
index 980a12fcb7d..95f269ee9b7 100644
--- a/hw/char/mcf_uart.c
+++ b/hw/char/mcf_uart.c
@@ -17,6 +17,8 @@
#include "chardev/char-fe.h"
#include "qom/object.h"
+#define FIFO_DEPTH 4
+
struct mcf_uart_state {
SysBusDevice parent_obj;
@@ -27,7 +29,7 @@ struct mcf_uart_state {
uint8_t imr;
uint8_t bg1;
uint8_t bg2;
- uint8_t fifo[4];
+ uint8_t fifo[FIFO_DEPTH];
uint8_t tb;
int current_mr;
int fifo_len;
@@ -247,14 +249,16 @@ static void mcf_uart_reset(DeviceState *dev)
static void mcf_uart_push_byte(mcf_uart_state *s, uint8_t data)
{
/* Break events overwrite the last byte if the fifo is full. */
- if (s->fifo_len == 4)
+ if (s->fifo_len == FIFO_DEPTH) {
s->fifo_len--;
+ }
s->fifo[s->fifo_len] = data;
s->fifo_len++;
s->sr |= MCF_UART_RxRDY;
- if (s->fifo_len == 4)
+ if (s->fifo_len == FIFO_DEPTH) {
s->sr |= MCF_UART_FFULL;
+ }
mcf_uart_update(s);
}
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 26/41] hw/char/mcf_uart: Really use RX FIFO depth
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (24 preceding siblings ...)
2025-03-05 1:21 ` [PULL 25/41] hw/char/mcf_uart: Use FIFO_DEPTH definition instead of magic values Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 27/41] hw/char/sh_serial: Return correct number of empty RX FIFO elements Philippe Mathieu-Daudé
` (14 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Luc Michel, Thomas Huth,
Richard Henderson
While we model a 4-elements RX FIFO since the MCF UART model
was introduced in commit 20dcee94833 ("MCF5208 emulation"),
we only read 1 char at a time!
Have the IOCanReadHandler handler return how many elements are
available, and use that in the IOReadHandler handler.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Luc Michel <luc.michel@amd.com>
Tested-by: Thomas Huth <huth@tuxfamily.org>
Reviewed-by: Thomas Huth <huth@tuxfamily.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20250220092903.3726-9-philmd@linaro.org>
---
hw/char/mcf_uart.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/hw/char/mcf_uart.c b/hw/char/mcf_uart.c
index 95f269ee9b7..529c26be93a 100644
--- a/hw/char/mcf_uart.c
+++ b/hw/char/mcf_uart.c
@@ -281,14 +281,16 @@ static int mcf_uart_can_receive(void *opaque)
{
mcf_uart_state *s = (mcf_uart_state *)opaque;
- return s->rx_enabled && (s->sr & MCF_UART_FFULL) == 0;
+ return s->rx_enabled ? FIFO_DEPTH - s->fifo_len : 0;
}
static void mcf_uart_receive(void *opaque, const uint8_t *buf, int size)
{
mcf_uart_state *s = (mcf_uart_state *)opaque;
- mcf_uart_push_byte(s, buf[0]);
+ for (int i = 0; i < size; i++) {
+ mcf_uart_push_byte(s, buf[i]);
+ }
}
static const MemoryRegionOps mcf_uart_ops = {
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 27/41] hw/char/sh_serial: Return correct number of empty RX FIFO elements
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (25 preceding siblings ...)
2025-03-05 1:21 ` [PULL 26/41] hw/char/mcf_uart: Really use RX FIFO depth Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 28/41] hw/char/sifive_uart: Free fifo on unrealize Philippe Mathieu-Daudé
` (13 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Luc Michel, Richard Henderson
In the IOCanReadHandler sh_serial_can_receive(), if the Serial
Control Register 'Receive Enable' bit is set (bit 4), then we
return a size of (1 << 4) which happens to be equal to 16, so
effectively SH_RX_FIFO_LENGTH.
The IOReadHandler, sh_serial_receive1() takes care to receive
multiple chars, but if the FIFO is partly filled, we only process
the number of free slots in the FIFO, discarding the other chars!
Fix by returning how many elements the FIFO can queue in the
IOCanReadHandler, so we don't have to process more than that in
the IOReadHandler, thus not discarding anything.
Remove the now unnecessary check on 's->rx_cnt < SH_RX_FIFO_LENGTH'
in IOReadHandler, reducing the block indentation.
Fixes: 63242a007a1 ("SH4: Serial controller improvement")
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Luc Michel <luc.michel@amd.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20250220092903.3726-10-philmd@linaro.org>
---
hw/char/sh_serial.c | 30 ++++++++++++++----------------
1 file changed, 14 insertions(+), 16 deletions(-)
diff --git a/hw/char/sh_serial.c b/hw/char/sh_serial.c
index 247aeb071ac..41c8175a638 100644
--- a/hw/char/sh_serial.c
+++ b/hw/char/sh_serial.c
@@ -320,7 +320,7 @@ static uint64_t sh_serial_read(void *opaque, hwaddr offs,
static int sh_serial_can_receive(SHSerialState *s)
{
- return s->scr & (1 << 4);
+ return s->scr & (1 << 4) ? SH_RX_FIFO_LENGTH - s->rx_head : 0;
}
static void sh_serial_receive_break(SHSerialState *s)
@@ -353,22 +353,20 @@ static void sh_serial_receive1(void *opaque, const uint8_t *buf, int size)
if (s->feat & SH_SERIAL_FEAT_SCIF) {
int i;
for (i = 0; i < size; i++) {
- if (s->rx_cnt < SH_RX_FIFO_LENGTH) {
- s->rx_fifo[s->rx_head++] = buf[i];
- if (s->rx_head == SH_RX_FIFO_LENGTH) {
- s->rx_head = 0;
- }
- s->rx_cnt++;
- if (s->rx_cnt >= s->rtrg) {
- s->flags |= SH_SERIAL_FLAG_RDF;
- if (s->scr & (1 << 6) && s->rxi) {
- timer_del(&s->fifo_timeout_timer);
- qemu_set_irq(s->rxi, 1);
- }
- } else {
- timer_mod(&s->fifo_timeout_timer,
- qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 15 * s->etu);
+ s->rx_fifo[s->rx_head++] = buf[i];
+ if (s->rx_head == SH_RX_FIFO_LENGTH) {
+ s->rx_head = 0;
+ }
+ s->rx_cnt++;
+ if (s->rx_cnt >= s->rtrg) {
+ s->flags |= SH_SERIAL_FLAG_RDF;
+ if (s->scr & (1 << 6) && s->rxi) {
+ timer_del(&s->fifo_timeout_timer);
+ qemu_set_irq(s->rxi, 1);
}
+ } else {
+ timer_mod(&s->fifo_timeout_timer,
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 15 * s->etu);
}
}
} else {
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 28/41] hw/char/sifive_uart: Free fifo on unrealize
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (26 preceding siblings ...)
2025-03-05 1:21 ` [PULL 27/41] hw/char/sh_serial: Return correct number of empty RX FIFO elements Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 29/41] hw/misc/macio: Improve trace logs Philippe Mathieu-Daudé
` (12 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel
Cc: Alistair Francis, Alistair Francis, Philippe Mathieu-Daudé,
Daniel Henrique Barboza, Clément Chigot
From: Alistair Francis <alistair23@gmail.com>
We previously allocate the fifo on reset and never free it, which means
we are leaking memory.
Instead let's allocate on realize and free on unrealize.
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Tested-by: Clément Chigot <chigot@adacore.com>
Message-ID: <20250303023120.157221-1-alistair.francis@wdc.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/char/sifive_uart.c | 44 +++++++++++++++++++++++++++----------------
1 file changed, 28 insertions(+), 16 deletions(-)
diff --git a/hw/char/sifive_uart.c b/hw/char/sifive_uart.c
index 4bc5767284b..b45e6c098c4 100644
--- a/hw/char/sifive_uart.c
+++ b/hw/char/sifive_uart.c
@@ -251,6 +251,23 @@ static int sifive_uart_be_change(void *opaque)
return 0;
}
+static void sifive_uart_reset_enter(Object *obj, ResetType type)
+{
+ SiFiveUARTState *s = SIFIVE_UART(obj);
+
+ s->txfifo = 0;
+ s->ie = 0;
+ s->ip = 0;
+ s->txctrl = 0;
+ s->rxctrl = 0;
+ s->div = 0;
+
+ s->rx_fifo_len = 0;
+
+ memset(s->rx_fifo, 0, SIFIVE_UART_RX_FIFO_SIZE);
+ fifo8_reset(&s->tx_fifo);
+}
+
static const Property sifive_uart_properties[] = {
DEFINE_PROP_CHR("chardev", SiFiveUARTState, chr),
};
@@ -270,30 +287,24 @@ static void sifive_uart_realize(DeviceState *dev, Error **errp)
{
SiFiveUARTState *s = SIFIVE_UART(dev);
+ fifo8_create(&s->tx_fifo, SIFIVE_UART_TX_FIFO_SIZE);
+
s->fifo_trigger_handle = timer_new_ns(QEMU_CLOCK_VIRTUAL,
fifo_trigger_update, s);
- qemu_chr_fe_set_handlers(&s->chr, sifive_uart_can_rx, sifive_uart_rx,
- sifive_uart_event, sifive_uart_be_change, s,
- NULL, true);
+ if (qemu_chr_fe_backend_connected(&s->chr)) {
+ qemu_chr_fe_set_handlers(&s->chr, sifive_uart_can_rx, sifive_uart_rx,
+ sifive_uart_event, sifive_uart_be_change, s,
+ NULL, true);
+ }
}
-static void sifive_uart_reset_enter(Object *obj, ResetType type)
+static void sifive_uart_unrealize(DeviceState *dev)
{
- SiFiveUARTState *s = SIFIVE_UART(obj);
+ SiFiveUARTState *s = SIFIVE_UART(dev);
- s->txfifo = 0;
- s->ie = 0;
- s->ip = 0;
- s->txctrl = 0;
- s->rxctrl = 0;
- s->div = 0;
-
- s->rx_fifo_len = 0;
-
- memset(s->rx_fifo, 0, SIFIVE_UART_RX_FIFO_SIZE);
- fifo8_create(&s->tx_fifo, SIFIVE_UART_TX_FIFO_SIZE);
+ fifo8_destroy(&s->tx_fifo);
}
static void sifive_uart_reset_hold(Object *obj, ResetType type)
@@ -329,6 +340,7 @@ static void sifive_uart_class_init(ObjectClass *oc, void *data)
ResettableClass *rc = RESETTABLE_CLASS(oc);
dc->realize = sifive_uart_realize;
+ dc->unrealize = sifive_uart_unrealize;
dc->vmsd = &vmstate_sifive_uart;
rc->phases.enter = sifive_uart_reset_enter;
rc->phases.hold = sifive_uart_reset_hold;
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 29/41] hw/misc/macio: Improve trace logs
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (27 preceding siblings ...)
2025-03-05 1:21 ` [PULL 28/41] hw/char/sifive_uart: Free fifo on unrealize Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 30/41] hw/misc/macio/gpio: Add constants for register bits Philippe Mathieu-Daudé
` (11 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: BALATON Zoltan, Mark Cave-Ayland, Philippe Mathieu-Daudé
From: BALATON Zoltan <balaton@eik.bme.hu>
Add macio_gpio_read trace event and use that in macio_gpio_read()
instead of macio_gpio_write. Also change log message to match
macio_timer_{read,write}.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20250222122850.9D8B84E603D@zero.eik.bme.hu>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/misc/macio/gpio.c | 2 +-
hw/misc/macio/trace-events | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/hw/misc/macio/gpio.c b/hw/misc/macio/gpio.c
index 7cad62819a0..4364afc84af 100644
--- a/hw/misc/macio/gpio.c
+++ b/hw/misc/macio/gpio.c
@@ -135,7 +135,7 @@ static uint64_t macio_gpio_read(void *opaque, hwaddr addr, unsigned size)
}
}
- trace_macio_gpio_write(addr, val);
+ trace_macio_gpio_read(addr, val);
return val;
}
diff --git a/hw/misc/macio/trace-events b/hw/misc/macio/trace-events
index ad4b9d1c08e..055a407aebb 100644
--- a/hw/misc/macio/trace-events
+++ b/hw/misc/macio/trace-events
@@ -18,7 +18,8 @@ macio_timer_read(uint64_t addr, unsigned len, uint32_t val) "read addr 0x%"PRIx6
macio_set_gpio(int gpio, bool state) "setting GPIO %d to %d"
macio_gpio_irq_assert(int gpio) "asserting GPIO %d"
macio_gpio_irq_deassert(int gpio) "deasserting GPIO %d"
-macio_gpio_write(uint64_t addr, uint64_t val) "addr: 0x%"PRIx64" value: 0x%"PRIx64
+macio_gpio_write(uint64_t addr, uint64_t val) "addr 0x%"PRIx64" val 0x%"PRIx64
+macio_gpio_read(uint64_t addr, uint64_t val) "addr 0x%"PRIx64" val 0x%"PRIx64
# pmu.c
pmu_adb_poll(int olen) "ADB autopoll, olen=%d"
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 30/41] hw/misc/macio/gpio: Add constants for register bits
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (28 preceding siblings ...)
2025-03-05 1:21 ` [PULL 29/41] hw/misc/macio: Improve trace logs Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 31/41] hw/ufs: Add temperature event notification support Philippe Mathieu-Daudé
` (10 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: BALATON Zoltan, Philippe Mathieu-Daudé, Mark Cave-Ayland
From: BALATON Zoltan <balaton@eik.bme.hu>
Add named constants for register bit values that should make it easier
to understand what these mean.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Message-ID: <20250224141026.3B36C4E6010@zero.eik.bme.hu>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/misc/macio/gpio.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/hw/misc/macio/gpio.c b/hw/misc/macio/gpio.c
index 4364afc84af..e87bfca1f5d 100644
--- a/hw/misc/macio/gpio.c
+++ b/hw/misc/macio/gpio.c
@@ -34,6 +34,11 @@
#include "qemu/module.h"
#include "trace.h"
+enum MacioGPIORegisterBits {
+ OUT_DATA = 1,
+ IN_DATA = 2,
+ OUT_ENABLE = 4,
+};
void macio_set_gpio(MacIOGPIOState *s, uint32_t gpio, bool state)
{
@@ -41,14 +46,14 @@ void macio_set_gpio(MacIOGPIOState *s, uint32_t gpio, bool state)
trace_macio_set_gpio(gpio, state);
- if (s->gpio_regs[gpio] & 4) {
+ if (s->gpio_regs[gpio] & OUT_ENABLE) {
qemu_log_mask(LOG_GUEST_ERROR,
"GPIO: Setting GPIO %d while it's an output\n", gpio);
}
- new_reg = s->gpio_regs[gpio] & ~2;
+ new_reg = s->gpio_regs[gpio] & ~IN_DATA;
if (state) {
- new_reg |= 2;
+ new_reg |= IN_DATA;
}
if (new_reg == s->gpio_regs[gpio]) {
@@ -107,12 +112,12 @@ static void macio_gpio_write(void *opaque, hwaddr addr, uint64_t value,
addr -= 8;
if (addr < 36) {
- value &= ~2;
+ value &= ~IN_DATA;
- if (value & 4) {
- ibit = (value & 1) << 1;
+ if (value & OUT_ENABLE) {
+ ibit = (value & OUT_DATA) << 1;
} else {
- ibit = s->gpio_regs[addr] & 2;
+ ibit = s->gpio_regs[addr] & IN_DATA;
}
s->gpio_regs[addr] = value | ibit;
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 31/41] hw/ufs: Add temperature event notification support
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (29 preceding siblings ...)
2025-03-05 1:21 ` [PULL 30/41] hw/misc/macio/gpio: Add constants for register bits Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 32/41] tests/qtest/ufs-test: Add test code for the temperature feature Philippe Mathieu-Daudé
` (9 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: Keoseong Park, Jeuk Kim, Philippe Mathieu-Daudé
From: Keoseong Park <keosung.park@samsung.com>
This patch introduces temperature event notification support to the UFS
emulation. It enables the emulated UFS device to generate
temperature-related events, including high and low temperature
notifications, in compliance with the UFS specification.
With this feature, UFS drivers can now handle temperature exception events
during testing and development within the emulated environment.
This enhances validation and debugging capabilities for thermal event
handling in UFS implementations.
Signed-off-by: Keoseong Park <keosung.park@samsung.com>
Reviewed-by: Jeuk Kim <jeuk20.kim@samsung.com>
Message-ID: <20250225064146epcms2p50889cb0066e2d4734f2386de325bcdf6@epcms2p5>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/ufs/ufs.h | 2 ++
include/block/ufs.h | 13 +++++++-
hw/ufs/ufs.c | 78 ++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 91 insertions(+), 2 deletions(-)
diff --git a/hw/ufs/ufs.h b/hw/ufs/ufs.h
index 4bcc41f53a0..3799d97f30d 100644
--- a/hw/ufs/ufs.h
+++ b/hw/ufs/ufs.h
@@ -146,6 +146,8 @@ typedef struct UfsHc {
/* MCQ properties */
UfsSq *sq[UFS_MAX_MCQ_QNUM];
UfsCq *cq[UFS_MAX_MCQ_QNUM];
+
+ uint8_t temperature;
} UfsHc;
static inline uint32_t ufs_mcq_sq_tail(UfsHc *u, uint32_t qid)
diff --git a/include/block/ufs.h b/include/block/ufs.h
index 57f5ea3500c..a3ee62b027a 100644
--- a/include/block/ufs.h
+++ b/include/block/ufs.h
@@ -461,7 +461,7 @@ typedef struct Attributes {
uint8_t psa_state;
uint32_t psa_data_size;
uint8_t ref_clk_gating_wait_time;
- uint8_t device_case_rough_temperaure;
+ uint8_t device_case_rough_temperature;
uint8_t device_too_high_temp_boundary;
uint8_t device_too_low_temp_boundary;
uint8_t throttling_status;
@@ -1073,6 +1073,11 @@ enum health_desc_param {
UFS_HEALTH_DESC_PARAM_LIFE_TIME_EST_B = 0x4,
};
+enum {
+ UFS_DEV_HIGH_TEMP_NOTIF = BIT(4),
+ UFS_DEV_LOW_TEMP_NOTIF = BIT(5),
+};
+
/* WriteBooster buffer mode */
enum {
UFS_WB_BUF_MODE_LU_DEDICATED = 0x0,
@@ -1091,6 +1096,12 @@ enum ufs_lu_wp_type {
UFS_LU_PERM_WP = 0x02,
};
+/* Exception event mask values */
+enum {
+ MASK_EE_TOO_HIGH_TEMP = BIT(3),
+ MASK_EE_TOO_LOW_TEMP = BIT(4),
+};
+
/* UTP QUERY Transaction Specific Fields OpCode */
enum query_opcode {
UFS_UPIU_QUERY_OPCODE_NOP = 0x0,
diff --git a/hw/ufs/ufs.c b/hw/ufs/ufs.c
index 1ccd6f88b69..857de6e9c2c 100644
--- a/hw/ufs/ufs.c
+++ b/hw/ufs/ufs.c
@@ -34,6 +34,11 @@
#define UFS_MAX_NUTMRS 8
#define UFS_MCQ_QCFGPTR 2
+/* Each value represents the temperature in celsius as (value - 80) */
+#define UFS_TEMPERATURE 120
+#define UFS_TOO_HIGH_TEMP_BOUNDARY 160
+#define UFS_TOO_LOW_TEMP_BOUNDARY 60
+
static void ufs_exec_req(UfsRequest *req);
static void ufs_clear_req(UfsRequest *req);
@@ -838,6 +843,42 @@ static const MemoryRegionOps ufs_mmio_ops = {
},
};
+static void ufs_update_ee_status(UfsHc *u)
+{
+ uint16_t ee_status = be16_to_cpu(u->attributes.exception_event_status);
+ uint8_t high_temp_thresh = u->attributes.device_too_high_temp_boundary;
+ uint8_t low_temp_thresh = u->attributes.device_too_low_temp_boundary;
+
+ if (u->temperature >= high_temp_thresh) {
+ ee_status |= MASK_EE_TOO_HIGH_TEMP;
+ } else {
+ ee_status &= ~MASK_EE_TOO_HIGH_TEMP;
+ }
+
+ if (u->temperature <= low_temp_thresh) {
+ ee_status |= MASK_EE_TOO_LOW_TEMP;
+ } else {
+ ee_status &= ~MASK_EE_TOO_LOW_TEMP;
+ }
+
+ u->attributes.exception_event_status = cpu_to_be16(ee_status);
+}
+
+static bool ufs_check_exception_event_alert(UfsHc *u, uint8_t trans_type)
+{
+ uint16_t ee_control = be16_to_cpu(u->attributes.exception_event_control);
+ uint16_t ee_status;
+
+ if (trans_type != UFS_UPIU_TRANSACTION_RESPONSE) {
+ return false;
+ }
+
+ ufs_update_ee_status(u);
+
+ ee_status = be16_to_cpu(u->attributes.exception_event_status);
+
+ return ee_control & ee_status;
+}
void ufs_build_upiu_header(UfsRequest *req, uint8_t trans_type, uint8_t flags,
uint8_t response, uint8_t scsi_status,
@@ -848,6 +889,8 @@ void ufs_build_upiu_header(UfsRequest *req, uint8_t trans_type, uint8_t flags,
req->rsp_upiu.header.flags = flags;
req->rsp_upiu.header.response = response;
req->rsp_upiu.header.scsi_status = scsi_status;
+ req->rsp_upiu.header.device_inf =
+ ufs_check_exception_event_alert(req->hc, trans_type);
req->rsp_upiu.header.data_segment_length = cpu_to_be16(data_segment_length);
}
@@ -1042,6 +1085,25 @@ static QueryRespCode ufs_exec_query_flag(UfsRequest *req, int op)
return UFS_QUERY_RESULT_SUCCESS;
}
+static inline uint8_t ufs_read_device_temp(UfsHc *u)
+{
+ uint8_t feat_sup = u->device_desc.ufs_features_support;
+ bool high_temp_sup, low_temp_sup, high_temp_en, low_temp_en;
+ uint16_t ee_control = be16_to_cpu(u->attributes.exception_event_control);
+
+ high_temp_sup = feat_sup & UFS_DEV_HIGH_TEMP_NOTIF;
+ low_temp_sup = feat_sup & UFS_DEV_LOW_TEMP_NOTIF;
+ high_temp_en = ee_control & MASK_EE_TOO_HIGH_TEMP;
+ low_temp_en = ee_control & MASK_EE_TOO_LOW_TEMP;
+
+ if ((high_temp_sup && high_temp_en) ||
+ (low_temp_sup && low_temp_en)) {
+ return u->temperature;
+ }
+
+ return 0;
+}
+
static uint32_t ufs_read_attr_value(UfsHc *u, uint8_t idn)
{
switch (idn) {
@@ -1072,6 +1134,7 @@ static uint32_t ufs_read_attr_value(UfsHc *u, uint8_t idn)
case UFS_QUERY_ATTR_IDN_EE_CONTROL:
return be16_to_cpu(u->attributes.exception_event_control);
case UFS_QUERY_ATTR_IDN_EE_STATUS:
+ ufs_update_ee_status(u);
return be16_to_cpu(u->attributes.exception_event_status);
case UFS_QUERY_ATTR_IDN_SECONDS_PASSED:
return be32_to_cpu(u->attributes.seconds_passed);
@@ -1086,7 +1149,8 @@ static uint32_t ufs_read_attr_value(UfsHc *u, uint8_t idn)
case UFS_QUERY_ATTR_IDN_REF_CLK_GATING_WAIT_TIME:
return u->attributes.ref_clk_gating_wait_time;
case UFS_QUERY_ATTR_IDN_CASE_ROUGH_TEMP:
- return u->attributes.device_case_rough_temperaure;
+ u->attributes.device_case_rough_temperature = ufs_read_device_temp(u);
+ return u->attributes.device_case_rough_temperature;
case UFS_QUERY_ATTR_IDN_HIGH_TEMP_BOUND:
return u->attributes.device_too_high_temp_boundary;
case UFS_QUERY_ATTR_IDN_LOW_TEMP_BOUND:
@@ -1677,8 +1741,12 @@ static void ufs_init_hc(UfsHc *u)
u->device_desc.ud_0_base_offset = 0x16;
u->device_desc.ud_config_p_length = 0x1A;
u->device_desc.device_rtt_cap = 0x02;
+ u->device_desc.ufs_features_support = UFS_DEV_HIGH_TEMP_NOTIF |
+ UFS_DEV_LOW_TEMP_NOTIF;
u->device_desc.queue_depth = u->params.nutrs;
u->device_desc.product_revision_level = 0x04;
+ u->device_desc.extended_ufs_features_support =
+ cpu_to_be32(UFS_DEV_HIGH_TEMP_NOTIF | UFS_DEV_LOW_TEMP_NOTIF);
memset(&u->geometry_desc, 0, sizeof(GeometryDescriptor));
u->geometry_desc.length = sizeof(GeometryDescriptor);
@@ -1702,9 +1770,17 @@ static void ufs_init_hc(UfsHc *u)
/* configure descriptor is not supported */
u->attributes.config_descr_lock = 0x01;
u->attributes.max_num_of_rtt = 0x02;
+ u->attributes.device_too_high_temp_boundary = UFS_TOO_HIGH_TEMP_BOUNDARY;
+ u->attributes.device_too_low_temp_boundary = UFS_TOO_LOW_TEMP_BOUNDARY;
memset(&u->flags, 0, sizeof(u->flags));
u->flags.permanently_disable_fw_update = 1;
+
+ /*
+ * The temperature value is fixed to UFS_TEMPERATURE and does not change
+ * dynamically
+ */
+ u->temperature = UFS_TEMPERATURE;
}
static void ufs_realize(PCIDevice *pci_dev, Error **errp)
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 32/41] tests/qtest/ufs-test: Add test code for the temperature feature
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (30 preceding siblings ...)
2025-03-05 1:21 ` [PULL 31/41] hw/ufs: Add temperature event notification support Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 33/41] hw/arm/omap1: Convert raw printfs to qemu_log_mask() Philippe Mathieu-Daudé
` (8 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel
Cc: Keoseong Park, Fabiano Rosas, Jeuk Kim,
Philippe Mathieu-Daudé
From: Keoseong Park <keosung.park@samsung.com>
This commit adds tests to verify the correctness of query attribute
results related to the temperature feature. It ensures that querying
temperature attributes returns expected values.
Signed-off-by: Keoseong Park <keosung.park@samsung.com>
Acked-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Jeuk Kim <jeuk20.kim@samsung.com>
Message-ID: <20250225064243epcms2p8b7b59e7bf381bd68d30a6f59b40dea9f@epcms2p8>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
tests/qtest/ufs-test.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/tests/qtest/ufs-test.c b/tests/qtest/ufs-test.c
index d5076bdeb54..4867ccf08a1 100644
--- a/tests/qtest/ufs-test.c
+++ b/tests/qtest/ufs-test.c
@@ -784,6 +784,30 @@ static void ufstest_query_attr_request(void *obj, void *data,
g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x00));
+ ocs = ufs_send_query(ufs, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
+ UFS_UPIU_QUERY_OPCODE_READ_ATTR,
+ UFS_QUERY_ATTR_IDN_CASE_ROUGH_TEMP, 0, 0, 0,
+ &rsp_upiu);
+ g_assert_cmpuint(ocs, ==, UFS_OCS_SUCCESS);
+ g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
+ g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(0x00));
+
+ ocs = ufs_send_query(ufs, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
+ UFS_UPIU_QUERY_OPCODE_READ_ATTR,
+ UFS_QUERY_ATTR_IDN_HIGH_TEMP_BOUND, 0, 0, 0,
+ &rsp_upiu);
+ g_assert_cmpuint(ocs, ==, UFS_OCS_SUCCESS);
+ g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
+ g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(160));
+
+ ocs = ufs_send_query(ufs, UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST,
+ UFS_UPIU_QUERY_OPCODE_READ_ATTR,
+ UFS_QUERY_ATTR_IDN_LOW_TEMP_BOUND, 0, 0, 0,
+ &rsp_upiu);
+ g_assert_cmpuint(ocs, ==, UFS_OCS_SUCCESS);
+ g_assert_cmpuint(rsp_upiu.header.response, ==, UFS_COMMAND_RESULT_SUCCESS);
+ g_assert_cmpuint(rsp_upiu.qr.value, ==, cpu_to_be32(60));
+
/* Write Writable Attributes & Read Again */
ocs = ufs_send_query(ufs, UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST,
UFS_UPIU_QUERY_OPCODE_WRITE_ATTR,
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 33/41] hw/arm/omap1: Convert raw printfs to qemu_log_mask()
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (31 preceding siblings ...)
2025-03-05 1:21 ` [PULL 32/41] tests/qtest/ufs-test: Add test code for the temperature feature Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 34/41] hw/arm/omap1: Drop ALMDEBUG ifdeffed out code Philippe Mathieu-Daudé
` (7 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Richard Henderson, Philippe Mathieu-Daudé
From: Peter Maydell <peter.maydell@linaro.org>
omap1.c is very old code, and it contains numerous calls direct to
printf() for various error and information cases.
In this commit, convert the printf() calls that are for either guest
error or unimplemented functionality to qemu_log_mask() calls.
This leaves the printf() calls that are informative or which are
ifdeffed-out debug statements untouched.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20250227170117.1726895-2-peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/arm/omap1.c | 48 +++++++++++++++++++++++++++++++-----------------
1 file changed, 31 insertions(+), 17 deletions(-)
diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
index ca2eb0d1576..3c0ce5e0979 100644
--- a/hw/arm/omap1.c
+++ b/hw/arm/omap1.c
@@ -2559,8 +2559,9 @@ static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
static void omap_rtc_alarm_update(struct omap_rtc_s *s)
{
s->alarm_ti = mktimegm(&s->alarm_tm);
- if (s->alarm_ti == -1)
- printf("%s: conversion failed\n", __func__);
+ if (s->alarm_ti == -1) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: conversion failed\n", __func__);
+ }
}
static uint64_t omap_rtc_read(void *opaque, hwaddr addr, unsigned size)
@@ -3024,8 +3025,9 @@ static void omap_mcbsp_source_tick(void *opaque)
if (!s->rx_rate)
return;
- if (s->rx_req)
- printf("%s: Rx FIFO overrun\n", __func__);
+ if (s->rx_req) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Rx FIFO overrun\n", __func__);
+ }
s->rx_req = s->rx_rate << bps[(s->rcr[0] >> 5) & 7];
@@ -3070,8 +3072,9 @@ static void omap_mcbsp_sink_tick(void *opaque)
if (!s->tx_rate)
return;
- if (s->tx_req)
- printf("%s: Tx FIFO underrun\n", __func__);
+ if (s->tx_req) {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Tx FIFO underrun\n", __func__);
+ }
s->tx_req = s->tx_rate << bps[(s->xcr[0] >> 5) & 7];
@@ -3173,7 +3176,7 @@ static uint64_t omap_mcbsp_read(void *opaque, hwaddr addr,
/* Fall through. */
case 0x02: /* DRR1 */
if (s->rx_req < 2) {
- printf("%s: Rx FIFO underrun\n", __func__);
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Rx FIFO underrun\n", __func__);
omap_mcbsp_rx_done(s);
} else {
s->tx_req -= 2;
@@ -3278,8 +3281,9 @@ static void omap_mcbsp_writeh(void *opaque, hwaddr addr,
}
if (s->tx_req < 2)
omap_mcbsp_tx_done(s);
- } else
- printf("%s: Tx FIFO overrun\n", __func__);
+ } else {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Tx FIFO overrun\n", __func__);
+ }
return;
case 0x08: /* SPCR2 */
@@ -3293,8 +3297,11 @@ static void omap_mcbsp_writeh(void *opaque, hwaddr addr,
case 0x0a: /* SPCR1 */
s->spcr[0] &= 0x0006;
s->spcr[0] |= 0xf8f9 & value;
- if (value & (1 << 15)) /* DLB */
- printf("%s: Digital Loopback mode enable attempt\n", __func__);
+ if (value & (1 << 15)) { /* DLB */
+ qemu_log_mask(LOG_UNIMP,
+ "%s: Digital Loopback mode enable attempt\n",
+ __func__);
+ }
if (~value & 1) { /* RRST */
s->spcr[0] &= ~6;
s->rx_req = 0;
@@ -3325,13 +3332,19 @@ static void omap_mcbsp_writeh(void *opaque, hwaddr addr,
return;
case 0x18: /* MCR2 */
s->mcr[1] = value & 0x03e3;
- if (value & 3) /* XMCM */
- printf("%s: Tx channel selection mode enable attempt\n", __func__);
+ if (value & 3) { /* XMCM */
+ qemu_log_mask(LOG_UNIMP,
+ "%s: Tx channel selection mode enable attempt\n",
+ __func__);
+ }
return;
case 0x1a: /* MCR1 */
s->mcr[0] = value & 0x03e1;
- if (value & 1) /* RMCM */
- printf("%s: Rx channel selection mode enable attempt\n", __func__);
+ if (value & 1) { /* RMCM */
+ qemu_log_mask(LOG_UNIMP,
+ "%s: Rx channel selection mode enable attempt\n",
+ __func__);
+ }
return;
case 0x1c: /* RCERA */
s->rcer[0] = value & 0xffff;
@@ -3412,8 +3425,9 @@ static void omap_mcbsp_writew(void *opaque, hwaddr addr,
}
if (s->tx_req < 4)
omap_mcbsp_tx_done(s);
- } else
- printf("%s: Tx FIFO overrun\n", __func__);
+ } else {
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Tx FIFO overrun\n", __func__);
+ }
return;
}
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 34/41] hw/arm/omap1: Drop ALMDEBUG ifdeffed out code
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (32 preceding siblings ...)
2025-03-05 1:21 ` [PULL 33/41] hw/arm/omap1: Convert raw printfs to qemu_log_mask() Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 35/41] hw/arm/omap1: Convert information printfs to tracepoints Philippe Mathieu-Daudé
` (6 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Richard Henderson, Philippe Mathieu-Daudé
From: Peter Maydell <peter.maydell@linaro.org>
In omap1.c, there are some debug printfs in the omap_rtc_write()
function that are guardad by ifdef ALMDEBUG. ALMDEBUG is never
set, so this is all dead code.
It's not worth the effort of converting all of these to tracepoints;
a modern tracepoint approach would probably have a single tracepoint
covering all the register writes anyway. Just delete the printf()s.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20250227170117.1726895-3-peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/arm/omap1.c | 51 --------------------------------------------------
1 file changed, 51 deletions(-)
diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
index 3c0ce5e0979..8f5bb81c96a 100644
--- a/hw/arm/omap1.c
+++ b/hw/arm/omap1.c
@@ -2660,25 +2660,16 @@ static void omap_rtc_write(void *opaque, hwaddr addr,
switch (offset) {
case 0x00: /* SECONDS_REG */
-#ifdef ALMDEBUG
- printf("RTC SEC_REG <-- %02x\n", value);
-#endif
s->ti -= s->current_tm.tm_sec;
s->ti += from_bcd(value);
return;
case 0x04: /* MINUTES_REG */
-#ifdef ALMDEBUG
- printf("RTC MIN_REG <-- %02x\n", value);
-#endif
s->ti -= s->current_tm.tm_min * 60;
s->ti += from_bcd(value) * 60;
return;
case 0x08: /* HOURS_REG */
-#ifdef ALMDEBUG
- printf("RTC HRS_REG <-- %02x\n", value);
-#endif
s->ti -= s->current_tm.tm_hour * 3600;
if (s->pm_am) {
s->ti += (from_bcd(value & 0x3f) & 12) * 3600;
@@ -2688,17 +2679,11 @@ static void omap_rtc_write(void *opaque, hwaddr addr,
return;
case 0x0c: /* DAYS_REG */
-#ifdef ALMDEBUG
- printf("RTC DAY_REG <-- %02x\n", value);
-#endif
s->ti -= s->current_tm.tm_mday * 86400;
s->ti += from_bcd(value) * 86400;
return;
case 0x10: /* MONTHS_REG */
-#ifdef ALMDEBUG
- printf("RTC MTH_REG <-- %02x\n", value);
-#endif
memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
new_tm.tm_mon = from_bcd(value);
ti[0] = mktimegm(&s->current_tm);
@@ -2715,9 +2700,6 @@ static void omap_rtc_write(void *opaque, hwaddr addr,
return;
case 0x14: /* YEARS_REG */
-#ifdef ALMDEBUG
- printf("RTC YRS_REG <-- %02x\n", value);
-#endif
memcpy(&new_tm, &s->current_tm, sizeof(new_tm));
new_tm.tm_year += from_bcd(value) - (new_tm.tm_year % 100);
ti[0] = mktimegm(&s->current_tm);
@@ -2737,25 +2719,16 @@ static void omap_rtc_write(void *opaque, hwaddr addr,
return; /* Ignored */
case 0x20: /* ALARM_SECONDS_REG */
-#ifdef ALMDEBUG
- printf("ALM SEC_REG <-- %02x\n", value);
-#endif
s->alarm_tm.tm_sec = from_bcd(value);
omap_rtc_alarm_update(s);
return;
case 0x24: /* ALARM_MINUTES_REG */
-#ifdef ALMDEBUG
- printf("ALM MIN_REG <-- %02x\n", value);
-#endif
s->alarm_tm.tm_min = from_bcd(value);
omap_rtc_alarm_update(s);
return;
case 0x28: /* ALARM_HOURS_REG */
-#ifdef ALMDEBUG
- printf("ALM HRS_REG <-- %02x\n", value);
-#endif
if (s->pm_am)
s->alarm_tm.tm_hour =
((from_bcd(value & 0x3f)) % 12) +
@@ -2766,33 +2739,21 @@ static void omap_rtc_write(void *opaque, hwaddr addr,
return;
case 0x2c: /* ALARM_DAYS_REG */
-#ifdef ALMDEBUG
- printf("ALM DAY_REG <-- %02x\n", value);
-#endif
s->alarm_tm.tm_mday = from_bcd(value);
omap_rtc_alarm_update(s);
return;
case 0x30: /* ALARM_MONTHS_REG */
-#ifdef ALMDEBUG
- printf("ALM MON_REG <-- %02x\n", value);
-#endif
s->alarm_tm.tm_mon = from_bcd(value);
omap_rtc_alarm_update(s);
return;
case 0x34: /* ALARM_YEARS_REG */
-#ifdef ALMDEBUG
- printf("ALM YRS_REG <-- %02x\n", value);
-#endif
s->alarm_tm.tm_year = from_bcd(value);
omap_rtc_alarm_update(s);
return;
case 0x40: /* RTC_CTRL_REG */
-#ifdef ALMDEBUG
- printf("RTC CONTROL <-- %02x\n", value);
-#endif
s->pm_am = (value >> 3) & 1;
s->auto_comp = (value >> 2) & 1;
s->round = (value >> 1) & 1;
@@ -2802,32 +2763,20 @@ static void omap_rtc_write(void *opaque, hwaddr addr,
return;
case 0x44: /* RTC_STATUS_REG */
-#ifdef ALMDEBUG
- printf("RTC STATUSL <-- %02x\n", value);
-#endif
s->status &= ~((value & 0xc0) ^ 0x80);
omap_rtc_interrupts_update(s);
return;
case 0x48: /* RTC_INTERRUPTS_REG */
-#ifdef ALMDEBUG
- printf("RTC INTRS <-- %02x\n", value);
-#endif
s->interrupts = value;
return;
case 0x4c: /* RTC_COMP_LSB_REG */
-#ifdef ALMDEBUG
- printf("RTC COMPLSB <-- %02x\n", value);
-#endif
s->comp_reg &= 0xff00;
s->comp_reg |= 0x00ff & value;
return;
case 0x50: /* RTC_COMP_MSB_REG */
-#ifdef ALMDEBUG
- printf("RTC COMPMSB <-- %02x\n", value);
-#endif
s->comp_reg &= 0x00ff;
s->comp_reg |= 0xff00 & (value << 8);
return;
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 35/41] hw/arm/omap1: Convert information printfs to tracepoints
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (33 preceding siblings ...)
2025-03-05 1:21 ` [PULL 34/41] hw/arm/omap1: Drop ALMDEBUG ifdeffed out code Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 36/41] hw/arm/omap_sx1: Remove ifdeffed out debug printf Philippe Mathieu-Daudé
` (5 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Richard Henderson, Philippe Mathieu-Daudé
From: Peter Maydell <peter.maydell@linaro.org>
The omap1 code uses raw printf() statements to print information
about some events; convert these to tracepoints.
In particular, this will stop the functional test for the sx1
from printing the not-very-helpful note
"omap_clkm_write: clocking scheme set to synchronous scalable"
to the test's default.log.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20250227170117.1726895-4-peter.maydell@linaro.org>
[PMD: Include component name (pwl/pwt/lpg) in trace events]
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/arm/omap1.c | 26 ++++++++++++++------------
hw/arm/trace-events | 7 +++++++
2 files changed, 21 insertions(+), 12 deletions(-)
diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
index 8f5bb81c96a..3ee10b47770 100644
--- a/hw/arm/omap1.c
+++ b/hw/arm/omap1.c
@@ -42,6 +42,7 @@
#include "qemu/cutils.h"
#include "qemu/bcd.h"
#include "target/arm/cpu-qom.h"
+#include "trace.h"
static inline void omap_log_badwidth(const char *funcname, hwaddr addr, int sz)
{
@@ -1731,7 +1732,7 @@ static void omap_clkm_write(void *opaque, hwaddr addr,
case 0x18: /* ARM_SYSST */
if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) {
s->clkm.clocking_scheme = (value >> 11) & 7;
- printf("%s: clocking scheme set to %s\n", __func__,
+ trace_omap1_pwl_clocking_scheme(
clkschemename[s->clkm.clocking_scheme]);
}
s->clkm.cold_start &= value & 0x3f;
@@ -2335,7 +2336,7 @@ static void omap_pwl_update(struct omap_pwl_s *s)
if (output != s->output) {
s->output = output;
- printf("%s: Backlight now at %i/256\n", __func__, output);
+ trace_omap1_pwl_backlight(output);
}
}
@@ -2470,8 +2471,8 @@ static void omap_pwt_write(void *opaque, hwaddr addr,
break;
case 0x04: /* VRC */
if ((value ^ s->vrc) & 1) {
- if (value & 1)
- printf("%s: %iHz buzz on\n", __func__, (int)
+ if (value & 1) {
+ trace_omap1_pwt_buzz(
/* 1.5 MHz from a 12-MHz or 13-MHz PWT_CLK */
((omap_clk_getrate(s->clk) >> 3) /
/* Pre-multiplexer divider */
@@ -2487,8 +2488,9 @@ static void omap_pwt_write(void *opaque, hwaddr addr,
/* 80/127 divider */
((value & (1 << 5)) ? 80 : 127) /
(107 * 55 * 63 * 127)));
- else
- printf("%s: silence!\n", __func__);
+ } else {
+ trace_omap1_pwt_silence();
+ }
}
s->vrc = value & 0x7f;
break;
@@ -3494,7 +3496,7 @@ static void omap_lpg_tick(void *opaque)
timer_mod(s->tm, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->on);
s->cycle = !s->cycle;
- printf("%s: LED is %s\n", __func__, s->cycle ? "on" : "off");
+ trace_omap1_lpg_led(s->cycle ? "on" : "off");
}
static void omap_lpg_update(struct omap_lpg_s *s)
@@ -3514,11 +3516,11 @@ static void omap_lpg_update(struct omap_lpg_s *s)
}
timer_del(s->tm);
- if (on == period && s->on < s->period)
- printf("%s: LED is on\n", __func__);
- else if (on == 0 && s->on)
- printf("%s: LED is off\n", __func__);
- else if (on && (on != s->on || period != s->period)) {
+ if (on == period && s->on < s->period) {
+ trace_omap1_lpg_led("on");
+ } else if (on == 0 && s->on) {
+ trace_omap1_lpg_led("off");
+ } else if (on && (on != s->on || period != s->period)) {
s->cycle = 0;
s->on = on;
s->period = period;
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
index 7790db780e0..f49cae1656e 100644
--- a/hw/arm/trace-events
+++ b/hw/arm/trace-events
@@ -1,5 +1,12 @@
# See docs/devel/tracing.rst for syntax documentation.
+# omap1.c
+omap1_pwl_clocking_scheme(const char *scheme) "omap1 CLKM: clocking scheme set to %s"
+omap1_pwl_backlight(int output) "omap1 PWL: backlight now at %d/256"
+omap1_pwt_buzz(int freq) "omap1 PWT: %dHz buzz on"
+omap1_pwt_silence(void) "omap1 PWT: buzzer silenced"
+omap1_lpg_led(const char *onoff) "omap1 LPG: LED is %s"
+
# virt-acpi-build.c
virt_acpi_setup(void) "No fw cfg or ACPI disabled. Bailing out."
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 36/41] hw/arm/omap_sx1: Remove ifdeffed out debug printf
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (34 preceding siblings ...)
2025-03-05 1:21 ` [PULL 35/41] hw/arm/omap1: Convert information printfs to tracepoints Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 37/41] hw/arm/versatilepb: Convert printfs to LOG_GUEST_ERROR Philippe Mathieu-Daudé
` (4 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Richard Henderson, Philippe Mathieu-Daudé
From: Peter Maydell <peter.maydell@linaro.org>
Remove an ifdeffed out debug printf from the static_write() function in
omap_sx1.c. In theory we could turn this into a tracepoint, but for
code this old it doesn't seem worthwhile. We can add tracepoints if
and when we have a reason to debug something.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20250227170117.1726895-5-peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/arm/omap_sx1.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
index c6b0bed0796..24b40431832 100644
--- a/hw/arm/omap_sx1.c
+++ b/hw/arm/omap_sx1.c
@@ -76,10 +76,6 @@ static uint64_t static_read(void *opaque, hwaddr offset,
static void static_write(void *opaque, hwaddr offset,
uint64_t value, unsigned size)
{
-#ifdef SPY
- printf("%s: value %" PRIx64 " %u bytes written at 0x%x\n",
- __func__, value, size, (int)offset);
-#endif
}
static const MemoryRegionOps static_ops = {
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 37/41] hw/arm/versatilepb: Convert printfs to LOG_GUEST_ERROR
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (35 preceding siblings ...)
2025-03-05 1:21 ` [PULL 36/41] hw/arm/omap_sx1: Remove ifdeffed out debug printf Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 38/41] hw/nvram/eeprom_at24c: Use OBJECT_DECLARE_SIMPLE_TYPE Philippe Mathieu-Daudé
` (3 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Richard Henderson, Philippe Mathieu-Daudé
From: Peter Maydell <peter.maydell@linaro.org>
Convert some printf() calls for attempts to access nonexistent
registers into LOG_GUEST_ERROR logging.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20250227170117.1726895-6-peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/arm/versatilepb.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index 941616cd25b..35766445fa4 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -27,6 +27,7 @@
#include "qom/object.h"
#include "audio/audio.h"
#include "target/arm/cpu-qom.h"
+#include "qemu/log.h"
#define VERSATILE_FLASH_ADDR 0x34000000
#define VERSATILE_FLASH_SIZE (64 * 1024 * 1024)
@@ -110,7 +111,8 @@ static uint64_t vpb_sic_read(void *opaque, hwaddr offset,
case 8: /* PICENABLE */
return s->pic_enable;
default:
- printf ("vpb_sic_read: Bad register offset 0x%x\n", (int)offset);
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "vpb_sic_read: Bad register offset 0x%x\n", (int)offset);
return 0;
}
}
@@ -144,7 +146,8 @@ static void vpb_sic_write(void *opaque, hwaddr offset,
vpb_sic_update_pic(s);
break;
default:
- printf ("vpb_sic_write: Bad register offset 0x%x\n", (int)offset);
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "vpb_sic_write: Bad register offset 0x%x\n", (int)offset);
return;
}
vpb_sic_update(s);
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 38/41] hw/nvram/eeprom_at24c: Use OBJECT_DECLARE_SIMPLE_TYPE
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (36 preceding siblings ...)
2025-03-05 1:21 ` [PULL 37/41] hw/arm/versatilepb: Convert printfs to LOG_GUEST_ERROR Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 39/41] hw/nvram/eeprom_at24c: Remove ERR macro that calls fprintf to stderr Philippe Mathieu-Daudé
` (2 subsequent siblings)
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: BALATON Zoltan, Philippe Mathieu-Daudé
From: BALATON Zoltan <balaton@eik.bme.hu>
No need to open code it so use the simple object type declaration.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <08d9900af04789ede485942c8072eaa58bf52f80.1740839457.git.balaton@eik.bme.hu>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/nvram/eeprom_at24c.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index a40cc5dd15a..2ae03935d47 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -30,9 +30,7 @@
## __VA_ARGS__)
#define TYPE_AT24C_EE "at24c-eeprom"
-typedef struct EEPROMState EEPROMState;
-DECLARE_INSTANCE_CHECKER(EEPROMState, AT24C_EE,
- TYPE_AT24C_EE)
+OBJECT_DECLARE_SIMPLE_TYPE(EEPROMState, AT24C_EE)
struct EEPROMState {
I2CSlave parent_obj;
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 39/41] hw/nvram/eeprom_at24c: Remove ERR macro that calls fprintf to stderr
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (37 preceding siblings ...)
2025-03-05 1:21 ` [PULL 38/41] hw/nvram/eeprom_at24c: Use OBJECT_DECLARE_SIMPLE_TYPE Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 40/41] hw/nvram/eeprom_at24c: Remove memset after g_malloc0 Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 41/41] hw/nvram/eeprom_at24c: Reorganise init to avoid overwriting values Philippe Mathieu-Daudé
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: BALATON Zoltan, Philippe Mathieu-Daudé
From: BALATON Zoltan <balaton@eik.bme.hu>
In the realize method error_setg can be used like other places there
already do. The other usage can be replaced with error_report which is
the preferred way instead of directly printing to stderr.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <637b92984795a385b648a84208f093947cc261e4.1740839457.git.balaton@eik.bme.hu>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/nvram/eeprom_at24c.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index 2ae03935d47..9f606842eb6 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -10,6 +10,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
+#include "qemu/error-report.h"
#include "qemu/module.h"
#include "hw/i2c/i2c.h"
#include "hw/nvram/eeprom_at24c.h"
@@ -26,9 +27,6 @@
#define DPRINTK(FMT, ...) do {} while (0)
#endif
-#define ERR(FMT, ...) fprintf(stderr, TYPE_AT24C_EE " : " FMT, \
- ## __VA_ARGS__)
-
#define TYPE_AT24C_EE "at24c-eeprom"
OBJECT_DECLARE_SIMPLE_TYPE(EEPROMState, AT24C_EE)
@@ -75,8 +73,7 @@ int at24c_eeprom_event(I2CSlave *s, enum i2c_event event)
if (ee->blk && ee->changed) {
int ret = blk_pwrite(ee->blk, 0, ee->rsize, ee->mem, 0);
if (ret < 0) {
- ERR(TYPE_AT24C_EE
- " : failed to write backing file\n");
+ error_report("%s: failed to write backing file", __func__);
}
DPRINTK("Wrote to backing file\n");
}
@@ -203,8 +200,9 @@ static void at24c_eeprom_realize(DeviceState *dev, Error **errp)
int ret = blk_pread(ee->blk, 0, ee->rsize, ee->mem, 0);
if (ret < 0) {
- ERR(TYPE_AT24C_EE
- " : Failed initial sync with backing file\n");
+ error_setg(errp, "%s: Failed initial sync with backing file",
+ TYPE_AT24C_EE);
+ return;
}
DPRINTK("Reset read backing file\n");
}
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 40/41] hw/nvram/eeprom_at24c: Remove memset after g_malloc0
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (38 preceding siblings ...)
2025-03-05 1:21 ` [PULL 39/41] hw/nvram/eeprom_at24c: Remove ERR macro that calls fprintf to stderr Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
2025-03-05 1:21 ` [PULL 41/41] hw/nvram/eeprom_at24c: Reorganise init to avoid overwriting values Philippe Mathieu-Daudé
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: BALATON Zoltan, Philippe Mathieu-Daudé
From: BALATON Zoltan <balaton@eik.bme.hu>
Calling memset to zero memory is not needed after g_malloc0 which
already clears memory. These used to be in separate functions but
after some patches the memset ended up after g_malloc0 and thus can be
dropped.
Fixes: 4f2c6448c3 (hw/nvram/eeprom_at24c: Make reset behavior more like hardware)
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <ff281851e6d824ecd01b8b5cd955328dae1515a0.1740839457.git.balaton@eik.bme.hu>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/nvram/eeprom_at24c.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index 9f606842eb6..78c81bea77f 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -190,7 +190,6 @@ static void at24c_eeprom_realize(DeviceState *dev, Error **errp)
}
ee->mem = g_malloc0(ee->rsize);
- memset(ee->mem, 0, ee->rsize);
if (ee->init_rom) {
memcpy(ee->mem, ee->init_rom, MIN(ee->init_rom_size, ee->rsize));
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PULL 41/41] hw/nvram/eeprom_at24c: Reorganise init to avoid overwriting values
2025-03-05 1:21 [PULL 00/41] Misc HW patches for 2025-03-05 Philippe Mathieu-Daudé
` (39 preceding siblings ...)
2025-03-05 1:21 ` [PULL 40/41] hw/nvram/eeprom_at24c: Remove memset after g_malloc0 Philippe Mathieu-Daudé
@ 2025-03-05 1:21 ` Philippe Mathieu-Daudé
40 siblings, 0 replies; 45+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-03-05 1:21 UTC (permalink / raw)
To: qemu-devel; +Cc: BALATON Zoltan, Philippe Mathieu-Daudé
From: BALATON Zoltan <balaton@eik.bme.hu>
The init_rom[] can write values to the beginning of the memory but
these are overwritten by values from a backing file that covers the
whole memory.
init_rom[] is used only if there's no backing file (provides default
content) but should not overwrite backing file content (especially
leaving the file unchanged and only change it in memory).
Do the init_rom[] handling only if it would not be overwritten.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <fd8e0478febd60d5f48c58bc77c60e043d1c3cdc.1740839457.git.balaton@eik.bme.hu>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/nvram/eeprom_at24c.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c
index 78c81bea77f..ff7a21eee7f 100644
--- a/hw/nvram/eeprom_at24c.c
+++ b/hw/nvram/eeprom_at24c.c
@@ -191,10 +191,6 @@ static void at24c_eeprom_realize(DeviceState *dev, Error **errp)
ee->mem = g_malloc0(ee->rsize);
- if (ee->init_rom) {
- memcpy(ee->mem, ee->init_rom, MIN(ee->init_rom_size, ee->rsize));
- }
-
if (ee->blk) {
int ret = blk_pread(ee->blk, 0, ee->rsize, ee->mem, 0);
@@ -204,6 +200,8 @@ static void at24c_eeprom_realize(DeviceState *dev, Error **errp)
return;
}
DPRINTK("Reset read backing file\n");
+ } else if (ee->init_rom) {
+ memcpy(ee->mem, ee->init_rom, MIN(ee->init_rom_size, ee->rsize));
}
/*
--
2.47.1
^ permalink raw reply related [flat|nested] 45+ messages in thread