aboutsummaryrefslogtreecommitdiff
path: root/hw/cxl/cxl-mailbox-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/cxl/cxl-mailbox-utils.c')
-rw-r--r--hw/cxl/cxl-mailbox-utils.c106
1 files changed, 85 insertions, 21 deletions
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 3f46538048..02f9b5a870 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -80,25 +80,6 @@ struct cxl_cmd {
uint8_t *payload;
};
-#define DEFINE_MAILBOX_HANDLER_ZEROED(name, size) \
- uint16_t __zero##name = size; \
- static CXLRetCode cmd_##name(struct cxl_cmd *cmd, \
- CXLDeviceState *cxl_dstate, uint16_t *len) \
- { \
- *len = __zero##name; \
- memset(cmd->payload, 0, *len); \
- return CXL_MBOX_SUCCESS; \
- }
-#define DEFINE_MAILBOX_HANDLER_NOP(name) \
- static CXLRetCode cmd_##name(struct cxl_cmd *cmd, \
- CXLDeviceState *cxl_dstate, uint16_t *len) \
- { \
- return CXL_MBOX_SUCCESS; \
- }
-
-DEFINE_MAILBOX_HANDLER_ZEROED(events_get_interrupt_policy, 4);
-DEFINE_MAILBOX_HANDLER_NOP(events_set_interrupt_policy);
-
static CXLRetCode cmd_events_get_records(struct cxl_cmd *cmd,
CXLDeviceState *cxlds,
uint16_t *len)
@@ -136,6 +117,88 @@ static CXLRetCode cmd_events_clear_records(struct cxl_cmd *cmd,
return cxl_event_clear_records(cxlds, pl);
}
+static CXLRetCode cmd_events_get_interrupt_policy(struct cxl_cmd *cmd,
+ CXLDeviceState *cxlds,
+ uint16_t *len)
+{
+ CXLEventInterruptPolicy *policy;
+ CXLEventLog *log;
+
+ policy = (CXLEventInterruptPolicy *)cmd->payload;
+ memset(policy, 0, sizeof(*policy));
+
+ log = &cxlds->event_logs[CXL_EVENT_TYPE_INFO];
+ if (log->irq_enabled) {
+ policy->info_settings = CXL_EVENT_INT_SETTING(log->irq_vec);
+ }
+
+ log = &cxlds->event_logs[CXL_EVENT_TYPE_WARN];
+ if (log->irq_enabled) {
+ policy->warn_settings = CXL_EVENT_INT_SETTING(log->irq_vec);
+ }
+
+ log = &cxlds->event_logs[CXL_EVENT_TYPE_FAIL];
+ if (log->irq_enabled) {
+ policy->failure_settings = CXL_EVENT_INT_SETTING(log->irq_vec);
+ }
+
+ log = &cxlds->event_logs[CXL_EVENT_TYPE_FATAL];
+ if (log->irq_enabled) {
+ policy->fatal_settings = CXL_EVENT_INT_SETTING(log->irq_vec);
+ }
+
+ log = &cxlds->event_logs[CXL_EVENT_TYPE_DYNAMIC_CAP];
+ if (log->irq_enabled) {
+ /* Dynamic Capacity borrows the same vector as info */
+ policy->dyn_cap_settings = CXL_INT_MSI_MSIX;
+ }
+
+ *len = sizeof(*policy);
+ return CXL_MBOX_SUCCESS;
+}
+
+static CXLRetCode cmd_events_set_interrupt_policy(struct cxl_cmd *cmd,
+ CXLDeviceState *cxlds,
+ uint16_t *len)
+{
+ CXLEventInterruptPolicy *policy;
+ CXLEventLog *log;
+
+ if (*len < CXL_EVENT_INT_SETTING_MIN_LEN) {
+ return CXL_MBOX_INVALID_PAYLOAD_LENGTH;
+ }
+
+ policy = (CXLEventInterruptPolicy *)cmd->payload;
+
+ log = &cxlds->event_logs[CXL_EVENT_TYPE_INFO];
+ log->irq_enabled = (policy->info_settings & CXL_EVENT_INT_MODE_MASK) ==
+ CXL_INT_MSI_MSIX;
+
+ log = &cxlds->event_logs[CXL_EVENT_TYPE_WARN];
+ log->irq_enabled = (policy->warn_settings & CXL_EVENT_INT_MODE_MASK) ==
+ CXL_INT_MSI_MSIX;
+
+ log = &cxlds->event_logs[CXL_EVENT_TYPE_FAIL];
+ log->irq_enabled = (policy->failure_settings & CXL_EVENT_INT_MODE_MASK) ==
+ CXL_INT_MSI_MSIX;
+
+ log = &cxlds->event_logs[CXL_EVENT_TYPE_FATAL];
+ log->irq_enabled = (policy->fatal_settings & CXL_EVENT_INT_MODE_MASK) ==
+ CXL_INT_MSI_MSIX;
+
+ /* DCD is optional */
+ if (*len < sizeof(*policy)) {
+ return CXL_MBOX_SUCCESS;
+ }
+
+ log = &cxlds->event_logs[CXL_EVENT_TYPE_DYNAMIC_CAP];
+ log->irq_enabled = (policy->dyn_cap_settings & CXL_EVENT_INT_MODE_MASK) ==
+ CXL_INT_MSI_MSIX;
+
+ *len = sizeof(*policy);
+ return CXL_MBOX_SUCCESS;
+}
+
/* 8.2.9.2.1 */
static CXLRetCode cmd_firmware_update_get_info(struct cxl_cmd *cmd,
CXLDeviceState *cxl_dstate,
@@ -611,9 +674,10 @@ static struct cxl_cmd cxl_cmd_set[256][256] = {
[EVENTS][CLEAR_RECORDS] = { "EVENTS_CLEAR_RECORDS",
cmd_events_clear_records, ~0, IMMEDIATE_LOG_CHANGE },
[EVENTS][GET_INTERRUPT_POLICY] = { "EVENTS_GET_INTERRUPT_POLICY",
- cmd_events_get_interrupt_policy, 0, 0 },
+ cmd_events_get_interrupt_policy, 0, 0 },
[EVENTS][SET_INTERRUPT_POLICY] = { "EVENTS_SET_INTERRUPT_POLICY",
- cmd_events_set_interrupt_policy, 4, IMMEDIATE_CONFIG_CHANGE },
+ cmd_events_set_interrupt_policy,
+ ~0, IMMEDIATE_CONFIG_CHANGE },
[FIRMWARE_UPDATE][GET_INFO] = { "FIRMWARE_UPDATE_GET_INFO",
cmd_firmware_update_get_info, 0, 0 },
[TIMESTAMP][GET] = { "TIMESTAMP_GET", cmd_timestamp_get, 0, 0 },