HDM decoder programming and CDAT table ingestion are two
debugging-prone paths in the CXL stack: the former drives
address-decoding behaviour, the latter is parsed before any guest
interaction so wrong inputs surface late.
Add four trace points:
* cxl_hdm_decoder_write - guest write to a decoder CTRL register,
capturing the raw value and whether a
commit is being requested
* cxl_hdm_decoder_commit - actual commit, with the resolved base,
size, IW and IG fields
* cxl_cdat_init - CDAT initialisation, distinguishing the
file-backed vs built-in source
* cxl_cdat_loaded - successful file load with size and
number of entries parsed
The hw/mem/cxl_type3.c trace points are declared in the existing
hw/mem/trace-events. The cxl_ prefix keeps the namespace unified for
filtering with -trace 'cxl_*'.
Signed-off-by: Junjie Cao <[email protected]>
---
hw/cxl/cxl-cdat.c | 3 +++
hw/cxl/trace-events | 4 ++++
hw/mem/cxl_type3.c | 17 ++++++++++++++++-
hw/mem/trace-events | 4 ++++
4 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/hw/cxl/cxl-cdat.c b/hw/cxl/cxl-cdat.c
index 959a55518e..5274ac8c12 100644
--- a/hw/cxl/cxl-cdat.c
+++ b/hw/cxl/cxl-cdat.c
@@ -12,6 +12,7 @@
#include "hw/cxl/cxl.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
+#include "trace.h"
static void cdat_len_check(CDATSubHeader *hdr, Error **errp)
{
@@ -186,6 +187,7 @@ static bool ct3_load_cdat(CDATObject *cdat, Error **errp)
cdat->entry_len = num_ent;
cdat->entry = g_steal_pointer(&cdat_st);
cdat->buf = g_steal_pointer(&buf);
+ trace_cxl_cdat_loaded(cdat->filename, file_size, num_ent);
return true;
}
@@ -193,6 +195,7 @@ bool cxl_doe_cdat_init(CXLComponentState *cxl_cstate, Error
**errp)
{
CDATObject *cdat = &cxl_cstate->cdat;
+ trace_cxl_cdat_init(cdat->filename ?: "<built-in>");
if (cdat->filename) {
return ct3_load_cdat(cdat, errp);
} else {
diff --git a/hw/cxl/trace-events b/hw/cxl/trace-events
index abca116ed3..15977dce6e 100644
--- a/hw/cxl/trace-events
+++ b/hw/cxl/trace-events
@@ -6,3 +6,7 @@
cxl_mailbox_command(uint16_t opcode, size_t len_in) "opcode=0x%04x len_in=%zu"
cxl_mailbox_invalid_payload(uint16_t opcode, size_t len_in, size_t expected)
"opcode=0x%04x len_in=%zu expected=%zu"
cxl_mailbox_handler_return(uint16_t opcode, int ret, size_t len_out)
"opcode=0x%04x ret=%d len_out=%zu"
+
+# cxl-cdat.c
+cxl_cdat_init(const char *source) "source=%s"
+cxl_cdat_loaded(const char *filename, size_t length, int num_entries)
"filename=%s length=%zu entries=%d"
diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
index 4739239da3..8130abeb37 100644
--- a/hw/mem/cxl_type3.c
+++ b/hw/mem/cxl_type3.c
@@ -30,6 +30,7 @@
#include "system/numa.h"
#include "hw/cxl/cxl.h"
#include "hw/pci/msix.h"
+#include "trace.h"
/* type3 device private */
enum CXL_T3_MSIX_VECTOR {
@@ -419,9 +420,20 @@ static void hdm_decoder_commit(CXLType3Dev *ct3d, int
which)
int hdm_inc = R_CXL_HDM_DECODER1_BASE_LO - R_CXL_HDM_DECODER0_BASE_LO;
ComponentRegisters *cregs = &ct3d->cxl_cstate.crb;
uint32_t *cache_mem = cregs->cache_mem_registers;
- uint32_t ctrl;
+ uint32_t ctrl, low, high;
+ uint64_t base, size;
ctrl = ldl_le_p(cache_mem + R_CXL_HDM_DECODER0_CTRL + which * hdm_inc);
+ low = ldl_le_p(cache_mem + R_CXL_HDM_DECODER0_BASE_LO + which * hdm_inc);
+ high = ldl_le_p(cache_mem + R_CXL_HDM_DECODER0_BASE_HI + which * hdm_inc);
+ base = (low & 0xf0000000) | ((uint64_t)high << 32);
+ low = ldl_le_p(cache_mem + R_CXL_HDM_DECODER0_SIZE_LO + which * hdm_inc);
+ high = ldl_le_p(cache_mem + R_CXL_HDM_DECODER0_SIZE_HI + which * hdm_inc);
+ size = (low & 0xf0000000) | ((uint64_t)high << 32);
+ trace_cxl_hdm_decoder_commit(which, base, size,
+ FIELD_EX32(ctrl, CXL_HDM_DECODER0_CTRL, IW),
+ FIELD_EX32(ctrl, CXL_HDM_DECODER0_CTRL, IG));
+
/* TODO: Sanity checks that the decoder is possible */
ctrl = FIELD_DP32(ctrl, CXL_HDM_DECODER0_CTRL, ERR, 0);
ctrl = FIELD_DP32(ctrl, CXL_HDM_DECODER0_CTRL, COMMITTED, 1);
@@ -623,6 +635,9 @@ static void ct3d_reg_write(void *opaque, hwaddr offset,
uint64_t value,
}
stl_le_p((uint8_t *)cache_mem + offset, value);
+ if (which_hdm >= 0) {
+ trace_cxl_hdm_decoder_write(which_hdm, value, should_commit);
+ }
if (should_commit) {
hdm_decoder_commit(ct3d, which_hdm);
} else if (should_uncommit) {
diff --git a/hw/mem/trace-events b/hw/mem/trace-events
index 8b6b02b5bf..770831f701 100644
--- a/hw/mem/trace-events
+++ b/hw/mem/trace-events
@@ -6,3 +6,7 @@ mhp_pc_dimm_assigned_slot(int slot) "%d"
memory_device_pre_plug(const char *id, uint64_t addr) "id=%s addr=0x%"PRIx64
memory_device_plug(const char *id, uint64_t addr) "id=%s addr=0x%"PRIx64
memory_device_unplug(const char *id, uint64_t addr) "id=%s addr=0x%"PRIx64
+
+# cxl_type3.c
+cxl_hdm_decoder_write(int which, uint32_t value, bool commit) "decoder=%d
ctrl=0x%08x commit=%d"
+cxl_hdm_decoder_commit(int which, uint64_t base, uint64_t size, uint32_t
iw_enc, uint32_t ig_enc) "decoder=%d base=0x%"PRIx64" size=0x%"PRIx64"
iw_enc=0x%x ig_enc=0x%x"
--
2.43.0