aboutsummaryrefslogtreecommitdiff
path: root/hw/mem
diff options
context:
space:
mode:
Diffstat (limited to 'hw/mem')
-rw-r--r--hw/mem/cxl_type3.c62
-rw-r--r--hw/mem/cxl_type3_stubs.c12
2 files changed, 74 insertions, 0 deletions
diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
index 3c07b1b..4e31474 100644
--- a/hw/mem/cxl_type3.c
+++ b/hw/mem/cxl_type3.c
@@ -1201,6 +1201,11 @@ static const QemuUUID dram_uuid = {
0x4e, 0x9b, 0xfb, 0x5c, 0x96, 0x24),
};
+static const QemuUUID memory_module_uuid = {
+ .data = UUID(0xfe927475, 0xdd59, 0x4339, 0xa5, 0x86,
+ 0x79, 0xba, 0xb1, 0x13, 0xb7, 0x74),
+};
+
#define CXL_GMER_VALID_CHANNEL BIT(0)
#define CXL_GMER_VALID_RANK BIT(1)
#define CXL_GMER_VALID_DEVICE BIT(2)
@@ -1408,6 +1413,63 @@ void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log, uint8_t flags,
return;
}
+void qmp_cxl_inject_memory_module_event(const char *path, CxlEventLog log,
+ uint8_t flags, uint8_t type,
+ uint8_t health_status,
+ uint8_t media_status,
+ uint8_t additional_status,
+ uint8_t life_used,
+ int16_t temperature,
+ uint32_t dirty_shutdown_count,
+ uint32_t corrected_volatile_error_count,
+ uint32_t corrected_persistent_error_count,
+ Error **errp)
+{
+ Object *obj = object_resolve_path(path, NULL);
+ CXLEventMemoryModule module;
+ CXLEventRecordHdr *hdr = &module.hdr;
+ CXLDeviceState *cxlds;
+ CXLType3Dev *ct3d;
+ uint8_t enc_log;
+ int rc;
+
+ if (!obj) {
+ error_setg(errp, "Unable to resolve path");
+ return;
+ }
+ if (!object_dynamic_cast(obj, TYPE_CXL_TYPE3)) {
+ error_setg(errp, "Path does not point to a CXL type 3 device");
+ return;
+ }
+ ct3d = CXL_TYPE3(obj);
+ cxlds = &ct3d->cxl_dstate;
+
+ rc = ct3d_qmp_cxl_event_log_enc(log);
+ if (rc < 0) {
+ error_setg(errp, "Unhandled error log type");
+ return;
+ }
+ enc_log = rc;
+
+ memset(&module, 0, sizeof(module));
+ cxl_assign_event_header(hdr, &memory_module_uuid, flags, sizeof(module),
+ cxl_device_get_timestamp(&ct3d->cxl_dstate));
+
+ module.type = type;
+ module.health_status = health_status;
+ module.media_status = media_status;
+ module.additional_status = additional_status;
+ module.life_used = life_used;
+ stw_le_p(&module.temperature, temperature);
+ stl_le_p(&module.dirty_shutdown_count, dirty_shutdown_count);
+ stl_le_p(&module.corrected_volatile_error_count, corrected_volatile_error_count);
+ stl_le_p(&module.corrected_persistent_error_count, corrected_persistent_error_count);
+
+ if (cxl_event_insert(cxlds, enc_log, (CXLEventRecordRaw *)&module)) {
+ cxl_event_irq_assert(ct3d);
+ }
+}
+
static void ct3_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
diff --git a/hw/mem/cxl_type3_stubs.c b/hw/mem/cxl_type3_stubs.c
index e904c5d..f3e4a9f 100644
--- a/hw/mem/cxl_type3_stubs.c
+++ b/hw/mem/cxl_type3_stubs.c
@@ -26,6 +26,18 @@ void qmp_cxl_inject_dram_event(const char *path, CxlEventLog log, uint8_t flags,
bool has_correction_mask, uint64List *correction_mask,
Error **errp) {}
+void qmp_cxl_inject_memory_module_event(const char *path, CxlEventLog log,
+ uint8_t flags, uint8_t type,
+ uint8_t health_status,
+ uint8_t media_status,
+ uint8_t additional_status,
+ uint8_t life_used,
+ int16_t temperature,
+ uint32_t dirty_shutdown_count,
+ uint32_t corrected_volatile_error_count,
+ uint32_t corrected_persistent_error_count,
+ Error **errp) {}
+
void qmp_cxl_inject_poison(const char *path, uint64_t start, uint64_t length,
Error **errp)
{