From: Shiju Jose <shiju.jose@huawei.com>
CXL spec rev3.2 section 8.2.10.2.1.2 Table 8-58, DRAM event record
has updated with following new fields.
1. Component Identifier
2. Sub-channel of the memory event location
3. Advanced Programmable Corrected Memory Error Threshold Event Flags
4. Corrected Volatile Memory Error Count at Event
5. Memory Event Sub-Type
Add updates for the above spec changes in the CXL DRAM event
reporting and QMP command to inject DRAM event.
Signed-off-by: Shiju Jose <shiju.jose@huawei.com>
---
hw/mem/cxl_type3.c | 42 +++++++++++++++++++++++++++++++++++++
hw/mem/cxl_type3_stubs.c | 7 +++++++
include/hw/cxl/cxl_events.h | 9 ++++++--
qapi/cxl.json | 21 ++++++++++++++++++-
4 files changed, 76 insertions(+), 3 deletions(-)
diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
index 1a8ca533fa..c359a8b65c 100644
--- a/hw/mem/cxl_type3.c
+++ b/hw/mem/cxl_type3.c
@@ -1783,6 +1783,13 @@ void qmp_cxl_inject_general_media_event(const char *path, CxlEventLog log,
#define CXL_DRAM_VALID_ROW BIT(5)
#define CXL_DRAM_VALID_COLUMN BIT(6)
#define CXL_DRAM_VALID_CORRECTION_MASK BIT(7)
+#define CXL_DRAM_VALID_COMPONENT BIT(8)
+#define CXL_DRAM_VALID_COMPONENT_ID_FORMAT BIT(9)
+#define CXL_DRAM_VALID_SUB_CHANNEL BIT(10)
+
+#define CXL_DRAM_EV_DESC_UCE BIT(0)
+#define CXL_DRAM_EV_DESC_THRESHOLD_EVENT BIT(1)
+#define CXL_DRAM_EV_DESC_POISON_LIST_OVERFLOW_EVENT BIT(2)
void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log,
uint32_t flags,
@@ -1802,6 +1809,12 @@ void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log,
bool has_column, uint16_t column,
bool has_correction_mask,
uint64List *correction_mask,
+ const char *component_id,
+ bool has_comp_id_pldm, bool is_comp_id_pldm,
+ bool has_sub_channel, uint8_t sub_channel,
+ bool has_cme_ev_flags, uint8_t cme_ev_flags,
+ bool has_cvme_count, uint32_t cvme_count,
+ uint8_t sub_type,
Error **errp)
{
Object *obj = object_resolve_path(path, NULL);
@@ -1888,6 +1901,35 @@ void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log,
valid_flags |= CXL_DRAM_VALID_CORRECTION_MASK;
}
+ if (component_id) {
+ strncpy((char *)dram.component_id, component_id,
+ sizeof(dram.component_id) - 1);
+ valid_flags |= CXL_DRAM_VALID_COMPONENT;
+ if (has_comp_id_pldm && is_comp_id_pldm) {
+ valid_flags |= CXL_DRAM_VALID_COMPONENT_ID_FORMAT;
+ }
+ }
+
+ if (has_sub_channel) {
+ dram.sub_channel = sub_channel;
+ valid_flags |= CXL_DRAM_VALID_SUB_CHANNEL;
+ }
+
+ if (has_cme_ev_flags) {
+ dram.cme_ev_flags = cme_ev_flags;
+ } else {
+ dram.cme_ev_flags = 0;
+ }
+
+ if (has_cvme_count) {
+ descriptor |= CXL_DRAM_EV_DESC_THRESHOLD_EVENT;
+ st24_le_p(dram.cvme_count, cvme_count);
+ } else {
+ st24_le_p(dram.cvme_count, 0);
+ }
+
+ dram.sub_type = sub_type;
+
stw_le_p(&dram.validity_flags, valid_flags);
if (cxl_event_insert(cxlds, enc_log, (CXLEventRecordRaw *)&dram)) {
diff --git a/hw/mem/cxl_type3_stubs.c b/hw/mem/cxl_type3_stubs.c
index 2047e97846..231dda263f 100644
--- a/hw/mem/cxl_type3_stubs.c
+++ b/hw/mem/cxl_type3_stubs.c
@@ -53,6 +53,13 @@ void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log,
bool has_column, uint16_t column,
bool has_correction_mask,
uint64List *correction_mask,
+ const char *component_id,
+ bool has_comp_id_pldm,
+ bool is_comp_id_pldm,
+ bool has_sub_channel, uint8_t sub_channel,
+ bool has_cme_ev_flags, uint8_t cme_ev_flags,
+ bool has_cvme_count, uint32_t cvme_count,
+ uint8_t sub_type,
Error **errp) {}
void qmp_cxl_inject_memory_module_event(const char *path, CxlEventLog log,
diff --git a/include/hw/cxl/cxl_events.h b/include/hw/cxl/cxl_events.h
index 352f9891bd..a3c5f2ec20 100644
--- a/include/hw/cxl/cxl_events.h
+++ b/include/hw/cxl/cxl_events.h
@@ -138,7 +138,7 @@ typedef struct CXLEventGenMedia {
/*
* DRAM Event Record
- * CXL r3.1 Section 8.2.9.2.1.2: Table 8-46
+ * CXL r3.2 Section 8.2.10.2.1.2: Table 8-58
* All fields little endian.
*/
typedef struct CXLEventDram {
@@ -156,7 +156,12 @@ typedef struct CXLEventDram {
uint8_t row[3];
uint16_t column;
uint64_t correction_mask[4];
- uint8_t reserved[0x17];
+ uint8_t component_id[CXL_EVENT_GEN_MED_COMP_ID_SIZE];
+ uint8_t sub_channel;
+ uint8_t cme_ev_flags;
+ uint8_t cvme_count[3];
+ uint8_t sub_type;
+ uint8_t reserved;
} QEMU_PACKED CXLEventDram;
/*
diff --git a/qapi/cxl.json b/qapi/cxl.json
index a245632f92..c2f8b03224 100644
--- a/qapi/cxl.json
+++ b/qapi/cxl.json
@@ -166,6 +166,21 @@
# @correction-mask: Bits within each nibble. Used in order of bits
# set in the nibble-mask. Up to 4 nibbles may be covered.
#
+# @component-id: Device specific component identifier for the event.
+# May describe a field replaceable sub-component of the device.
+#
+# @is-comp-id-pldm: This flag specifies whether the device-specific
+# component identifier format follows PLDM.
+#
+# @sub-channel: The sub-channel of the memory event location.
+#
+# @cme-ev-flags: Advanced programmable corrected memory error
+# threshold event flags.
+#
+# @cvme-count: Corrected volatile memory error count at event.
+#
+# @sub-type: Memory event sub-type.
+#
# Since: 8.1
##
{ 'struct': 'CXLDRAMEvent',
@@ -174,7 +189,11 @@
'type': 'uint8', 'transaction-type': 'uint8',
'*channel': 'uint8', '*rank': 'uint8', '*nibble-mask': 'uint32',
'*bank-group': 'uint8', '*bank': 'uint8', '*row': 'uint32',
- '*column': 'uint16', '*correction-mask': [ 'uint64' ]
+ '*column': 'uint16', '*correction-mask': [ 'uint64' ],
+ '*component-id': 'str', '*is-comp-id-pldm':'bool',
+ '*sub-channel':'uint8',
+ '*cme-ev-flags':'uint8', '*cvme-count':'uint32',
+ 'sub-type':'uint8'
}}
##
--
2.43.0