Re: [PATCH v3 6/9] hw/mem/cxl_type3: Add DC extent list representative and get DC extent list mailbox support

2024-01-24 Thread Jonathan Cameron via
On Tue,  7 Nov 2023 10:07:10 -0800
nifan@gmail.com wrote:

> From: Fan Ni 
> 
> Add dynamic capacity extent list representative to the definition of
> CXLType3Dev and add get DC extent list mailbox command per
> CXL.spec.3.0:.8.2.9.8.9.2.
> 
> Signed-off-by: Fan Ni 
A few minor comments inline.

J
> ---
>  hw/cxl/cxl-mailbox-utils.c  | 73 +
>  hw/mem/cxl_type3.c  |  1 +
>  include/hw/cxl/cxl_device.h | 23 
>  3 files changed, 97 insertions(+)
> 
> diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
> index 1f512b3e6b..56f4aa237a 100644
> --- a/hw/cxl/cxl-mailbox-utils.c
> +++ b/hw/cxl/cxl-mailbox-utils.c
> @@ -82,6 +82,7 @@ enum {
>  #define CLEAR_POISON   0x2
>  DCD_CONFIG  = 0x48,
>  #define GET_DC_CONFIG  0x0
> +#define GET_DYN_CAP_EXT_LIST   0x1
>  PHYSICAL_SWITCH = 0x51,
>  #define IDENTIFY_SWITCH_DEVICE  0x0
>  #define GET_PHYSICAL_PORT_STATE 0x1
> @@ -1286,6 +1287,75 @@ static CXLRetCode cmd_dcd_get_dyn_cap_config(const 
> struct cxl_cmd *cmd,
>  return CXL_MBOX_SUCCESS;
>  }
>  
> +/*
> + * CXL r3.0 section 8.2.9.8.9.2:
> + * Get Dynamic Capacity Extent List (Opcode 4810h)

4801h

> + */
> +static CXLRetCode cmd_dcd_get_dyn_cap_ext_list(const struct cxl_cmd *cmd,
> +   uint8_t *payload_in,
> +   size_t len_in,
> +   uint8_t *payload_out,
> +   size_t *len_out,
> +   CXLCCI *cci)
> +{
> +CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
> +struct get_dyn_cap_ext_list_in_pl {
> +uint32_t extent_cnt;
> +uint32_t start_extent_id;
> +} QEMU_PACKED;
> +
> +struct get_dyn_cap_ext_list_out_pl {
> +uint32_t count;
> +uint32_t total_extents;
> +uint32_t generation_num;
> +uint8_t rsvd[4];
> +CXLDCExtentRaw records[];
> +} QEMU_PACKED;
> +
> +struct get_dyn_cap_ext_list_in_pl *in = (void *)payload_in;
> +struct get_dyn_cap_ext_list_out_pl *out = (void *)payload_out;
> +uint16_t record_count = 0, i = 0, record_done = 0;
> +CXLDCDExtentList *extent_list = >dc.extents;
> +CXLDCDExtent *ent;
> +uint16_t out_pl_len;
> +uint32_t start_extent_id = in->start_extent_id;
> +
> +if (start_extent_id > ct3d->dc.total_extent_count) {
> +return CXL_MBOX_INVALID_INPUT;
> +}
> +
> +record_count = MIN(in->extent_cnt,
> +   ct3d->dc.total_extent_count - start_extent_id);
> +
> +out_pl_len = sizeof(*out) + record_count * sizeof(out->records[0]);
> +/* May need more processing here in the future */

Not sure what this comment is referring to... I'd be tempted to just
remove it.

> +assert(out_pl_len <= CXL_MAILBOX_MAX_PAYLOAD_SIZE);
> +
> +memset(out, 0, out_pl_len);

As before. It should be already zeroed.

> +stl_le_p(>count, record_count);
> +stl_le_p(>total_extents, ct3d->dc.total_extent_count);
> +stl_le_p(>generation_num, ct3d->dc.ext_list_gen_seq);
> +
> +if (record_count > 0) {
> +QTAILQ_FOREACH(ent, extent_list, node) {
> +if (i++ < start_extent_id) {
> +continue;
> +}
> +stq_le_p(>records[record_done].start_dpa, ent->start_dpa);
> +stq_le_p(>records[record_done].len, ent->len);
> +memcpy(>records[record_done].tag, ent->tag, 0x10);
> +stw_le_p(>records[record_done].shared_seq, ent->shared_seq);
> +record_done++;
> +if (record_done == record_count) {
> +break;
> +}
> +}
> +}
> +
> +*len_out = out_pl_len;
> +return CXL_MBOX_SUCCESS;
> +}
> +



> diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
> index 3dc6928bc5..5738c6f434 100644
> --- a/include/hw/cxl/cxl_device.h
> +++ b/include/hw/cxl/cxl_device.h
> @@ -420,6 +420,25 @@ typedef QLIST_HEAD(, CXLPoison) CXLPoisonList;
>  
>  #define DCD_MAX_REGION_NUM 8
>  
> +typedef struct CXLDCDExtentRaw {
> +uint64_t start_dpa;
> +uint64_t len;
> +uint8_t tag[0x10];
> +uint16_t shared_seq;
> +uint8_t rsvd[0x6];
> +} QEMU_PACKED CXLDCExtentRaw;
Naming mismatch.

> +
> +typedef struct CXLDCDExtent {
> +uint64_t start_dpa;
> +uint64_t len;
> +uint8_t tag[0x10];
> +uint16_t shared_seq;
> +uint8_t rsvd[0x6];
> +
> +QTAILQ_ENTRY(CXLDCDExtent) node;
> +} CXLDCDExtent;

DCD or DC?  I don't really care but inconsistent currently.

> +typedef QTAILQ_HEAD(, CXLDCDExtent) CXLDCDExtentList;
> +
>  typedef struct CXLDCDRegion {
>  uint64_t base;
>  uint64_t decode_len; /* aligned to 256*MiB */
> @@ -470,6 +489,10 @@ struct CXLType3Dev {
>  HostMemoryBackend *host_dc;
>  AddressSpace host_dc_as;
>  uint64_t 

[PATCH v3 6/9] hw/mem/cxl_type3: Add DC extent list representative and get DC extent list mailbox support

2023-11-07 Thread nifan . cxl
From: Fan Ni 

Add dynamic capacity extent list representative to the definition of
CXLType3Dev and add get DC extent list mailbox command per
CXL.spec.3.0:.8.2.9.8.9.2.

Signed-off-by: Fan Ni 
---
 hw/cxl/cxl-mailbox-utils.c  | 73 +
 hw/mem/cxl_type3.c  |  1 +
 include/hw/cxl/cxl_device.h | 23 
 3 files changed, 97 insertions(+)

diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 1f512b3e6b..56f4aa237a 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -82,6 +82,7 @@ enum {
 #define CLEAR_POISON   0x2
 DCD_CONFIG  = 0x48,
 #define GET_DC_CONFIG  0x0
+#define GET_DYN_CAP_EXT_LIST   0x1
 PHYSICAL_SWITCH = 0x51,
 #define IDENTIFY_SWITCH_DEVICE  0x0
 #define GET_PHYSICAL_PORT_STATE 0x1
@@ -1286,6 +1287,75 @@ static CXLRetCode cmd_dcd_get_dyn_cap_config(const 
struct cxl_cmd *cmd,
 return CXL_MBOX_SUCCESS;
 }
 
+/*
+ * CXL r3.0 section 8.2.9.8.9.2:
+ * Get Dynamic Capacity Extent List (Opcode 4810h)
+ */
+static CXLRetCode cmd_dcd_get_dyn_cap_ext_list(const struct cxl_cmd *cmd,
+   uint8_t *payload_in,
+   size_t len_in,
+   uint8_t *payload_out,
+   size_t *len_out,
+   CXLCCI *cci)
+{
+CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
+struct get_dyn_cap_ext_list_in_pl {
+uint32_t extent_cnt;
+uint32_t start_extent_id;
+} QEMU_PACKED;
+
+struct get_dyn_cap_ext_list_out_pl {
+uint32_t count;
+uint32_t total_extents;
+uint32_t generation_num;
+uint8_t rsvd[4];
+CXLDCExtentRaw records[];
+} QEMU_PACKED;
+
+struct get_dyn_cap_ext_list_in_pl *in = (void *)payload_in;
+struct get_dyn_cap_ext_list_out_pl *out = (void *)payload_out;
+uint16_t record_count = 0, i = 0, record_done = 0;
+CXLDCDExtentList *extent_list = >dc.extents;
+CXLDCDExtent *ent;
+uint16_t out_pl_len;
+uint32_t start_extent_id = in->start_extent_id;
+
+if (start_extent_id > ct3d->dc.total_extent_count) {
+return CXL_MBOX_INVALID_INPUT;
+}
+
+record_count = MIN(in->extent_cnt,
+   ct3d->dc.total_extent_count - start_extent_id);
+
+out_pl_len = sizeof(*out) + record_count * sizeof(out->records[0]);
+/* May need more processing here in the future */
+assert(out_pl_len <= CXL_MAILBOX_MAX_PAYLOAD_SIZE);
+
+memset(out, 0, out_pl_len);
+stl_le_p(>count, record_count);
+stl_le_p(>total_extents, ct3d->dc.total_extent_count);
+stl_le_p(>generation_num, ct3d->dc.ext_list_gen_seq);
+
+if (record_count > 0) {
+QTAILQ_FOREACH(ent, extent_list, node) {
+if (i++ < start_extent_id) {
+continue;
+}
+stq_le_p(>records[record_done].start_dpa, ent->start_dpa);
+stq_le_p(>records[record_done].len, ent->len);
+memcpy(>records[record_done].tag, ent->tag, 0x10);
+stw_le_p(>records[record_done].shared_seq, ent->shared_seq);
+record_done++;
+if (record_done == record_count) {
+break;
+}
+}
+}
+
+*len_out = out_pl_len;
+return CXL_MBOX_SUCCESS;
+}
+
 #define IMMEDIATE_CONFIG_CHANGE (1 << 1)
 #define IMMEDIATE_DATA_CHANGE (1 << 2)
 #define IMMEDIATE_POLICY_CHANGE (1 << 3)
@@ -1333,6 +1403,9 @@ static const struct cxl_cmd cxl_cmd_set[256][256] = {
 static const struct cxl_cmd cxl_cmd_set_dcd[256][256] = {
 [DCD_CONFIG][GET_DC_CONFIG] = { "DCD_GET_DC_CONFIG",
 cmd_dcd_get_dyn_cap_config, 2, 0 },
+[DCD_CONFIG][GET_DYN_CAP_EXT_LIST] = {
+"DCD_GET_DYNAMIC_CAPACITY_EXTENT_LIST", cmd_dcd_get_dyn_cap_ext_list,
+8, 0 },
 };
 
 static const struct cxl_cmd cxl_cmd_set_sw[256][256] = {
diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
index 152a51306d..c9d792a725 100644
--- a/hw/mem/cxl_type3.c
+++ b/hw/mem/cxl_type3.c
@@ -811,6 +811,7 @@ static int cxl_create_dc_regions(CXLType3Dev *ct3d)
 
 region_base += region->len;
 }
+QTAILQ_INIT(>dc.extents);
 
 return 0;
 }
diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
index 3dc6928bc5..5738c6f434 100644
--- a/include/hw/cxl/cxl_device.h
+++ b/include/hw/cxl/cxl_device.h
@@ -420,6 +420,25 @@ typedef QLIST_HEAD(, CXLPoison) CXLPoisonList;
 
 #define DCD_MAX_REGION_NUM 8
 
+typedef struct CXLDCDExtentRaw {
+uint64_t start_dpa;
+uint64_t len;
+uint8_t tag[0x10];
+uint16_t shared_seq;
+uint8_t rsvd[0x6];
+} QEMU_PACKED CXLDCExtentRaw;
+
+typedef struct CXLDCDExtent {
+uint64_t start_dpa;
+uint64_t len;
+uint8_t tag[0x10];
+uint16_t shared_seq;
+uint8_t rsvd[0x6];
+
+QTAILQ_ENTRY(CXLDCDExtent) node;
+}