All of lore.kernel.org
 help / color / mirror / Atom feed
From: fan <nifan.cxl@gmail.com>
To: Davidlohr Bueso <dave@stgolabs.net>
Cc: Jonathan.Cameron@huawei.com, vishal.l.verma@intel.com,
	fan.ni@samsung.com, a.manzanares@samsung.com,
	mounika.k@samsung.com, linux-cxl@vger.kernel.org
Subject: Re: [PATCH 1/2] hw/cxl: Add Transfer FW support
Date: Tue, 9 Jan 2024 14:36:57 -0800	[thread overview]
Message-ID: <ZZ3KiceGpf5RUC5a@debian> (raw)
In-Reply-To: <20240109070436.21253-2-dave@stgolabs.net>

On Mon, Jan 08, 2024 at 11:04:35PM -0800, Davidlohr Bueso wrote:
> Per the latest 3.1 spec for supporting firmware update metadata
> (no actual buffers). Aborting a xfer is currently unsupported
> through a nop.
> 
> Signed-off-by: Davidlohr Bueso <dave@stgolabs.net>
> ---
>  hw/cxl/cxl-mailbox-utils.c  | 124 ++++++++++++++++++++++++++++++++++--
>  include/hw/cxl/cxl_device.h |   9 +++
>  2 files changed, 129 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
> index 11ec8b648baf..0295ea8b29aa 100644
> --- a/hw/cxl/cxl-mailbox-utils.c
> +++ b/hw/cxl/cxl-mailbox-utils.c
> @@ -60,6 +60,7 @@ enum {
>          #define SET_INTERRUPT_POLICY   0x3
>      FIRMWARE_UPDATE = 0x02,
>          #define GET_INFO      0x0
> +        #define TRANSFER      0x1
>      TIMESTAMP   = 0x03,
>          #define GET           0x0
>          #define SET           0x1
> @@ -815,6 +816,8 @@ static CXLRetCode cmd_infostat_bg_op_sts(const struct cxl_cmd *cmd,
>      return CXL_MBOX_SUCCESS;
>  }
>  
> +#define CXL_FW_SLOTS 2
> +
>  /* CXL r3.0 Section 8.2.9.3.1: Get FW Info (Opcode 0200h) */
>  static CXLRetCode cmd_firmware_update_get_info(const struct cxl_cmd *cmd,
>                                                 uint8_t *payload_in,
> @@ -846,15 +849,118 @@ static CXLRetCode cmd_firmware_update_get_info(const struct cxl_cmd *cmd,
>      fw_info = (void *)payload_out;
>      memset(fw_info, 0, sizeof(*fw_info));
>  
> -    fw_info->slots_supported = 2;
> -    fw_info->slot_info = BIT(0) | BIT(3);
> +    fw_info->slots_supported = CXL_FW_SLOTS;
> +    fw_info->slot_info = (cci->fw.active_slot & 0x7) |
> +            ((cci->fw.staged_slot & 0x7) << 3);
>      fw_info->caps = 0;
> -    pstrcpy(fw_info->fw_rev1, sizeof(fw_info->fw_rev1), "BWFW VERSION 0");
> +
> +    if (cci->fw.slot[0]) {
> +        pstrcpy(fw_info->fw_rev1, sizeof(fw_info->fw_rev1), "BWFW VERSION 0");
> +    }
> +    if (cci->fw.slot[1]) {
> +        pstrcpy(fw_info->fw_rev2, sizeof(fw_info->fw_rev2), "BWFW VERSION 1");
> +    }
> +    if (cci->fw.slot[2]) {
> +        pstrcpy(fw_info->fw_rev3, sizeof(fw_info->fw_rev3), "BWFW VERSION 2");
> +    }
> +    if (cci->fw.slot[3]) {
> +        pstrcpy(fw_info->fw_rev4, sizeof(fw_info->fw_rev4), "BWFW VERSION 3");
> +    }
>  
>      *len_out = sizeof(*fw_info);
>      return CXL_MBOX_SUCCESS;
>  }
>  
> +/* CXL r3.1 section 8.2.9.3.2: Transfer FW (Opcode 0201h) */
> +#define CXL_FW_XFER_ALIGNMENT   128
> +
> +#define CXL_FW_XFER_ACTION_FULL	    0x0
> +#define CXL_FW_XFER_ACTION_INIT	    0x1
> +#define CXL_FW_XFER_ACTION_CONTINUE 0x2
> +#define CXL_FW_XFER_ACTION_END	    0x3
> +#define CXL_FW_XFER_ACTION_ABORT    0x4
> +
> +#define CXL_FW_SIZE  0x02000000 /* 32 mb */
> +
> +static CXLRetCode cmd_firmware_update_transfer(const struct cxl_cmd *cmd,
> +                                               uint8_t *payload_in,
> +                                               size_t len,
> +                                               uint8_t *payload_out,
> +                                               size_t *len_out,
> +                                               CXLCCI *cci)
> +{
> +    CXLDeviceState *cxl_dstate = &CXL_TYPE3(cci->d)->cxl_dstate;
> +    struct {
> +        uint8_t action;
> +        uint8_t slot;
> +        uint8_t caps;
> +        uint8_t rsvd1[2];
> +        uint32_t offset;
> +        uint8_t rsvd2[0x78];
> +        uint8_t data[];
> +    } QEMU_PACKED *fw_transfer;
> +    size_t offset, length;
> +
> +    if ((cxl_dstate->vmem_size < CXL_CAPACITY_MULTIPLIER) ||
> +        (cxl_dstate->pmem_size < CXL_CAPACITY_MULTIPLIER)) {
> +        return CXL_MBOX_INTERNAL_ERROR;
> +    }
> +
> +    fw_transfer = (void *)payload_in;
> +
> +    if (cci->fw.transfering &&
> +        (fw_transfer->action == CXL_FW_XFER_ACTION_FULL ||
> +         fw_transfer->action == CXL_FW_XFER_ACTION_INIT)) {
> +        return CXL_MBOX_FW_XFER_IN_PROGRESS;
> +    }
> +
> +    offset = fw_transfer->offset * CXL_FW_XFER_ALIGNMENT;
> +    length = len - sizeof(*fw_transfer);
> +    if (offset + length > CXL_FW_SIZE) {
> +        return CXL_MBOX_INVALID_INPUT;
> +    }
> +
> +    switch (fw_transfer->action) {
> +    case CXL_FW_XFER_ACTION_FULL: /* ignores offset */
> +    case CXL_FW_XFER_ACTION_END:
> +        if (fw_transfer->slot == 0 ||
> +            fw_transfer->slot == cci->fw.active_slot ||
> +            fw_transfer->slot > CXL_FW_SLOTS) {
Should here be >= instead of > ?
> +            return CXL_MBOX_FW_INVALID_SLOT;
> +        }
> +        /*
> +         * Optimistically mark the slot used now (as opposed
> +         * to at the end of the successful transfer). That
> +         * way we don't need to keep command context.
> +         */
> +        cci->fw.slot[fw_transfer->slot - 1] = true;
> +        break;
> +    case CXL_FW_XFER_ACTION_INIT:
> +        if (offset != 0) {
> +            return CXL_MBOX_INVALID_INPUT;
> +        }
> +        /* fallthrough */
> +    case CXL_FW_XFER_ACTION_CONTINUE:
> +        break;
> +    case CXL_FW_XFER_ACTION_ABORT: /* nop */
> +        return CXL_MBOX_SUCCESS;
> +    default:
> +        return CXL_MBOX_INVALID_INPUT;
> +    }
> +
> +    cci->fw.transfering = true;
> +
> +    cci->bg.runtime = 2 * 1000UL;

How we get this? I see the spec mentioned the timeout between FW package ports
is 30 seconds.

Fan
> +    *len_out = 0;
> +
> +    return CXL_MBOX_BG_STARTED;
> +}
> +
> +static void __do_firmware_xfer(CXLCCI *cci)
> +{
> +    cci->fw.transfering = false;
> +}
> +
>  /* CXL r3.0 Section 8.2.9.4.1: Get Timestamp (Opcode 0300h) */
>  static CXLRetCode cmd_timestamp_get(const struct cxl_cmd *cmd,
>                                      uint8_t *payload_in,
> @@ -2165,6 +2271,8 @@ static const struct cxl_cmd cxl_cmd_set[256][256] = {
>                                        ~0, CXL_MBOX_IMMEDIATE_CONFIG_CHANGE },
>      [FIRMWARE_UPDATE][GET_INFO] = { "FIRMWARE_UPDATE_GET_INFO",
>          cmd_firmware_update_get_info, 0, 0 },
> +    [FIRMWARE_UPDATE][TRANSFER] = { "FIRMWARE_UPDATE_TRANSFER",
> +        cmd_firmware_update_transfer, ~0, CXL_MBOX_BACKGROUND_OPERATION },
>      [TIMESTAMP][GET] = { "TIMESTAMP_GET", cmd_timestamp_get, 0, 0 },
>      [TIMESTAMP][SET] = { "TIMESTAMP_SET", cmd_timestamp_set,
>                           8, CXL_MBOX_IMMEDIATE_POLICY_CHANGE },
> @@ -2278,7 +2386,8 @@ int cxl_process_cci_message(CXLCCI *cci, uint8_t set, uint8_t cmd,
>              h == cmd_media_get_poison_list ||
>              h == cmd_media_inject_poison ||
>              h == cmd_media_clear_poison ||
> -            h == cmd_sanitize_overwrite) {
> +            h == cmd_sanitize_overwrite ||
> +            h == cmd_firmware_update_transfer) {
>              return CXL_MBOX_MEDIA_DISABLED;
>          }
>      }
> @@ -2325,6 +2434,9 @@ static void bg_timercb(void *opaque)
>              CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
>  
>              switch (cci->bg.opcode) {
> +            case 0x0201: /* fw transfer */
> +                __do_firmware_xfer(cci);
> +                break;
>              case 0x4400: /* sanitize */
>                  __do_sanitization(ct3d);
>                  cxl_dev_enable_media(&ct3d->cxl_dstate);
> @@ -2388,6 +2500,10 @@ void cxl_init_cci(CXLCCI *cci, size_t payload_max)
>      cci->payload_max = payload_max;
>      cxl_rebuild_cel(cci);
>  
> +    cci->fw.active_slot = cci->fw.staged_slot = 1;
> +    memset(cci->fw.slot, 0, sizeof(cci->fw.slot));
> +    cci->fw.slot[cci->fw.active_slot - 1] = true;
> +
>      cci->bg.complete_pct = 0;
>      cci->bg.starttime = 0;
>      cci->bg.runtime = 0;
> diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
> index b2cb280e1631..b4373bfe4d2a 100644
> --- a/include/hw/cxl/cxl_device.h
> +++ b/include/hw/cxl/cxl_device.h
> @@ -201,6 +201,15 @@ typedef struct CXLCCI {
>          uint64_t runtime;
>          QEMUTimer *timer;
>      } bg;
> +
> +    /* firmware update */
> +    struct {
> +        bool transfering;
> +        int active_slot;
> +        int staged_slot;
> +        bool slot[4];
> +    } fw;
> +
>      size_t payload_max;
>      /* Pointer to device hosting the CCI */
>      DeviceState *d;
> -- 
> 2.43.0
> 

  reply	other threads:[~2024-01-09 22:37 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-09  7:04 [PATCH -qemu 0/2] hw/cxl: Firmware Update support Davidlohr Bueso
2024-01-09  7:04 ` [PATCH 1/2] hw/cxl: Add Transfer FW support Davidlohr Bueso
2024-01-09 22:36   ` fan [this message]
2024-01-10 16:43     ` Davidlohr Bueso
2024-01-26 15:42   ` Jonathan Cameron
2024-01-26 17:17     ` Davidlohr Bueso
2024-01-26 17:48       ` Jonathan Cameron
2024-01-09  7:04 ` [PATCH 2/2] hw/cxl: Add Activate " Davidlohr Bueso
2024-01-26 15:54   ` Jonathan Cameron
2024-01-26 16:57     ` Davidlohr Bueso
2024-01-26 17:35       ` Jonathan Cameron

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZZ3KiceGpf5RUC5a@debian \
    --to=nifan.cxl@gmail.com \
    --cc=Jonathan.Cameron@huawei.com \
    --cc=a.manzanares@samsung.com \
    --cc=dave@stgolabs.net \
    --cc=fan.ni@samsung.com \
    --cc=linux-cxl@vger.kernel.org \
    --cc=mounika.k@samsung.com \
    --cc=vishal.l.verma@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.