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>
This commit is contained in:
Ira Weiny 2023-05-30 14:36:00 +01:00 committed by Michael S. Tsirkin
parent 22d7e3be07
commit 6676bb973b
5 changed files with 147 additions and 25 deletions

View file

@ -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);
}
}
}