hw/cxl/mbox: Wire up interrupts for background completion

Notify when the background operation is done. Note that for now background
commands are only supported on the main Type 3 mailbox.

Signed-off-by: Davidlohr Bueso <dave@stgolabs.net>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Message-Id: <20231023160806.13206-13-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:
Davidlohr Bueso 2023-10-23 17:08:01 +01:00 committed by Michael S. Tsirkin
parent 221d2cfbdb
commit 43efb0bfad
3 changed files with 24 additions and 18 deletions

View file

@ -357,10 +357,18 @@ static void device_reg_init_common(CXLDeviceState *cxl_dstate)
static void mailbox_reg_init_common(CXLDeviceState *cxl_dstate)
{
/* 2048 payload size, with no interrupt */
const uint8_t msi_n = 9;
/* 2048 payload size */
ARRAY_FIELD_DP32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CAP,
PAYLOAD_SIZE, CXL_MAILBOX_PAYLOAD_SHIFT);
cxl_dstate->payload_size = CXL_MAILBOX_MAX_PAYLOAD_SIZE;
/* irq support */
ARRAY_FIELD_DP32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CAP,
BG_INT_CAP, 1);
ARRAY_FIELD_DP32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CAP,
MSI_N, msi_n);
cxl_dstate->mbox_msi_n = msi_n;
}
static void memdev_reg_init_common(CXLDeviceState *cxl_dstate) { }

View file

@ -8,6 +8,8 @@
*/
#include "qemu/osdep.h"
#include "hw/pci/msi.h"
#include "hw/pci/msix.h"
#include "hw/cxl/cxl.h"
#include "hw/cxl/cxl_events.h"
#include "hw/pci/pci.h"
@ -1076,28 +1078,16 @@ int cxl_process_cci_message(CXLCCI *cci, uint8_t set, uint8_t cmd,
static void bg_timercb(void *opaque)
{
CXLCCI *cci = opaque;
CXLDeviceState *cxl_dstate = &CXL_TYPE3(cci->d)->cxl_dstate;
uint64_t bg_status_reg = 0;
uint64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
uint64_t total_time = cci->bg.starttime + cci->bg.runtime;
assert(cci->bg.runtime > 0);
bg_status_reg = FIELD_DP64(bg_status_reg, CXL_DEV_BG_CMD_STS,
OP, cci->bg.opcode);
if (now >= total_time) { /* we are done */
uint64_t status_reg;
uint16_t ret = CXL_MBOX_SUCCESS;
cci->bg.complete_pct = 100;
/* Clear bg */
status_reg = FIELD_DP64(0, CXL_DEV_MAILBOX_STS, BG_OP, 0);
cxl_dstate->mbox_reg_state64[R_CXL_DEV_MAILBOX_STS] = status_reg;
bg_status_reg = FIELD_DP64(bg_status_reg, CXL_DEV_BG_CMD_STS,
RET_CODE, ret);
/* TODO add ad-hoc cmd succesful completion handling */
cci->bg.ret_code = ret;
qemu_log("Background command %04xh finished: %s\n",
cci->bg.opcode,
@ -1108,14 +1098,21 @@ static void bg_timercb(void *opaque)
timer_mod(cci->bg.timer, now + CXL_MBOX_BG_UPDATE_FREQ);
}
bg_status_reg = FIELD_DP64(bg_status_reg, CXL_DEV_BG_CMD_STS,
PERCENTAGE_COMP, cci->bg.complete_pct);
cxl_dstate->mbox_reg_state64[R_CXL_DEV_BG_CMD_STS] = bg_status_reg;
if (cci->bg.complete_pct == 100) {
/* TODO: generalize to switch CCI */
CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
CXLDeviceState *cxl_dstate = &ct3d->cxl_dstate;
PCIDevice *pdev = PCI_DEVICE(cci->d);
cci->bg.starttime = 0;
/* registers are updated, allow new bg-capable cmds */
cci->bg.runtime = 0;
if (msix_enabled(pdev)) {
msix_notify(pdev, cxl_dstate->mbox_msi_n);
} else if (msi_enabled(pdev)) {
msi_notify(pdev, cxl_dstate->mbox_msi_n);
}
}
}

View file

@ -193,6 +193,7 @@ typedef struct cxl_device_state {
struct {
MemoryRegion mailbox;
uint16_t payload_size;
uint8_t mbox_msi_n;
union {
uint8_t mbox_reg_state[CXL_MAILBOX_REGISTERS_LENGTH];
uint16_t mbox_reg_state16[CXL_MAILBOX_REGISTERS_LENGTH / 2];