aboutsummaryrefslogtreecommitdiff
path: root/hw/cxl/cxl-events.c
diff options
context:
space:
mode:
authorIra Weiny <ira.weiny@intel.com>2023-05-30 14:36:00 +0100
committerMichael S. Tsirkin <mst@redhat.com>2023-06-22 18:55:14 -0400
commit6676bb973ba53d60886b06213ec98fbd736d66a1 (patch)
tree28911071ca8f35c75b76f7743687b4039bd886ad /hw/cxl/cxl-events.c
parent22d7e3be0714f39bae43bd0c05f6e6d149a47b13 (diff)
hw/cxl/events: Add event interrupt support
Replace the stubbed out CXL Get/Set Event interrupt policy mailbox commands. Enable those commands to control interrupts for each of the event log types. Skip the standard input mailbox length on the Set command due to DCD being optional. Perform the checks separately. Signed-off-by: Ira Weiny <ira.weiny@intel.com> Reviewed-by: Fan Ni <fan.ni@samsung.com> Reviewed-by: Davidlohr Bueso <dave@stgolabs.net> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Message-Id: <20230530133603.16934-5-Jonathan.Cameron@huawei.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/cxl/cxl-events.c')
-rw-r--r--hw/cxl/cxl-events.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/hw/cxl/cxl-events.c b/hw/cxl/cxl-events.c
index 5da1b76b97..d161d57456 100644
--- a/hw/cxl/cxl-events.c
+++ b/hw/cxl/cxl-events.c
@@ -13,6 +13,8 @@
#include "qemu/bswap.h"
#include "qemu/typedefs.h"
#include "qemu/error-report.h"
+#include "hw/pci/msi.h"
+#include "hw/pci/msix.h"
#include "hw/cxl/cxl.h"
#include "hw/cxl/cxl_events.h"
@@ -26,7 +28,7 @@ static void reset_overflow(CXLEventLog *log)
log->last_overflow_timestamp = 0;
}
-void cxl_event_init(CXLDeviceState *cxlds)
+void cxl_event_init(CXLDeviceState *cxlds, int start_msg_num)
{
CXLEventLog *log;
int i;
@@ -37,9 +39,16 @@ void cxl_event_init(CXLDeviceState *cxlds)
log->overflow_err_count = 0;
log->first_overflow_timestamp = 0;
log->last_overflow_timestamp = 0;
+ log->irq_enabled = false;
+ log->irq_vec = start_msg_num++;
qemu_mutex_init(&log->lock);
QSIMPLEQ_INIT(&log->events);
}
+
+ /* Override -- Dynamic Capacity uses the same vector as info */
+ cxlds->event_logs[CXL_EVENT_TYPE_DYNAMIC_CAP].irq_vec =
+ cxlds->event_logs[CXL_EVENT_TYPE_INFO].irq_vec;
+
}
static CXLEvent *cxl_event_get_head(CXLEventLog *log)
@@ -215,3 +224,25 @@ CXLRetCode cxl_event_clear_records(CXLDeviceState *cxlds, CXLClearEventPayload *
return CXL_MBOX_SUCCESS;
}
+
+void cxl_event_irq_assert(CXLType3Dev *ct3d)
+{
+ CXLDeviceState *cxlds = &ct3d->cxl_dstate;
+ PCIDevice *pdev = &ct3d->parent_obj;
+ int i;
+
+ for (i = 0; i < CXL_EVENT_TYPE_MAX; i++) {
+ CXLEventLog *log = &cxlds->event_logs[i];
+
+ if (!log->irq_enabled || cxl_event_empty(log)) {
+ continue;
+ }
+
+ /* Notifies interrupt, legacy IRQ is not supported */
+ if (msix_enabled(pdev)) {
+ msix_notify(pdev, log->irq_vec);
+ } else if (msi_enabled(pdev)) {
+ msi_notify(pdev, log->irq_vec);
+ }
+ }
+}