* [PATCH v2 0/4] RME-DA preparatory work
@ 2026-09-04 16:05 Jim MacArthur
2026-09-04 16:05 ` [PATCH v2 1/4] hw/pci: add IDE + TEE capability to PCIe root port Jim MacArthur
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Jim MacArthur @ 2026-09-04 16:05 UTC (permalink / raw)
To: qemu-devel
Cc: Michael S. Tsirkin, John Snow, Denis V. Lunev, qemu-block,
Jim MacArthur, Pierrick Bouvier, Viresh Kumar, Pierrick Bouvier
This is a subset of patches from Gustavo Romero's SMMU DA branch work,
featuring patches from Pierrick Bouvier and Viresh Kumar. These add
capabilities to the PCIe root port and ICH9 SATA driver, and also refactor
some code in hw/pci/msi.c for future use.
The goal here is to upstream work which is independent of Tao Tang's SMMU-V3
patches, while those are being reviewed. If/when Tao Tang's patches are
accepted, we can proceed with the remainder of the SMMU DA work.
I have spent some time understanding these patches and believe them to be
sensible, but some parts of them may be outside my understanding. In
particular, we may be incorrectly advertising features here which are not
actually implemented; although this doesn't cause any problems I can see
with Linux or our test suites, I can quite easily set the feature flags to
zero and keep the code structure if that's a problem.
Jim
Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
---
Changes in v2:
- Removed RFC tag, rebased to current master. No other changes.
- Link to v1: https://lore.kernel.org/qemu-devel/20260818-jmac-rme-da-prep-v1-0-30fab951bc75@linaro.org
---
Pierrick Bouvier (4):
hw/pci: add IDE + TEE capability to PCIe root port
sata: add SPDM + IDE + TEE pci support
hw/pci: add DVSEC RMEDA capability to PCIe root port
hw/pci/msi: extract msi_message_address_register
hw/ide/ich.c | 72 +++++++++++++++++++++++++++++++++++++-
hw/pci-bridge/gen_pcie_root_port.c | 38 ++++++++++++++++++++
hw/pci/msi.c | 19 ++++++----
hw/pci/pcie.c | 15 ++++++++
include/hw/pci/msi.h | 1 +
include/hw/pci/pcie.h | 3 ++
include/hw/pci/pcie_regs.h | 8 +++++
7 files changed, 149 insertions(+), 7 deletions(-)
---
base-commit: d2843fbf80260e4346c856819e8cea11768c9d0e
change-id: 20260818-jmac-rme-da-prep-8096fc816eee
Best regards,
--
Jim MacArthur <jim.macarthur@linaro.org>
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 1/4] hw/pci: add IDE + TEE capability to PCIe root port
2026-09-04 16:05 [PATCH v2 0/4] RME-DA preparatory work Jim MacArthur
@ 2026-09-04 16:05 ` Jim MacArthur
2026-09-04 21:12 ` Michael S. Tsirkin
2026-09-04 16:05 ` [PATCH v2 2/4] sata: add SPDM + IDE + TEE pci support Jim MacArthur
` (2 subsequent siblings)
3 siblings, 1 reply; 8+ messages in thread
From: Jim MacArthur @ 2026-09-04 16:05 UTC (permalink / raw)
To: qemu-devel
Cc: Michael S. Tsirkin, John Snow, Denis V. Lunev, qemu-block,
Jim MacArthur, Pierrick Bouvier, Pierrick Bouvier
From: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
---
hw/pci-bridge/gen_pcie_root_port.c | 8 ++++++++
hw/pci/pcie.c | 15 +++++++++++++++
include/hw/pci/pcie.h | 3 +++
include/hw/pci/pcie_regs.h | 4 ++++
4 files changed, 30 insertions(+)
diff --git a/hw/pci-bridge/gen_pcie_root_port.c b/hw/pci-bridge/gen_pcie_root_port.c
index 5434d693d9..452ebf69b3 100644
--- a/hw/pci-bridge/gen_pcie_root_port.c
+++ b/hw/pci-bridge/gen_pcie_root_port.c
@@ -26,6 +26,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(GenPCIERootPort, GEN_PCIE_ROOT_PORT)
#define GEN_PCIE_ROOT_PORT_AER_OFFSET 0x100
#define GEN_PCIE_ROOT_PORT_ACS_OFFSET \
(GEN_PCIE_ROOT_PORT_AER_OFFSET + PCI_ERR_SIZEOF)
+#define GEN_PCIE_ROOT_PORT_ACS_END \
+ (GEN_PCIE_ROOT_PORT_ACS_OFFSET + PCI_ACS_SIZEOF)
#define GEN_PCIE_ROOT_PORT_MSIX_NR_VECTOR 1
#define GEN_PCIE_ROOT_DEFAULT_IO_RANGE 4096
@@ -100,6 +102,12 @@ static void gen_rp_realize(DeviceState *dev, Error **errp)
d->wmask[PCI_IO_BASE] = 0;
d->wmask[PCI_IO_LIMIT] = 0;
}
+
+ uint32_t offset = GEN_PCIE_ROOT_PORT_ACS_END;
+ pcie_ide_init(d, offset);
+ offset += PCI_IDE_SIZEOF;
+
+ pcie_cap_tee_init(d);
}
static const VMStateDescription vmstate_rp_dev = {
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 4622c75e48..b9ead826ed 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -968,6 +968,12 @@ void pcie_cap_flr_write_config(PCIDevice *dev,
}
}
+void pcie_cap_tee_init(PCIDevice *dev)
+{
+ pci_long_test_and_set_mask(dev->config + dev->exp.exp_cap + PCI_EXP_DEVCAP,
+ PCI_EXP_DEVCAP_TEE);
+}
+
/* Alternative Routing-ID Interpretation (ARI)
* forwarding support for root and downstream ports
*/
@@ -1371,6 +1377,15 @@ uint32_t pcie_pri_get_req_alloc(const PCIDevice *dev)
return pci_get_long(dev->config + dev->exp.pri_cap + PCI_PRI_ALLOC_REQ);
}
+/* IDE */
+void pcie_ide_init(PCIDevice *dev, uint16_t offset)
+{
+ pcie_add_capability(dev, PCI_EXT_CAP_ID_IDE, PCI_IDE_VER,
+ offset, PCI_IDE_SIZEOF);
+ uint32_t cap = PCI_IDE_CAP_SELECTIVE;
+ pci_set_byte(dev->config + offset + PCI_IDE_CAP, cap);
+}
+
bool pcie_pri_enabled(const PCIDevice *dev)
{
if (!pci_is_express(dev) || !dev->exp.pri_cap) {
diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
index 71ba94874b..db66678252 100644
--- a/include/hw/pci/pcie.h
+++ b/include/hw/pci/pcie.h
@@ -123,6 +123,8 @@ void pcie_cap_flr_init(PCIDevice *dev);
void pcie_cap_flr_write_config(PCIDevice *dev,
uint32_t addr, uint32_t val, int len);
+void pcie_cap_tee_init(PCIDevice *dev);
+
/* ARI forwarding capability and control */
void pcie_cap_arifwd_init(PCIDevice *dev);
void pcie_cap_arifwd_reset(PCIDevice *dev);
@@ -161,6 +163,7 @@ void pcie_pasid_init(PCIDevice *dev, uint16_t offset, uint8_t pasid_width,
bool exec_perm, bool priv_mod);
void pcie_pri_init(PCIDevice *dev, uint16_t offset, uint32_t outstanding_pr_cap,
bool prg_response_pasid_req);
+void pcie_ide_init(PCIDevice *dev, uint16_t offset);
uint32_t pcie_pri_get_req_alloc(const PCIDevice *dev);
bool pcie_pri_enabled(const PCIDevice *dev);
diff --git a/include/hw/pci/pcie_regs.h b/include/hw/pci/pcie_regs.h
index 33a22229fe..aa21177411 100644
--- a/include/hw/pci/pcie_regs.h
+++ b/include/hw/pci/pcie_regs.h
@@ -182,4 +182,8 @@ typedef enum PCIExpLinkWidth {
#define PCI_DOE_VER 0x1
#define PCI_DOE_SIZEOF 24
+/* IDE */
+#define PCI_IDE_VER 0x1
+#define PCI_IDE_SIZEOF 12
+
#endif /* QEMU_PCIE_REGS_H */
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 2/4] sata: add SPDM + IDE + TEE pci support
2026-09-04 16:05 [PATCH v2 0/4] RME-DA preparatory work Jim MacArthur
2026-09-04 16:05 ` [PATCH v2 1/4] hw/pci: add IDE + TEE capability to PCIe root port Jim MacArthur
@ 2026-09-04 16:05 ` Jim MacArthur
2026-09-04 16:05 ` [PATCH v2 3/4] hw/pci: add DVSEC RMEDA capability to PCIe root port Jim MacArthur
2026-09-04 16:05 ` [PATCH v2 4/4] hw/pci/msi: extract msi_message_address_register Jim MacArthur
3 siblings, 0 replies; 8+ messages in thread
From: Jim MacArthur @ 2026-09-04 16:05 UTC (permalink / raw)
To: qemu-devel
Cc: Michael S. Tsirkin, John Snow, Denis V. Lunev, qemu-block,
Jim MacArthur, Pierrick Bouvier, Pierrick Bouvier
From: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Replaces the ICH9 config_write/config_read which versions which will use
DOE to write/read config if we have an SPDM port and DOE capability.
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
---
hw/ide/ich.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 71 insertions(+), 1 deletion(-)
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index b00987f08d..d2731598ea 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -70,6 +70,7 @@
#include "hw/ide/pci.h"
#include "hw/ide/ahci-pci.h"
#include "ahci-internal.h"
+#include "system/spdm-socket.h"
#define ICH9_MSI_CAP_OFFSET 0x80
#define ICH9_SATA_CAP_OFFSET 0xA8
@@ -90,6 +91,10 @@ static const VMStateDescription vmstate_ich9_ahci = {
},
};
+static const Property ich_props[] = {
+ DEFINE_PROP_UINT16("spdm_port", PCIDevice, spdm_port, 0),
+};
+
static void pci_ich9_ahci_update_irq(void *opaque, int irq_num, int level)
{
PCIDevice *pci_dev = opaque;
@@ -120,6 +125,27 @@ static void pci_ich9_ahci_init(Object *obj)
d->ahci.irq = &d->irq;
}
+static bool pcie_doe_spdm_rsp(DOECap *doe_cap)
+{
+ void *req = pcie_doe_get_write_mbox_ptr(doe_cap);
+ uint32_t req_len = pcie_doe_get_obj_len(req) * 4;
+ void *rsp = doe_cap->read_mbox;
+ uint32_t rsp_len = SPDM_SOCKET_MAX_MESSAGE_BUFFER_SIZE;
+
+ uint32_t recvd = spdm_socket_rsp(doe_cap->spdm_socket,
+ SPDM_SOCKET_TRANSPORT_TYPE_PCI_DOE,
+ req, req_len, rsp, rsp_len);
+ doe_cap->read_mbox_len += DIV_ROUND_UP(recvd, 4);
+
+ return recvd != 0;
+}
+
+static DOEProtocol doe_spdm_prot[] = {
+ { PCI_VENDOR_ID_PCI_SIG, PCI_SIG_DOE_CMA, pcie_doe_spdm_rsp },
+ { PCI_VENDOR_ID_PCI_SIG, PCI_SIG_DOE_SECURED_CMA, pcie_doe_spdm_rsp },
+ { }
+};
+
static void pci_ich9_ahci_realize(PCIDevice *dev, Error **errp)
{
AHCIPCIState *d;
@@ -145,6 +171,8 @@ static void pci_ich9_ahci_realize(PCIDevice *dev, Error **errp)
pci_register_bar(dev, ICH9_MEM_BAR, PCI_BASE_ADDRESS_SPACE_MEMORY,
&d->ahci.mem);
+ pcie_endpoint_cap_init(dev, 0xa8 + 0x8); /* right after SATA */
+
sata_cap_offset = pci_add_capability(dev, PCI_CAP_ID_SATA,
ICH9_SATA_CAP_OFFSET, SATA_CAP_SIZE,
errp);
@@ -165,6 +193,25 @@ static void pci_ich9_ahci_realize(PCIDevice *dev, Error **errp)
/* Any error other than -ENOTSUP(board's MSI support is broken)
* is a programming error. Fall back to INTx silently on -ENOTSUP */
assert(!ret || ret == -ENOTSUP);
+
+ uint16_t cap_offset = PCI_CONFIG_SPACE_SIZE;
+
+ if (dev->spdm_port) {
+ pcie_doe_init(dev, &dev->doe_spdm, cap_offset,
+ doe_spdm_prot, true, 0);
+ cap_offset += PCI_DOE_SIZEOF;
+
+ dev->doe_spdm.spdm_socket = spdm_socket_connect(dev->spdm_port,
+ errp);
+ assert(dev->doe_spdm.spdm_socket > 0);
+ }
+
+ /* ide */
+ pcie_ide_init(dev, cap_offset);
+ cap_offset += PCI_IDE_SIZEOF;
+
+ /* tee */
+ pcie_cap_tee_init(dev);
}
static void pci_ich9_uninit(PCIDevice *dev)
@@ -176,18 +223,41 @@ static void pci_ich9_uninit(PCIDevice *dev)
ahci_uninit(&d->ahci);
}
+static uint32_t ich_read_config(PCIDevice *dev, uint32_t address, int len)
+{
+ uint32_t val;
+ if (dev->spdm_port && pcie_find_capability(dev, PCI_EXT_CAP_ID_DOE)) {
+ if (pcie_doe_read_config(&dev->doe_spdm, address, len, &val)) {
+ return val;
+ }
+ }
+ return pci_default_read_config(dev, address, len);
+}
+
+static void ich_write_config(PCIDevice *dev, uint32_t address,
+ uint32_t val, int len)
+{
+ if (pcie_find_capability(dev, PCI_EXT_CAP_ID_DOE)) {
+ pcie_doe_write_config(&dev->doe_spdm, address, val, len);
+ }
+ pci_default_write_config(dev, address, val, len);
+}
+
static void ich_ahci_class_init(ObjectClass *klass, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
k->realize = pci_ich9_ahci_realize;
+ k->config_write = ich_write_config;
+ k->config_read = ich_read_config;
k->exit = pci_ich9_uninit;
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82801IR;
k->revision = 0x02;
k->class_id = PCI_CLASS_STORAGE_SATA;
dc->vmsd = &vmstate_ich9_ahci;
+ device_class_set_props(dc, ich_props);
device_class_set_legacy_reset(dc, pci_ich9_reset);
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
@@ -199,7 +269,7 @@ static const TypeInfo ich_ahci_info = {
.instance_init = pci_ich9_ahci_init,
.class_init = ich_ahci_class_init,
.interfaces = (const InterfaceInfo[]) {
- { INTERFACE_CONVENTIONAL_PCI_DEVICE },
+ { INTERFACE_PCIE_DEVICE },
{ },
},
};
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 3/4] hw/pci: add DVSEC RMEDA capability to PCIe root port
2026-09-04 16:05 [PATCH v2 0/4] RME-DA preparatory work Jim MacArthur
2026-09-04 16:05 ` [PATCH v2 1/4] hw/pci: add IDE + TEE capability to PCIe root port Jim MacArthur
2026-09-04 16:05 ` [PATCH v2 2/4] sata: add SPDM + IDE + TEE pci support Jim MacArthur
@ 2026-09-04 16:05 ` Jim MacArthur
2026-09-04 21:11 ` Michael S. Tsirkin
2026-09-04 16:05 ` [PATCH v2 4/4] hw/pci/msi: extract msi_message_address_register Jim MacArthur
3 siblings, 1 reply; 8+ messages in thread
From: Jim MacArthur @ 2026-09-04 16:05 UTC (permalink / raw)
To: qemu-devel
Cc: Michael S. Tsirkin, John Snow, Denis V. Lunev, qemu-block,
Jim MacArthur, Pierrick Bouvier, Viresh Kumar, Pierrick Bouvier
From: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
After this we can see all the capabilities listed for the PCIe bridge:
00:05.0 PCI bridge: Red Hat, Inc. QEMU PCIe Root port (prog-if 00 [Normal decode])
...
Capabilities: [54] Express (v2) Root Port (Slot+), IntMsgNum 0
...
Capabilities: [48] MSI-X: Enable+ Count=1 Masked-
Vector table: BAR=0 offset=00000000
PBA: BAR=0 offset=00000800
Capabilities: [40] Subsystem: Red Hat, Inc. Device 0000
Capabilities: [100 v2] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol- UncorrIntErr- BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr+
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr- CorrIntErr- HeaderOF-
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+ CorrIntErr+ HeaderOF+
AERCap: First Error Pointer: 00, ECRCGenCap+ ECRCGenEn- ECRCChkCap+ ECRCChkEn-
MultHdrRecCap+ MultHdrRecEn- TLPPfxPres- HdrLogCap-
HeaderLog: 00000000 00000000 00000000 00000000
RootCmd: CERptEn+ NFERptEn+ FERptEn+
RootSta: CERcvd- MultCERcvd- UERcvd- MultUERcvd-
FirstFatal- NonFatalMsg- FatalMsg- IntMsgNum 0
ErrorSrc: ERR_COR: 0000 ERR_FATAL/NONFATAL: 0000
Capabilities: [148 v1] Access Control Services
ACSCap: SrcValid+ TransBlk+ ReqRedir+ CmpltRedir+ UpstreamFwd+ EgressCtrl- DirectTrans+
ACSCtl: SrcValid+ TransBlk- ReqRedir+ CmpltRedir+ UpstreamFwd+ EgressCtrl- DirectTrans-
Capabilities: [150 v1] Designated Vendor-Specific: Vendor=13b5 ID=ff01 Rev=0 Len=16 <?>
Capabilities: [164 v1] Integrity & Data Encryption
IDECap: Lnk=0 Sel=1 FlowThru- PartHdr- Aggr- PCPC- IDE_KM- Alg='AES-GCM-256-96b' TCs=1 TeeLim-
IDECtl: FTEn-
[170]SelectiveIDE#0 Cap: RID#=0
[174]SelectiveIDE#0 Ctl: En- NPR- PR- CPL- PCRC- CFG- HdrEnc=no Alg='AES-GCM-256-96b' TC0 ID0
[178]SelectiveIDE#0 Sta: insecure RecvChkFail-
[17c]SelectiveIDE#0 RID: Valid- Base=0 Limit=0 SegBase=0
Kernel driver in use: pcieport
---
hw/pci-bridge/gen_pcie_root_port.c | 30 ++++++++++++++++++++++++++++++
include/hw/pci/pcie_regs.h | 4 ++++
2 files changed, 34 insertions(+)
diff --git a/hw/pci-bridge/gen_pcie_root_port.c b/hw/pci-bridge/gen_pcie_root_port.c
index 452ebf69b3..035212508d 100644
--- a/hw/pci-bridge/gen_pcie_root_port.c
+++ b/hw/pci-bridge/gen_pcie_root_port.c
@@ -104,6 +104,36 @@ static void gen_rp_realize(DeviceState *dev, Error **errp)
}
uint32_t offset = GEN_PCIE_ROOT_PORT_ACS_END;
+ /*
+ * dvsec rme-da
+ * https://developer.arm.com/documentation/den0129/latest/
+ * Arm RME System Architecture
+ * 0x0000 RMEDA_ECH See B3.2.6.2.1 RME-DA Extended Capability Header
+ * 0x0004 RMEDA_HEAD1 See B3.2.6.2.2 RME-DA DVSEC Header 1
+ * 0x0008 RMEDA_HEAD2 See B3.2.6.2.3 RME-DA DVSEC Header 2
+ * 0x000C RMEDA_CTL1 See B3.2.6.2.4 RME-DA Control register 1
+ * 0x0010 RMEDA_CTL2 See B3.2.6.2.5 RME-DA Control register 2
+ */
+ pcie_add_capability(d, PCI_EXT_CAP_ID_DVSEC, PCI_RMEDA_VER, offset,
+ PCI_RMEDA_SIZEOF);
+ const uint32_t header1 = 0x010013b5;
+ const uint32_t header2 = 0xFF01;
+ const uint32_t ctl1 = 0x1; /* support tdisp */
+ const uint32_t ctl2 = 0x0; /* unlocked */
+ pci_set_long(d->config + offset + 0x4, header1);
+ pci_set_long(d->config + offset + 0x8, header2);
+ pci_set_long(d->config + offset + 0xC, ctl1);
+ pci_set_long(d->config + offset + 0x10, ctl2);
+ d->wmask[offset + 0xC] = 0xff;
+ d->wmask[offset + 0xC + 1] = 0xff;
+ d->wmask[offset + 0xC + 2] = 0xff;
+ d->wmask[offset + 0xC + 3] = 0xff;
+ d->wmask[offset + 0x10] = 0xff;
+ d->wmask[offset + 0x10 + 1] = 0xff;
+ d->wmask[offset + 0x10 + 2] = 0xff;
+ d->wmask[offset + 0x10 + 3] = 0xff;
+ offset += PCI_RMEDA_SIZEOF;
+
pcie_ide_init(d, offset);
offset += PCI_IDE_SIZEOF;
diff --git a/include/hw/pci/pcie_regs.h b/include/hw/pci/pcie_regs.h
index aa21177411..233378fd79 100644
--- a/include/hw/pci/pcie_regs.h
+++ b/include/hw/pci/pcie_regs.h
@@ -186,4 +186,8 @@ typedef enum PCIExpLinkWidth {
#define PCI_IDE_VER 0x1
#define PCI_IDE_SIZEOF 12
+/* RME-DA */
+#define PCI_RMEDA_VER 0x1
+#define PCI_RMEDA_SIZEOF 20
+
#endif /* QEMU_PCIE_REGS_H */
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 4/4] hw/pci/msi: extract msi_message_address_register
2026-09-04 16:05 [PATCH v2 0/4] RME-DA preparatory work Jim MacArthur
` (2 preceding siblings ...)
2026-09-04 16:05 ` [PATCH v2 3/4] hw/pci: add DVSEC RMEDA capability to PCIe root port Jim MacArthur
@ 2026-09-04 16:05 ` Jim MacArthur
2026-09-04 16:14 ` Philippe Mathieu-Daudé
3 siblings, 1 reply; 8+ messages in thread
From: Jim MacArthur @ 2026-09-04 16:05 UTC (permalink / raw)
To: qemu-devel
Cc: Michael S. Tsirkin, John Snow, Denis V. Lunev, qemu-block,
Jim MacArthur, Pierrick Bouvier, Pierrick Bouvier
From: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
We need to access this address from smmu, to know if we are translating
an MSI.
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
---
hw/pci/msi.c | 19 +++++++++++++------
include/hw/pci/msi.h | 1 +
2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/hw/pci/msi.c b/hw/pci/msi.c
index b9f5b45920..7361776ace 100644
--- a/hw/pci/msi.c
+++ b/hw/pci/msi.c
@@ -137,6 +137,18 @@ void msi_set_message(PCIDevice *dev, MSIMessage msg)
pci_set_word(dev->config + msi_data_off(dev, msi64bit), msg.data);
}
+uint64_t msi_message_address_register(PCIDevice *dev)
+{
+ uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev));
+ bool msi64bit = flags & PCI_MSI_FLAGS_64BIT;
+
+ if (msi64bit) {
+ return pci_get_quad(dev->config + msi_address_lo_off(dev));
+ } else {
+ return pci_get_long(dev->config + msi_address_lo_off(dev));
+ }
+}
+
static MSIMessage msi_prepare_message(PCIDevice *dev, unsigned int vector)
{
uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev));
@@ -146,12 +158,7 @@ static MSIMessage msi_prepare_message(PCIDevice *dev, unsigned int vector)
assert(vector < nr_vectors);
- if (msi64bit) {
- msg.address = pci_get_quad(dev->config + msi_address_lo_off(dev));
- } else {
- msg.address = pci_get_long(dev->config + msi_address_lo_off(dev));
- }
-
+ msg.address = msi_message_address_register(dev);
/* upper bit 31:16 is zero */
msg.data = pci_get_word(dev->config + msi_data_off(dev, msi64bit));
if (nr_vectors > 1) {
diff --git a/include/hw/pci/msi.h b/include/hw/pci/msi.h
index abcfd13925..6f0e02c0fb 100644
--- a/include/hw/pci/msi.h
+++ b/include/hw/pci/msi.h
@@ -32,6 +32,7 @@ extern bool msi_nonbroken;
void msi_set_message(PCIDevice *dev, MSIMessage msg);
MSIMessage msi_get_message(PCIDevice *dev, unsigned int vector);
+uint64_t msi_message_address_register(PCIDevice *dev);
bool msi_enabled(const PCIDevice *dev);
void msi_set_enabled(PCIDevice *dev);
int msi_init(struct PCIDevice *dev, uint8_t offset,
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 4/4] hw/pci/msi: extract msi_message_address_register
2026-09-04 16:05 ` [PATCH v2 4/4] hw/pci/msi: extract msi_message_address_register Jim MacArthur
@ 2026-09-04 16:14 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-09-04 16:14 UTC (permalink / raw)
To: Jim MacArthur, qemu-devel
Cc: Michael S. Tsirkin, John Snow, Denis V. Lunev, qemu-block,
Pierrick Bouvier
Hi Jim,
On 4/9/26 18:05, Jim MacArthur wrote:
> From: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
>
> We need to access this address from smmu, to know if we are translating
> an MSI.
>
> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
> Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
> ---
> hw/pci/msi.c | 19 +++++++++++++------
> include/hw/pci/msi.h | 1 +
> 2 files changed, 14 insertions(+), 6 deletions(-)
>
> diff --git a/hw/pci/msi.c b/hw/pci/msi.c
> index b9f5b45920..7361776ace 100644
> --- a/hw/pci/msi.c
> +++ b/hw/pci/msi.c
> @@ -137,6 +137,18 @@ void msi_set_message(PCIDevice *dev, MSIMessage msg)
> pci_set_word(dev->config + msi_data_off(dev, msi64bit), msg.data);
> }
>
> +uint64_t msi_message_address_register(
const
> PCIDevice *dev)
> +{
> + uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev));
> + bool msi64bit = flags & PCI_MSI_FLAGS_64BIT;
> +
> + if (msi64bit) {
> + return pci_get_quad(dev->config + msi_address_lo_off(dev));
> + } else {
> + return pci_get_long(dev->config + msi_address_lo_off(dev));
> + }
> +}
> +
> static MSIMessage msi_prepare_message(PCIDevice *dev, unsigned int vector)
> {
> uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev));
> @@ -146,12 +158,7 @@ static MSIMessage msi_prepare_message(PCIDevice *dev, unsigned int vector)
>
> assert(vector < nr_vectors);
>
> - if (msi64bit) {
> - msg.address = pci_get_quad(dev->config + msi_address_lo_off(dev));
> - } else {
> - msg.address = pci_get_long(dev->config + msi_address_lo_off(dev));
> - }
> -
> + msg.address = msi_message_address_register(dev);
> /* upper bit 31:16 is zero */
> msg.data = pci_get_word(dev->config + msi_data_off(dev, msi64bit));
> if (nr_vectors > 1) {
> diff --git a/include/hw/pci/msi.h b/include/hw/pci/msi.h
> index abcfd13925..6f0e02c0fb 100644
> --- a/include/hw/pci/msi.h
> +++ b/include/hw/pci/msi.h
> @@ -32,6 +32,7 @@ extern bool msi_nonbroken;
>
> void msi_set_message(PCIDevice *dev, MSIMessage msg);
> MSIMessage msi_get_message(PCIDevice *dev, unsigned int vector);
> +uint64_t msi_message_address_register(PCIDevice *dev);
While this file lacks documentation, it would be good to start adding
some for new methods ;)
With doc+const:
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 3/4] hw/pci: add DVSEC RMEDA capability to PCIe root port
2026-09-04 16:05 ` [PATCH v2 3/4] hw/pci: add DVSEC RMEDA capability to PCIe root port Jim MacArthur
@ 2026-09-04 21:11 ` Michael S. Tsirkin
0 siblings, 0 replies; 8+ messages in thread
From: Michael S. Tsirkin @ 2026-09-04 21:11 UTC (permalink / raw)
To: Jim MacArthur
Cc: qemu-devel, John Snow, Denis V. Lunev, qemu-block,
Pierrick Bouvier, Viresh Kumar
On Fri, Sep 04, 2026 at 05:05:03PM +0100, Jim MacArthur wrote:
> From: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
>
> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
>
> After this we can see all the capabilities listed for the PCIe bridge:
>
> 00:05.0 PCI bridge: Red Hat, Inc. QEMU PCIe Root port (prog-if 00 [Normal decode])
>
> ...
>
> Capabilities: [54] Express (v2) Root Port (Slot+), IntMsgNum 0
>
> ...
>
> Capabilities: [48] MSI-X: Enable+ Count=1 Masked-
> Vector table: BAR=0 offset=00000000
> PBA: BAR=0 offset=00000800
> Capabilities: [40] Subsystem: Red Hat, Inc. Device 0000
> Capabilities: [100 v2] Advanced Error Reporting
> UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
> ECRC- UnsupReq- ACSViol- UncorrIntErr- BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
> PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
> UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP-
> ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr+
> PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
> UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+
> ECRC- UnsupReq- ACSViol- UncorrIntErr+ BlockedTLP- AtomicOpBlocked- TLPBlockedErr-
> PoisonTLPBlocked- DMWrReqBlocked- IDECheck- MisIDETLP- PCRC_CHECK- TLPXlatBlocked-
> CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr- CorrIntErr- HeaderOF-
> CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+ CorrIntErr+ HeaderOF+
> AERCap: First Error Pointer: 00, ECRCGenCap+ ECRCGenEn- ECRCChkCap+ ECRCChkEn-
> MultHdrRecCap+ MultHdrRecEn- TLPPfxPres- HdrLogCap-
> HeaderLog: 00000000 00000000 00000000 00000000
> RootCmd: CERptEn+ NFERptEn+ FERptEn+
> RootSta: CERcvd- MultCERcvd- UERcvd- MultUERcvd-
> FirstFatal- NonFatalMsg- FatalMsg- IntMsgNum 0
> ErrorSrc: ERR_COR: 0000 ERR_FATAL/NONFATAL: 0000
> Capabilities: [148 v1] Access Control Services
> ACSCap: SrcValid+ TransBlk+ ReqRedir+ CmpltRedir+ UpstreamFwd+ EgressCtrl- DirectTrans+
> ACSCtl: SrcValid+ TransBlk- ReqRedir+ CmpltRedir+ UpstreamFwd+ EgressCtrl- DirectTrans-
> Capabilities: [150 v1] Designated Vendor-Specific: Vendor=13b5 ID=ff01 Rev=0 Len=16 <?>
> Capabilities: [164 v1] Integrity & Data Encryption
> IDECap: Lnk=0 Sel=1 FlowThru- PartHdr- Aggr- PCPC- IDE_KM- Alg='AES-GCM-256-96b' TCs=1 TeeLim-
> IDECtl: FTEn-
> [170]SelectiveIDE#0 Cap: RID#=0
> [174]SelectiveIDE#0 Ctl: En- NPR- PR- CPL- PCRC- CFG- HdrEnc=no Alg='AES-GCM-256-96b' TC0 ID0
> [178]SelectiveIDE#0 Sta: insecure RecvChkFail-
> [17c]SelectiveIDE#0 RID: Valid- Base=0 Limit=0 SegBase=0
> Kernel driver in use: pcieport
> ---
> hw/pci-bridge/gen_pcie_root_port.c | 30 ++++++++++++++++++++++++++++++
> include/hw/pci/pcie_regs.h | 4 ++++
> 2 files changed, 34 insertions(+)
>
> diff --git a/hw/pci-bridge/gen_pcie_root_port.c b/hw/pci-bridge/gen_pcie_root_port.c
> index 452ebf69b3..035212508d 100644
> --- a/hw/pci-bridge/gen_pcie_root_port.c
> +++ b/hw/pci-bridge/gen_pcie_root_port.c
> @@ -104,6 +104,36 @@ static void gen_rp_realize(DeviceState *dev, Error **errp)
> }
>
> uint32_t offset = GEN_PCIE_ROOT_PORT_ACS_END;
> + /*
> + * dvsec rme-da
> + * https://developer.arm.com/documentation/den0129/latest/
> + * Arm RME System Architecture
> + * 0x0000 RMEDA_ECH See B3.2.6.2.1 RME-DA Extended Capability Header
> + * 0x0004 RMEDA_HEAD1 See B3.2.6.2.2 RME-DA DVSEC Header 1
> + * 0x0008 RMEDA_HEAD2 See B3.2.6.2.3 RME-DA DVSEC Header 2
> + * 0x000C RMEDA_CTL1 See B3.2.6.2.4 RME-DA Control register 1
> + * 0x0010 RMEDA_CTL2 See B3.2.6.2.5 RME-DA Control register 2
> + */
> + pcie_add_capability(d, PCI_EXT_CAP_ID_DVSEC, PCI_RMEDA_VER, offset,
> + PCI_RMEDA_SIZEOF);
don't put declarations after code.
> + const uint32_t header1 = 0x010013b5;
> + const uint32_t header2 = 0xFF01;
what are these things?
> + const uint32_t ctl1 = 0x1; /* support tdisp */
> + const uint32_t ctl2 = 0x0; /* unlocked */
so why do we need these vars? just open-code.
> + pci_set_long(d->config + offset + 0x4, header1);
> + pci_set_long(d->config + offset + 0x8, header2);
> + pci_set_long(d->config + offset + 0xC, ctl1);
> + pci_set_long(d->config + offset + 0x10, ctl2);
> + d->wmask[offset + 0xC] = 0xff;
> + d->wmask[offset + 0xC + 1] = 0xff;
> + d->wmask[offset + 0xC + 2] = 0xff;
> + d->wmask[offset + 0xC + 3] = 0xff;
> + d->wmask[offset + 0x10] = 0xff;
> + d->wmask[offset + 0x10 + 1] = 0xff;
> + d->wmask[offset + 0x10 + 2] = 0xff;
> + d->wmask[offset + 0x10 + 3] = 0xff;
> + offset += PCI_RMEDA_SIZEOF;
> +
> pcie_ide_init(d, offset);
> offset += PCI_IDE_SIZEOF;
You can't unconditionally change config space, this will break
cross version migration.
You must use a property (beginning with "x-") and compat machinery.
Besides, having all root ports on all arches have this capability
looks very strange. For example not everything supports tdisp.
> diff --git a/include/hw/pci/pcie_regs.h b/include/hw/pci/pcie_regs.h
> index aa21177411..233378fd79 100644
> --- a/include/hw/pci/pcie_regs.h
> +++ b/include/hw/pci/pcie_regs.h
> @@ -186,4 +186,8 @@ typedef enum PCIExpLinkWidth {
> #define PCI_IDE_VER 0x1
> #define PCI_IDE_SIZEOF 12
>
> +/* RME-DA */
> +#define PCI_RMEDA_VER 0x1
> +#define PCI_RMEDA_SIZEOF 20
> +
> #endif /* QEMU_PCIE_REGS_H */
>
> --
> 2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/4] hw/pci: add IDE + TEE capability to PCIe root port
2026-09-04 16:05 ` [PATCH v2 1/4] hw/pci: add IDE + TEE capability to PCIe root port Jim MacArthur
@ 2026-09-04 21:12 ` Michael S. Tsirkin
0 siblings, 0 replies; 8+ messages in thread
From: Michael S. Tsirkin @ 2026-09-04 21:12 UTC (permalink / raw)
To: Jim MacArthur
Cc: qemu-devel, John Snow, Denis V. Lunev, qemu-block,
Pierrick Bouvier
On Fri, Sep 04, 2026 at 05:05:01PM +0100, Jim MacArthur wrote:
> From: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
>
Please include a commit log explaining the motivation,
alternatives and result.
A possible format:
Currently .... as a result .... we can not .... because ....
To fix ... and then ...
> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
> Signed-off-by: Jim MacArthur <jim.macarthur@linaro.org>
> ---
> hw/pci-bridge/gen_pcie_root_port.c | 8 ++++++++
> hw/pci/pcie.c | 15 +++++++++++++++
> include/hw/pci/pcie.h | 3 +++
> include/hw/pci/pcie_regs.h | 4 ++++
> 4 files changed, 30 insertions(+)
>
> diff --git a/hw/pci-bridge/gen_pcie_root_port.c b/hw/pci-bridge/gen_pcie_root_port.c
> index 5434d693d9..452ebf69b3 100644
> --- a/hw/pci-bridge/gen_pcie_root_port.c
> +++ b/hw/pci-bridge/gen_pcie_root_port.c
> @@ -26,6 +26,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(GenPCIERootPort, GEN_PCIE_ROOT_PORT)
> #define GEN_PCIE_ROOT_PORT_AER_OFFSET 0x100
> #define GEN_PCIE_ROOT_PORT_ACS_OFFSET \
> (GEN_PCIE_ROOT_PORT_AER_OFFSET + PCI_ERR_SIZEOF)
> +#define GEN_PCIE_ROOT_PORT_ACS_END \
> + (GEN_PCIE_ROOT_PORT_ACS_OFFSET + PCI_ACS_SIZEOF)
>
> #define GEN_PCIE_ROOT_PORT_MSIX_NR_VECTOR 1
> #define GEN_PCIE_ROOT_DEFAULT_IO_RANGE 4096
> @@ -100,6 +102,12 @@ static void gen_rp_realize(DeviceState *dev, Error **errp)
> d->wmask[PCI_IO_BASE] = 0;
> d->wmask[PCI_IO_LIMIT] = 0;
> }
> +
> + uint32_t offset = GEN_PCIE_ROOT_PORT_ACS_END;
> + pcie_ide_init(d, offset);
> + offset += PCI_IDE_SIZEOF;
> +
> + pcie_cap_tee_init(d);
> }
>
> static const VMStateDescription vmstate_rp_dev = {
> diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
> index 4622c75e48..b9ead826ed 100644
> --- a/hw/pci/pcie.c
> +++ b/hw/pci/pcie.c
> @@ -968,6 +968,12 @@ void pcie_cap_flr_write_config(PCIDevice *dev,
> }
> }
>
> +void pcie_cap_tee_init(PCIDevice *dev)
> +{
> + pci_long_test_and_set_mask(dev->config + dev->exp.exp_cap + PCI_EXP_DEVCAP,
> + PCI_EXP_DEVCAP_TEE);
> +}
> +
> /* Alternative Routing-ID Interpretation (ARI)
> * forwarding support for root and downstream ports
> */
> @@ -1371,6 +1377,15 @@ uint32_t pcie_pri_get_req_alloc(const PCIDevice *dev)
> return pci_get_long(dev->config + dev->exp.pri_cap + PCI_PRI_ALLOC_REQ);
> }
>
> +/* IDE */
> +void pcie_ide_init(PCIDevice *dev, uint16_t offset)
> +{
> + pcie_add_capability(dev, PCI_EXT_CAP_ID_IDE, PCI_IDE_VER,
> + offset, PCI_IDE_SIZEOF);
> + uint32_t cap = PCI_IDE_CAP_SELECTIVE;
> + pci_set_byte(dev->config + offset + PCI_IDE_CAP, cap);
> +}
> +
> bool pcie_pri_enabled(const PCIDevice *dev)
> {
> if (!pci_is_express(dev) || !dev->exp.pri_cap) {
> diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
> index 71ba94874b..db66678252 100644
> --- a/include/hw/pci/pcie.h
> +++ b/include/hw/pci/pcie.h
> @@ -123,6 +123,8 @@ void pcie_cap_flr_init(PCIDevice *dev);
> void pcie_cap_flr_write_config(PCIDevice *dev,
> uint32_t addr, uint32_t val, int len);
>
> +void pcie_cap_tee_init(PCIDevice *dev);
> +
> /* ARI forwarding capability and control */
> void pcie_cap_arifwd_init(PCIDevice *dev);
> void pcie_cap_arifwd_reset(PCIDevice *dev);
> @@ -161,6 +163,7 @@ void pcie_pasid_init(PCIDevice *dev, uint16_t offset, uint8_t pasid_width,
> bool exec_perm, bool priv_mod);
> void pcie_pri_init(PCIDevice *dev, uint16_t offset, uint32_t outstanding_pr_cap,
> bool prg_response_pasid_req);
> +void pcie_ide_init(PCIDevice *dev, uint16_t offset);
>
> uint32_t pcie_pri_get_req_alloc(const PCIDevice *dev);
> bool pcie_pri_enabled(const PCIDevice *dev);
> diff --git a/include/hw/pci/pcie_regs.h b/include/hw/pci/pcie_regs.h
> index 33a22229fe..aa21177411 100644
> --- a/include/hw/pci/pcie_regs.h
> +++ b/include/hw/pci/pcie_regs.h
> @@ -182,4 +182,8 @@ typedef enum PCIExpLinkWidth {
> #define PCI_DOE_VER 0x1
> #define PCI_DOE_SIZEOF 24
>
> +/* IDE */
> +#define PCI_IDE_VER 0x1
> +#define PCI_IDE_SIZEOF 12
> +
> #endif /* QEMU_PCIE_REGS_H */
>
> --
> 2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-09-04 21:13 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-04 16:05 [PATCH v2 0/4] RME-DA preparatory work Jim MacArthur
2026-09-04 16:05 ` [PATCH v2 1/4] hw/pci: add IDE + TEE capability to PCIe root port Jim MacArthur
2026-09-04 21:12 ` Michael S. Tsirkin
2026-09-04 16:05 ` [PATCH v2 2/4] sata: add SPDM + IDE + TEE pci support Jim MacArthur
2026-09-04 16:05 ` [PATCH v2 3/4] hw/pci: add DVSEC RMEDA capability to PCIe root port Jim MacArthur
2026-09-04 21:11 ` Michael S. Tsirkin
2026-09-04 16:05 ` [PATCH v2 4/4] hw/pci/msi: extract msi_message_address_register Jim MacArthur
2026-09-04 16:14 ` Philippe Mathieu-Daudé
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.