mirror of https://github.com/xemu-project/xemu.git
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:
parent
221d2cfbdb
commit
43efb0bfad
|
@ -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) { }
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in New Issue