|
|
88d66a |
From c5d4db8ba7b2f3964f12bcde5d8fa5f27aa6c500 Mon Sep 17 00:00:00 2001
|
|
|
88d66a |
From: Hiral Patel <patelhiral@fb.com>
|
|
|
88d66a |
Date: Sat, 18 Feb 2023 01:03:11 -0800
|
|
|
88d66a |
Subject: [PATCH 1/3] Added SPD decoding and dimm_slot_info CCI command support
|
|
|
88d66a |
|
|
|
88d66a |
---
|
|
|
88d66a |
cxl/builtin.h | 1 +
|
|
|
88d66a |
cxl/cxl.c | 1 +
|
|
|
88d66a |
cxl/lib/libcxl.c | 154 +++++++++++++++++++++++++++++++++++----------
|
|
|
88d66a |
cxl/lib/libcxl.sym | 1 +
|
|
|
88d66a |
cxl/libcxl.h | 1 +
|
|
|
88d66a |
cxl/memdev.c | 24 +++++++
|
|
|
88d66a |
6 files changed, 149 insertions(+), 33 deletions(-)
|
|
|
88d66a |
|
|
|
88d66a |
diff --git a/cxl/builtin.h b/cxl/builtin.h
|
|
|
88d66a |
index ca8be68..5775f4a 100644
|
|
|
88d66a |
--- a/cxl/builtin.h
|
|
|
88d66a |
+++ b/cxl/builtin.h
|
|
|
88d66a |
@@ -115,4 +115,5 @@ int cmd_osa_misc_trig_cfg(int argc, const char **argv, struct cxl_ctx *ctx);
|
|
|
88d66a |
int cmd_osa_data_read(int argc, const char **argv, struct cxl_ctx *ctx);
|
|
|
88d66a |
int cmd_dimm_spd_read(int argc, const char **argv, struct cxl_ctx *ctx);
|
|
|
88d66a |
int cmd_ddr_training_status(int argc, const char **argv, struct cxl_ctx *ctx);
|
|
|
88d66a |
+int cmd_dimm_slot_info(int argc, const char **argv, struct cxl_ctx *ctx);
|
|
|
88d66a |
#endif /* _CXL_BUILTIN_H_ */
|
|
|
88d66a |
diff --git a/cxl/cxl.c b/cxl/cxl.c
|
|
|
88d66a |
index e5b5732..4b430b5 100644
|
|
|
88d66a |
--- a/cxl/cxl.c
|
|
|
88d66a |
+++ b/cxl/cxl.c
|
|
|
88d66a |
@@ -171,6 +171,7 @@ static struct cmd_struct commands[] = {
|
|
|
88d66a |
{ "osa-data-read", .c_fn = cmd_osa_data_read },
|
|
|
88d66a |
{ "dimm-spd-read", .c_fn = cmd_dimm_spd_read },
|
|
|
88d66a |
{ "ddr-training-status", .c_fn = cmd_ddr_training_status },
|
|
|
88d66a |
+ { "dimm-slot-info", .c_fn = cmd_dimm_slot_info },
|
|
|
88d66a |
};
|
|
|
88d66a |
|
|
|
88d66a |
int main(int argc, const char **argv)
|
|
|
88d66a |
diff --git a/cxl/lib/libcxl.c b/cxl/lib/libcxl.c
|
|
|
88d66a |
index cd9fcb5..a65f14a 100644
|
|
|
88d66a |
--- a/cxl/lib/libcxl.c
|
|
|
88d66a |
+++ b/cxl/lib/libcxl.c
|
|
|
88d66a |
@@ -9646,6 +9646,26 @@ struct cxl_mbox_dimm_spd_read_in {
|
|
|
88d66a |
__le32 num_bytes;
|
|
|
88d66a |
} __attribute__((packed));
|
|
|
88d66a |
|
|
|
88d66a |
+#define SPD_MODULE_SERIAL_NUMBER_LEN (328 - 325 + 1) // 4 Bytes
|
|
|
88d66a |
+
|
|
|
88d66a |
+void static
|
|
|
88d66a |
+IntToString (u8 *String, u8 *Integer, u8 SizeInByte) {
|
|
|
88d66a |
+ u8 Index;
|
|
|
88d66a |
+
|
|
|
88d66a |
+ for (Index = 0; Index < SizeInByte; Index++) {
|
|
|
88d66a |
+ *(String + Index * 2) = (*(Integer + Index) >> 4) & 0x0F;
|
|
|
88d66a |
+ *(String + Index * 2 + 1) = *(Integer + Index) & 0x0F;
|
|
|
88d66a |
+ }
|
|
|
88d66a |
+ for (Index = 0; Index < (SizeInByte * 2); Index++) {
|
|
|
88d66a |
+ if (*(String + Index) >= 0x0A) {
|
|
|
88d66a |
+ *(String + Index) += 0x37;
|
|
|
88d66a |
+ } else {
|
|
|
88d66a |
+ *(String + Index) += 0x30;
|
|
|
88d66a |
+ }
|
|
|
88d66a |
+ }
|
|
|
88d66a |
+ *(String + SizeInByte * 2) = 0x0;
|
|
|
88d66a |
+}
|
|
|
88d66a |
+
|
|
|
88d66a |
static char * decode_ddr4_module_type(u8 *bytes) {
|
|
|
88d66a |
char *type;
|
|
|
88d66a |
switch (bytes[3]) {
|
|
|
88d66a |
@@ -9670,23 +9690,17 @@ static float ddr4_mtb_ftb_calc(unsigned char b1, signed char b2) {
|
|
|
88d66a |
return b1 * mtb + b2 * ftb;
|
|
|
88d66a |
}
|
|
|
88d66a |
|
|
|
88d66a |
-static void decode_ddr4_module_speed(u8 *bytes, float *ddr_clock, int *pc4_speed) {
|
|
|
88d66a |
+static int decode_ddr4_module_speed(u8 *bytes) {
|
|
|
88d66a |
float ctime;
|
|
|
88d66a |
float ddrclk;
|
|
|
88d66a |
- int tbits, pcclk;
|
|
|
88d66a |
|
|
|
88d66a |
ctime = ddr4_mtb_ftb_calc(bytes[18], bytes[125]);
|
|
|
88d66a |
ddrclk = 2 * (1000 / ctime);
|
|
|
88d66a |
- tbits = 8 << (bytes[13] & 7);
|
|
|
88d66a |
-
|
|
|
88d66a |
- pcclk = ddrclk * tbits / 8;
|
|
|
88d66a |
- pcclk -= pcclk % 100;
|
|
|
88d66a |
|
|
|
88d66a |
- if (ddr_clock) { *ddr_clock = (int)ddrclk; }
|
|
|
88d66a |
- if (pc4_speed) { *pc4_speed = pcclk; }
|
|
|
88d66a |
+ return ddrclk;
|
|
|
88d66a |
}
|
|
|
88d66a |
|
|
|
88d66a |
-static double decode_ddr4_module_size(u8 *bytes) {
|
|
|
88d66a |
+static int decode_ddr4_module_size(u8 *bytes) {
|
|
|
88d66a |
double size;
|
|
|
88d66a |
int sdrcap = 256 << (bytes[4] & 15);
|
|
|
88d66a |
int buswidth = 8 << (bytes[13] & 7);
|
|
|
88d66a |
@@ -9696,19 +9710,7 @@ static double decode_ddr4_module_size(u8 *bytes) {
|
|
|
88d66a |
|
|
|
88d66a |
if (signal_loading == 2) lranks_per_dimm *= ((bytes[6] >> 4) & 7) + 1;
|
|
|
88d66a |
size = sdrcap / 8 * buswidth / sdrwidth * lranks_per_dimm;
|
|
|
88d66a |
- return size;
|
|
|
88d66a |
-}
|
|
|
88d66a |
-
|
|
|
88d66a |
-
|
|
|
88d66a |
-static char * decode_ddr4_module_detail(u8 *bytes) {
|
|
|
88d66a |
- char *type_detail = malloc(256);
|
|
|
88d66a |
- float ddr_clock;
|
|
|
88d66a |
- int pc4_speed;
|
|
|
88d66a |
- if (type_detail) {
|
|
|
88d66a |
- decode_ddr4_module_speed(bytes, &ddr_clock, &pc4_speed);
|
|
|
88d66a |
- snprintf(type_detail, 255, "DDR4-%.0f (PC4-%d)", ddr_clock, pc4_speed);
|
|
|
88d66a |
- }
|
|
|
88d66a |
- return type_detail;
|
|
|
88d66a |
+ return (int) size/1024;
|
|
|
88d66a |
}
|
|
|
88d66a |
|
|
|
88d66a |
static char * decode_ddr4_manufacturer(u8 *bytes){
|
|
|
88d66a |
@@ -9729,7 +9731,7 @@ static char * decode_ddr4_manufacturer(u8 *bytes){
|
|
|
88d66a |
manufacturer = NULL;
|
|
|
88d66a |
return manufacturer;
|
|
|
88d66a |
}
|
|
|
88d66a |
- manufacturer = (char *) vendors[bank][index];
|
|
|
88d66a |
+ manufacturer = (char *) vendors[bank][index-1];
|
|
|
88d66a |
return manufacturer;
|
|
|
88d66a |
}
|
|
|
88d66a |
|
|
|
88d66a |
@@ -9776,8 +9778,8 @@ static int decode_ram_type(u8 *bytes) {
|
|
|
88d66a |
|
|
|
88d66a |
static const char *ram_types[] = {"Unknown", "Direct Rambus", "Rambus", "FPM DRAM",
|
|
|
88d66a |
"EDO", "Pipelined Nibble", "SDR SDRAM", "Multiplexed ROM",
|
|
|
88d66a |
- "DDR SGRAM", "DDR SDRAM", "DDR2 SDRAM", "DDR3 SDRAM",
|
|
|
88d66a |
- "DDR4 SDRAM"};
|
|
|
88d66a |
+ "DDR SGRAM", "DDR SDRAM", "DDR2", "DDR3",
|
|
|
88d66a |
+ "DDR4"};
|
|
|
88d66a |
|
|
|
88d66a |
CXL_EXPORT int cxl_memdev_dimm_spd_read(struct cxl_memdev *memdev,
|
|
|
88d66a |
u32 spd_id, u32 offset, u32 num_bytes)
|
|
|
88d66a |
@@ -9787,7 +9789,9 @@ CXL_EXPORT int cxl_memdev_dimm_spd_read(struct cxl_memdev *memdev,
|
|
|
88d66a |
struct cxl_command_info *cinfo;
|
|
|
88d66a |
struct cxl_mbox_dimm_spd_read_in *dimm_spd_read_in;
|
|
|
88d66a |
u8 *dimm_spd_read_out;
|
|
|
88d66a |
+ u8 serial[9];
|
|
|
88d66a |
int rc = 0;
|
|
|
88d66a |
+ int buswidth;
|
|
|
88d66a |
RamType ram_type;
|
|
|
88d66a |
|
|
|
88d66a |
cmd = cxl_cmd_new_raw(memdev, CXL_MEM_COMMAND_ID_DIMM_SPD_READ_OPCODE);
|
|
|
88d66a |
@@ -9838,6 +9842,7 @@ CXL_EXPORT int cxl_memdev_dimm_spd_read(struct cxl_memdev *memdev,
|
|
|
88d66a |
|
|
|
88d66a |
dimm_spd_read_out = (u8*)cmd->send_cmd->out.payload;
|
|
|
88d66a |
ram_type = decode_ram_type(dimm_spd_read_out);
|
|
|
88d66a |
+
|
|
|
88d66a |
fprintf(stdout, "=========================== DIMM SPD READ Data ============================\n");
|
|
|
88d66a |
fprintf(stdout, "Output Payload:");
|
|
|
88d66a |
for(int i=0; i<cmd->send_cmd->out.size; i++){
|
|
|
88d66a |
@@ -9850,15 +9855,25 @@ CXL_EXPORT int cxl_memdev_dimm_spd_read(struct cxl_memdev *memdev,
|
|
|
88d66a |
fprintf(stdout, "%02x ", dimm_spd_read_out[i]);
|
|
|
88d66a |
}
|
|
|
88d66a |
}
|
|
|
88d66a |
+
|
|
|
88d66a |
// Decoding SPD data for only DDR4 SDRAM.
|
|
|
88d66a |
- if (ram_type == DDR4_SDRAM) {
|
|
|
88d66a |
- fprintf(stdout, "\n\n");
|
|
|
88d66a |
- fprintf(stdout, "DDR RAM Type: %s\n", ram_types[ram_type]);
|
|
|
88d66a |
- fprintf(stdout, "DDR Module Type: %s\n", decode_ddr4_module_type(dimm_spd_read_out));
|
|
|
88d66a |
- fprintf(stdout, "DDR Module Size: %1f\n", decode_ddr4_module_size(dimm_spd_read_out));
|
|
|
88d66a |
- fprintf(stdout, "DDR Module Detail: %s\n", decode_ddr4_module_detail(dimm_spd_read_out));
|
|
|
88d66a |
- fprintf(stdout, "DDR Manufacturer: %s\n", decode_ddr4_manufacturer(dimm_spd_read_out));
|
|
|
88d66a |
- }
|
|
|
88d66a |
+
|
|
|
88d66a |
+ buswidth = 8 << (dimm_spd_read_out[13] & 7);
|
|
|
88d66a |
+
|
|
|
88d66a |
+ fprintf(stdout, "Total Width: %s\n", "TBD");
|
|
|
88d66a |
+ fprintf(stdout, "Data Width: %d bits\n", buswidth);
|
|
|
88d66a |
+ fprintf(stdout, "Size: %d GB\n", decode_ddr4_module_size(dimm_spd_read_out));
|
|
|
88d66a |
+ fprintf(stdout, "Form Factor: %s\n", "TBD");
|
|
|
88d66a |
+ fprintf(stdout, "Set: %s\n", "TBD");
|
|
|
88d66a |
+ fprintf(stdout, "Locator: %s\n", "DIMM_X");
|
|
|
88d66a |
+ fprintf(stdout, "Bank Locator: %s\n", "_Node1_ChannelX_DimmX");
|
|
|
88d66a |
+ fprintf(stdout, "Type: %s\n", ram_types[ram_type]);
|
|
|
88d66a |
+ fprintf(stdout, "Type Detail: %s\n", decode_ddr4_module_type(dimm_spd_read_out));
|
|
|
88d66a |
+ fprintf(stdout, "Speed: %d MT/s\n", decode_ddr4_module_speed(dimm_spd_read_out));
|
|
|
88d66a |
+ fprintf(stdout, "Manufacturer: %s\n", decode_ddr4_manufacturer(dimm_spd_read_out));
|
|
|
88d66a |
+ IntToString(serial, &dimm_spd_read_out[325], SPD_MODULE_SERIAL_NUMBER_LEN);
|
|
|
88d66a |
+ fprintf(stdout, "Serial Number: %s\n", serial);
|
|
|
88d66a |
+ fprintf(stdout, "Asset Tag: %s\n", "TBD");
|
|
|
88d66a |
|
|
|
88d66a |
out:
|
|
|
88d66a |
cxl_cmd_unref(cmd);
|
|
|
88d66a |
@@ -9946,3 +9961,76 @@ out:
|
|
|
88d66a |
cxl_cmd_unref(cmd);
|
|
|
88d66a |
return rc;
|
|
|
88d66a |
}
|
|
|
88d66a |
+
|
|
|
88d66a |
+#define CXL_MEM_COMMAND_ID_DIMM_SLOT_INFO CXL_MEM_COMMAND_ID_RAW
|
|
|
88d66a |
+#define CXL_MEM_COMMAND_ID_DIMM_SLOT_INFO_OPCODE 0xC520
|
|
|
88d66a |
+#define CXL_MEM_COMMAND_ID_DIMM_SLOT_INFO_PAYLOAD_IN_SIZE 0
|
|
|
88d66a |
+
|
|
|
88d66a |
+CXL_EXPORT int cxl_memdev_dimm_slot_info(struct cxl_memdev *memdev)
|
|
|
88d66a |
+{
|
|
|
88d66a |
+ struct cxl_cmd *cmd;
|
|
|
88d66a |
+ struct cxl_mem_query_commands *query;
|
|
|
88d66a |
+ struct cxl_command_info *cinfo;
|
|
|
88d66a |
+ u8 *dimm_slot_info;
|
|
|
88d66a |
+ int rc = 0;
|
|
|
88d66a |
+ int offset = 0;
|
|
|
88d66a |
+
|
|
|
88d66a |
+
|
|
|
88d66a |
+ cmd = cxl_cmd_new_raw(memdev, CXL_MEM_COMMAND_ID_DIMM_SLOT_INFO_OPCODE);
|
|
|
88d66a |
+ if (!cmd) {
|
|
|
88d66a |
+ fprintf(stderr, "%s: cxl_cmd_new_raw returned Null output\n",
|
|
|
88d66a |
+ cxl_memdev_get_devname(memdev));
|
|
|
88d66a |
+ return -ENOMEM;
|
|
|
88d66a |
+ }
|
|
|
88d66a |
+
|
|
|
88d66a |
+ query = cmd->query_cmd;
|
|
|
88d66a |
+ cinfo = &query->commands[cmd->query_idx];
|
|
|
88d66a |
+
|
|
|
88d66a |
+ cinfo->size_in = CXL_MEM_COMMAND_ID_LOG_INFO_PAYLOAD_IN_SIZE;
|
|
|
88d66a |
+ if (cinfo->size_in > 0) {
|
|
|
88d66a |
+ cmd->input_payload = calloc(1, cinfo->size_in);
|
|
|
88d66a |
+ if (!cmd->input_payload)
|
|
|
88d66a |
+ return -ENOMEM;
|
|
|
88d66a |
+ cmd->send_cmd->in.payload = (u64)cmd->input_payload;
|
|
|
88d66a |
+ cmd->send_cmd->in.size = cinfo->size_in;
|
|
|
88d66a |
+ }
|
|
|
88d66a |
+
|
|
|
88d66a |
+ rc = cxl_cmd_submit(cmd);
|
|
|
88d66a |
+ if (rc < 0) {
|
|
|
88d66a |
+ fprintf(stderr, "%s: cmd submission failed: %d (%s)\n",
|
|
|
88d66a |
+ cxl_memdev_get_devname(memdev), rc, strerror(-rc));
|
|
|
88d66a |
+ goto out;
|
|
|
88d66a |
+ }
|
|
|
88d66a |
+
|
|
|
88d66a |
+ rc = cxl_cmd_get_mbox_status(cmd);
|
|
|
88d66a |
+ if (rc != 0) {
|
|
|
88d66a |
+ fprintf(stderr, "%s: firmware status: %d:\n%s\n",
|
|
|
88d66a |
+ cxl_memdev_get_devname(memdev), rc, DEVICE_ERRORS[rc]);
|
|
|
88d66a |
+ rc = -ENXIO;
|
|
|
88d66a |
+ goto out;
|
|
|
88d66a |
+ }
|
|
|
88d66a |
+
|
|
|
88d66a |
+ if (cmd->send_cmd->id != CXL_MEM_COMMAND_ID_DIMM_SLOT_INFO) {
|
|
|
88d66a |
+ fprintf(stderr, "%s: invalid command id 0x%x (expecting 0x%x)\n",
|
|
|
88d66a |
+ cxl_memdev_get_devname(memdev), cmd->send_cmd->id, CXL_MEM_COMMAND_ID_DIMM_SLOT_INFO);
|
|
|
88d66a |
+ return -EINVAL;
|
|
|
88d66a |
+ }
|
|
|
88d66a |
+
|
|
|
88d66a |
+ dimm_slot_info = (u8*)cmd->send_cmd->out.payload;
|
|
|
88d66a |
+ fprintf(stdout, "=========================== DIMM SLOT INFO ============================\n");
|
|
|
88d66a |
+ fprintf(stdout, "Output Payload:\n");
|
|
|
88d66a |
+ for(int i=0; i<cmd->send_cmd->out.size; i++){
|
|
|
88d66a |
+ if (i % 16 == 0)
|
|
|
88d66a |
+ {
|
|
|
88d66a |
+ fprintf(stdout, "\n%04x %02x ", i+offset, dimm_slot_info[i]);
|
|
|
88d66a |
+ }
|
|
|
88d66a |
+ else
|
|
|
88d66a |
+ {
|
|
|
88d66a |
+ fprintf(stdout, "%02x ", dimm_slot_info[i]);
|
|
|
88d66a |
+ }
|
|
|
88d66a |
+ }
|
|
|
88d66a |
+ fprintf(stdout, "\n");
|
|
|
88d66a |
+out:
|
|
|
88d66a |
+ cxl_cmd_unref(cmd);
|
|
|
88d66a |
+ return rc;
|
|
|
88d66a |
+}
|
|
|
88d66a |
diff --git a/cxl/lib/libcxl.sym b/cxl/lib/libcxl.sym
|
|
|
88d66a |
index e68bd89..aaf2d65 100644
|
|
|
88d66a |
--- a/cxl/lib/libcxl.sym
|
|
|
88d66a |
+++ b/cxl/lib/libcxl.sym
|
|
|
88d66a |
@@ -168,4 +168,5 @@ global:
|
|
|
88d66a |
cxl_memdev_osa_data_read;
|
|
|
88d66a |
cxl_memdev_dimm_spd_read;
|
|
|
88d66a |
cxl_memdev_ddr_training_status;
|
|
|
88d66a |
+ cxl_memdev_dimm_slot_info;
|
|
|
88d66a |
} LIBCXL_3;
|
|
|
88d66a |
diff --git a/cxl/libcxl.h b/cxl/libcxl.h
|
|
|
88d66a |
index 498de7d..0c24579 100644
|
|
|
88d66a |
--- a/cxl/libcxl.h
|
|
|
88d66a |
+++ b/cxl/libcxl.h
|
|
|
88d66a |
@@ -235,6 +235,7 @@ int cxl_memdev_osa_data_read(struct cxl_memdev *memdev, u8 cxl_mem_id,
|
|
|
88d66a |
int cxl_memdev_dimm_spd_read(struct cxl_memdev *memdev, u32 spd_id,
|
|
|
88d66a |
u32 offset, u32 num_bytes);
|
|
|
88d66a |
int cxl_memdev_ddr_training_status(struct cxl_memdev *memdev);
|
|
|
88d66a |
+int cxl_memdev_dimm_slot_info(struct cxl_memdev *memdev);
|
|
|
88d66a |
|
|
|
88d66a |
#define cxl_memdev_foreach(ctx, memdev) \
|
|
|
88d66a |
for (memdev = cxl_memdev_get_first(ctx); \
|
|
|
88d66a |
diff --git a/cxl/memdev.c b/cxl/memdev.c
|
|
|
88d66a |
index d3a6f67..64ba7e0 100644
|
|
|
88d66a |
--- a/cxl/memdev.c
|
|
|
88d66a |
+++ b/cxl/memdev.c
|
|
|
88d66a |
@@ -1895,6 +1895,11 @@ static const struct option cmd_ddr_training_status_options[] = {
|
|
|
88d66a |
OPT_END(),
|
|
|
88d66a |
};
|
|
|
88d66a |
|
|
|
88d66a |
+static const struct option cmd_dimm_slot_info_options[] = {
|
|
|
88d66a |
+ BASE_OPTIONS(),
|
|
|
88d66a |
+ OPT_END(),
|
|
|
88d66a |
+};
|
|
|
88d66a |
+
|
|
|
88d66a |
static int action_cmd_clear_event_records(struct cxl_memdev *memdev, struct action_context *actx)
|
|
|
88d66a |
{
|
|
|
88d66a |
u16 record_handle;
|
|
|
88d66a |
@@ -3438,6 +3443,17 @@ static int action_cmd_ddr_training_status(struct cxl_memdev *memdev, struct acti
|
|
|
88d66a |
return cxl_memdev_ddr_training_status(memdev);
|
|
|
88d66a |
}
|
|
|
88d66a |
|
|
|
88d66a |
+static int action_cmd_dimm_slot_info(struct cxl_memdev *memdev, struct action_context *actx)
|
|
|
88d66a |
+{
|
|
|
88d66a |
+ if (cxl_memdev_is_active(memdev)) {
|
|
|
88d66a |
+ fprintf(stderr, "%s: memdev active, abort dimm_slot_info\n",
|
|
|
88d66a |
+ cxl_memdev_get_devname(memdev));
|
|
|
88d66a |
+ return -EBUSY;
|
|
|
88d66a |
+ }
|
|
|
88d66a |
+
|
|
|
88d66a |
+ return cxl_memdev_dimm_slot_info(memdev);
|
|
|
88d66a |
+}
|
|
|
88d66a |
+
|
|
|
88d66a |
static int action_write(struct cxl_memdev *memdev, struct action_context *actx)
|
|
|
88d66a |
{
|
|
|
88d66a |
size_t size = param.len, read_len;
|
|
|
88d66a |
@@ -4495,3 +4511,11 @@ int cmd_ddr_training_status(int argc, const char **argv, struct cxl_ctx *ctx)
|
|
|
88d66a |
|
|
|
88d66a |
return rc >= 0 ? 0 : EXIT_FAILURE;
|
|
|
88d66a |
}
|
|
|
88d66a |
+
|
|
|
88d66a |
+int cmd_dimm_slot_info(int argc, const char **argv, struct cxl_ctx *ctx)
|
|
|
88d66a |
+{
|
|
|
88d66a |
+ int rc = memdev_action(argc, argv, ctx, action_cmd_dimm_slot_info, cmd_dimm_slot_info_options,
|
|
|
88d66a |
+ "cxl ddr-slot-info <mem0> [<mem1>..<memN>] [<options>]");
|
|
|
88d66a |
+
|
|
|
88d66a |
+ return rc >= 0 ? 0 : EXIT_FAILURE;
|
|
|
88d66a |
+}
|
|
|
88d66a |
--
|
|
|
88d66a |
2.39.2
|
|
|
88d66a |
|
|
|
88d66a |
|
|
|
88d66a |
From 86dc9d17c940b400bee7452121e64419e858cc8d Mon Sep 17 00:00:00 2001
|
|
|
88d66a |
From: Hiral Patel <patelhiral@fb.com>
|
|
|
88d66a |
Date: Sat, 18 Feb 2023 01:10:13 -0800
|
|
|
88d66a |
Subject: [PATCH 2/3] fix stdout format
|
|
|
88d66a |
|
|
|
88d66a |
---
|
|
|
88d66a |
cxl/lib/libcxl.c | 1 +
|
|
|
88d66a |
1 file changed, 1 insertion(+)
|
|
|
88d66a |
|
|
|
88d66a |
diff --git a/cxl/lib/libcxl.c b/cxl/lib/libcxl.c
|
|
|
88d66a |
index a65f14a..2a1b6f6 100644
|
|
|
88d66a |
--- a/cxl/lib/libcxl.c
|
|
|
88d66a |
+++ b/cxl/lib/libcxl.c
|
|
|
88d66a |
@@ -9855,6 +9855,7 @@ CXL_EXPORT int cxl_memdev_dimm_spd_read(struct cxl_memdev *memdev,
|
|
|
88d66a |
fprintf(stdout, "%02x ", dimm_spd_read_out[i]);
|
|
|
88d66a |
}
|
|
|
88d66a |
}
|
|
|
88d66a |
+ fprintf(stdout, "\n\n");
|
|
|
88d66a |
|
|
|
88d66a |
// Decoding SPD data for only DDR4 SDRAM.
|
|
|
88d66a |
|
|
|
88d66a |
--
|
|
|
88d66a |
2.39.2
|
|
|
88d66a |
|
|
|
88d66a |
|
|
|
88d66a |
From 7fcbe3d7dc7eff5673baf2c55ec7f59e68a3bda6 Mon Sep 17 00:00:00 2001
|
|
|
88d66a |
From: Panos Christeas <xrg@meta.com>
|
|
|
88d66a |
Date: Mon, 20 Feb 2023 15:39:16 +0000
|
|
|
88d66a |
Subject: [PATCH 3/3] add separator between SPD payload and decoding
|
|
|
88d66a |
|
|
|
88d66a |
Summary:
|
|
|
88d66a |
Printing the SPD decoding would be on the same last line of hex payload,
|
|
|
88d66a |
giving the parser a headache.
|
|
|
88d66a |
Just add a separator
|
|
|
88d66a |
|
|
|
88d66a |
Test Plan:
|
|
|
88d66a |
before:
|
|
|
88d66a |
```
|
|
|
88d66a |
cxl dimm-spd-read mem0 -s 0 -o 0 -n 512
|
|
|
88d66a |
=========================== DIMM SPD READ Data ============================
|
|
|
88d66a |
Output Payload:
|
|
|
88d66a |
0000 23 11 0c 01 85 ...
|
|
|
88d66a |
...
|
|
|
88d66a |
01f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Total Width: TBD
|
|
|
88d66a |
Data Width: 64 bits
|
|
|
88d66a |
Size: ...
|
|
|
88d66a |
|
|
|
88d66a |
```
|
|
|
88d66a |
|
|
|
88d66a |
After:
|
|
|
88d66a |
```
|
|
|
88d66a |
========================= DIMM SPD READ Data ============================
|
|
|
88d66a |
Output Payload:
|
|
|
88d66a |
0000 23 11 0c 01 85 ...
|
|
|
88d66a |
...
|
|
|
88d66a |
01f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
|
|
88d66a |
|
|
|
88d66a |
====== DIMM SPD DECODE ============
|
|
|
88d66a |
Total Width: TBD
|
|
|
88d66a |
Data Width: 64 bits
|
|
|
88d66a |
Size: ...
|
|
|
88d66a |
Form Factor: TBD
|
|
|
88d66a |
Set: TBD
|
|
|
88d66a |
Locator: ...
|
|
|
88d66a |
```
|
|
|
88d66a |
|
|
|
88d66a |
Reviewers:
|
|
|
88d66a |
|
|
|
88d66a |
Subscribers:
|
|
|
88d66a |
|
|
|
88d66a |
Tasks:
|
|
|
88d66a |
|
|
|
88d66a |
Tags:
|
|
|
88d66a |
---
|
|
|
88d66a |
cxl/lib/libcxl.c | 1 +
|
|
|
88d66a |
1 file changed, 1 insertion(+)
|
|
|
88d66a |
|
|
|
88d66a |
diff --git a/cxl/lib/libcxl.c b/cxl/lib/libcxl.c
|
|
|
88d66a |
index 2a1b6f6..8d39d2c 100644
|
|
|
88d66a |
--- a/cxl/lib/libcxl.c
|
|
|
88d66a |
+++ b/cxl/lib/libcxl.c
|
|
|
88d66a |
@@ -9861,6 +9861,7 @@ CXL_EXPORT int cxl_memdev_dimm_spd_read(struct cxl_memdev *memdev,
|
|
|
88d66a |
|
|
|
88d66a |
buswidth = 8 << (dimm_spd_read_out[13] & 7);
|
|
|
88d66a |
|
|
|
88d66a |
+ fprintf(stdout, "\n\n====== DIMM SPD DECODE ============\n");
|
|
|
88d66a |
fprintf(stdout, "Total Width: %s\n", "TBD");
|
|
|
88d66a |
fprintf(stdout, "Data Width: %d bits\n", buswidth);
|
|
|
88d66a |
fprintf(stdout, "Size: %d GB\n", decode_ddr4_module_size(dimm_spd_read_out));
|
|
|
88d66a |
--
|
|
|
88d66a |
2.39.2
|
|
|
88d66a |
|