All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drm/amdgpu: Add vbios info ioctl interface
@ 2021-05-18 12:16 Jiawei Gu
  2021-05-18 12:19 ` Gu, JiaWei (Will)
  0 siblings, 1 reply; 47+ messages in thread
From: Jiawei Gu @ 2021-05-18 12:16 UTC (permalink / raw)
  To: amd-gfx, christian.koenig, david.nieto, maraeo, alexander.deucher
  Cc: emily.deng, Jiawei Gu

Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.

Provides a way for the user application to get the VBIOS
information without having to parse the binary.
It is useful for the user to be able to display in a simple way the VBIOS
version in their system if they happen to encounter an issue.

V2:
Use numeric serial.
Parse and expose vbios version string.

V3:
Remove redundant data in drm_amdgpu_info_vbios struct.

Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  15 ++
 drivers/gpu/drm/amd/amdgpu/atom.c          | 172 +++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/atom.h          |  10 ++
 drivers/gpu/drm/amd/include/atomfirmware.h |   5 +
 include/uapi/drm/amdgpu_drm.h              |  10 ++
 5 files changed, 212 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 8d12e474745a..524e4fe5efe8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -861,6 +861,21 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
 					    min((size_t)size, (size_t)(bios_size - bios_offset)))
 					? -EFAULT : 0;
 		}
+		case AMDGPU_INFO_VBIOS_INFO: {
+			struct drm_amdgpu_info_vbios vbios_info = {};
+			struct atom_context *atom_context;
+
+			atom_context = adev->mode_info.atom_context;
+			memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
+			memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
+			vbios_info.version = atom_context->version;
+			memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str,
+						sizeof(atom_context->vbios_ver_str));
+			memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
+
+			return copy_to_user(out, &vbios_info,
+						min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
+		}
 		default:
 			DRM_DEBUG_KMS("Invalid request %d\n",
 					info->vbios_info.type);
diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c
index 3dcb8b32f48b..6fa2229b7229 100644
--- a/drivers/gpu/drm/amd/amdgpu/atom.c
+++ b/drivers/gpu/drm/amd/amdgpu/atom.c
@@ -31,6 +31,7 @@
 
 #define ATOM_DEBUG
 
+#include "atomfirmware.h"
 #include "atom.h"
 #include "atom-names.h"
 #include "atom-bits.h"
@@ -1299,12 +1300,168 @@ static void atom_index_iio(struct atom_context *ctx, int base)
 	}
 }
 
+static void atom_get_vbios_name(struct atom_context *ctx)
+{
+	unsigned char *p_rom;
+	unsigned char str_num;
+	unsigned short off_to_vbios_str;
+	unsigned char *c_ptr;
+	int name_size;
+	int i;
+
+	const char *na = "--N/A--";
+	char *back;
+
+	p_rom = ctx->bios;
+
+	str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
+	if (str_num != 0) {
+		off_to_vbios_str =
+			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
+
+		c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
+	} else {
+		/* do not know where to find name */
+		memcpy(ctx->name, na, 7);
+		ctx->name[7] = 0;
+		return;
+	}
+
+	/*
+	 * skip the atombios strings, usually 4
+	 * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
+	 */
+	for (i = 0; i < str_num; i++) {
+		while (*c_ptr != 0)
+			c_ptr++;
+		c_ptr++;
+	}
+
+	/* skip the following 2 chars: 0x0D 0x0A */
+	c_ptr += 2;
+
+	name_size = strnlen(c_ptr, STRLEN_LONG - 1);
+	memcpy(ctx->name, c_ptr, name_size);
+	back = ctx->name + name_size;
+	while ((*--back) == ' ')
+		;
+	*(back + 1) = '\0';
+}
+
+static void atom_get_vbios_date(struct atom_context *ctx)
+{
+	unsigned char *p_rom;
+	unsigned char *date_in_rom;
+
+	p_rom = ctx->bios;
+
+	date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
+
+	ctx->date[0] = '2';
+	ctx->date[1] = '0';
+	ctx->date[2] = date_in_rom[6];
+	ctx->date[3] = date_in_rom[7];
+	ctx->date[4] = '/';
+	ctx->date[5] = date_in_rom[0];
+	ctx->date[6] = date_in_rom[1];
+	ctx->date[7] = '/';
+	ctx->date[8] = date_in_rom[3];
+	ctx->date[9] = date_in_rom[4];
+	ctx->date[10] = ' ';
+	ctx->date[11] = date_in_rom[9];
+	ctx->date[12] = date_in_rom[10];
+	ctx->date[13] = date_in_rom[11];
+	ctx->date[14] = date_in_rom[12];
+	ctx->date[15] = date_in_rom[13];
+	ctx->date[16] = '\0';
+}
+
+static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
+					   int end, int maxlen)
+{
+	unsigned long str_off;
+	unsigned char *p_rom;
+	unsigned short str_len;
+
+	str_off = 0;
+	str_len = strnlen(str, maxlen);
+	p_rom = ctx->bios;
+
+	for (; start <= end; ++start) {
+		for (str_off = 0; str_off < str_len; ++str_off) {
+			if (str[str_off] != *(p_rom + start + str_off))
+				break;
+		}
+
+		if (str_off == str_len || str[str_off] == 0)
+			return p_rom + start;
+	}
+	return NULL;
+}
+
+static void atom_get_vbios_pn(struct atom_context *ctx)
+{
+	unsigned char *p_rom;
+	unsigned short off_to_vbios_str;
+	unsigned char *vbios_str;
+	int count;
+
+	off_to_vbios_str = 0;
+	p_rom = ctx->bios;
+
+	if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
+		off_to_vbios_str =
+			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
+
+		vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
+	} else {
+		vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
+	}
+
+	if (*vbios_str == 0) {
+		vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
+		if (vbios_str == NULL)
+			vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
+	}
+	if (vbios_str != NULL && *vbios_str == 0)
+		vbios_str++;
+
+	if (vbios_str != NULL) {
+		count = 0;
+		while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
+		       vbios_str[count] <= 'z') {
+			ctx->vbios_pn[count] = vbios_str[count];
+			count++;
+		}
+
+		ctx->vbios_pn[count] = 0;
+	}
+}
+
+static void atom_get_vbios_version(struct atom_context *ctx)
+{
+	unsigned char *vbios_ver;
+
+	/* find anchor ATOMBIOSBK-AMD */
+	vbios_ver = atom_find_str_in_rom(ctx, BIOS_VERSION_PREFIX, 3, 1024, 64);
+	if (vbios_ver != NULL) {
+		/* skip ATOMBIOSBK-AMD VER */
+		vbios_ver += 18;
+		memcpy(ctx->vbios_ver_str, vbios_ver, STRLEN_NORMAL);
+	} else {
+		ctx->vbios_ver_str[0] = '\0';
+	}
+}
+
 struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
 {
 	int base;
 	struct atom_context *ctx =
 	    kzalloc(sizeof(struct atom_context), GFP_KERNEL);
 	char *str;
+	struct _ATOM_ROM_HEADER *atom_rom_header;
+	struct _ATOM_MASTER_DATA_TABLE *master_table;
+	struct _ATOM_FIRMWARE_INFO *atom_fw_info;
 	u16 idx;
 
 	if (!ctx)
@@ -1353,6 +1510,21 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
 		strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
 	}
 
+	atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
+	if (atom_rom_header->usMasterDataTableOffset != 0) {
+		master_table = (struct _ATOM_MASTER_DATA_TABLE *)
+				CSTR(atom_rom_header->usMasterDataTableOffset);
+		if (master_table->ListOfDataTables.FirmwareInfo != 0) {
+			atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
+					CSTR(master_table->ListOfDataTables.FirmwareInfo);
+			ctx->version = atom_fw_info->ulFirmwareRevision;
+		}
+	}
+
+	atom_get_vbios_name(ctx);
+	atom_get_vbios_pn(ctx);
+	atom_get_vbios_date(ctx);
+	atom_get_vbios_version(ctx);
 
 	return ctx;
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h
index d279759cab47..0c1839824520 100644
--- a/drivers/gpu/drm/amd/amdgpu/atom.h
+++ b/drivers/gpu/drm/amd/amdgpu/atom.h
@@ -112,6 +112,10 @@ struct drm_device;
 #define ATOM_IO_SYSIO		2
 #define ATOM_IO_IIO		0x80
 
+#define STRLEN_NORMAL		32
+#define STRLEN_LONG		64
+#define STRLEN_VERYLONG		254
+
 struct card_info {
 	struct drm_device *dev;
 	void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
@@ -140,6 +144,12 @@ struct atom_context {
 	uint32_t *scratch;
 	int scratch_size_bytes;
 	char vbios_version[20];
+
+	uint8_t name[STRLEN_LONG];
+	uint8_t vbios_pn[STRLEN_LONG];
+	uint32_t version;
+	uint8_t vbios_ver_str[STRLEN_NORMAL];
+	uint8_t date[STRLEN_NORMAL];
 };
 
 extern int amdgpu_atom_debug;
diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
index 275468e4be60..28deecc2f990 100644
--- a/drivers/gpu/drm/amd/include/atomfirmware.h
+++ b/drivers/gpu/drm/amd/include/atomfirmware.h
@@ -197,6 +197,9 @@ enum atom_dp_vs_preemph_def{
   DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
 };
 
+#define BIOS_ATOM_PREFIX   "ATOMBIOS"
+#define BIOS_VERSION_PREFIX  "ATOMBIOSBK-AMD"
+#define BIOS_STRING_LENGTH 43
 
 /*
 enum atom_string_def{
@@ -215,6 +218,8 @@ enum atombios_image_offset{
   MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
   OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
   OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
+  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
+  OFFSET_TO_VBIOS_DATE                       = 0x50,
 };
 
 /****************************************************************************   
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index 9169df7fadee..155fd9918b4d 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -756,6 +756,8 @@ struct drm_amdgpu_cs_chunk_data {
 	#define AMDGPU_INFO_VBIOS_SIZE		0x1
 	/* Subquery id: Query vbios image */
 	#define AMDGPU_INFO_VBIOS_IMAGE		0x2
+	/* Subquery id: Query vbios info */
+	#define AMDGPU_INFO_VBIOS_INFO		0x3
 /* Query UVD handles */
 #define AMDGPU_INFO_NUM_HANDLES			0x1C
 /* Query sensor related information */
@@ -949,6 +951,14 @@ struct drm_amdgpu_info_firmware {
 	__u32 feature;
 };
 
+struct drm_amdgpu_info_vbios {
+	__u8 name[64];
+	__u8 vbios_pn[64];
+	__u32 version;
+	__u8 vbios_ver_str[32];
+	__u8 date[32];
+};
+
 #define AMDGPU_VRAM_TYPE_UNKNOWN 0
 #define AMDGPU_VRAM_TYPE_GDDR1 1
 #define AMDGPU_VRAM_TYPE_DDR2  2
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-05-18 12:16 [PATCH] drm/amdgpu: Add vbios info ioctl interface Jiawei Gu
@ 2021-05-18 12:19 ` Gu, JiaWei (Will)
  2021-05-18 13:17   ` Christian König
  0 siblings, 1 reply; 47+ messages in thread
From: Gu, JiaWei (Will) @ 2021-05-18 12:19 UTC (permalink / raw)
  To: Gu, JiaWei (Will),
	amd-gfx, Koenig, Christian, Nieto, David M, maraeo, Deucher,
	Alexander
  Cc: Deng, Emily

[AMD Official Use Only - Internal Distribution Only]

Hi all,

Please help confirm that we're all fine with this new struct in uapi in this V3 patch:

+struct drm_amdgpu_info_vbios {
+	__u8 name[64];
+	__u8 vbios_pn[64];
+	__u32 version;
+	__u8 vbios_ver_str[32];
+	__u8 date[32];
+};

Best regards,
Jiawei

-----Original Message-----
From: Jiawei Gu <Jiawei.Gu@amd.com> 
Sent: Tuesday, May 18, 2021 8:16 PM
To: amd-gfx@lists.freedesktop.org; Koenig, Christian <Christian.Koenig@amd.com>; Nieto, David M <David.Nieto@amd.com>; maraeo@gmail.com; Deucher, Alexander <Alexander.Deucher@amd.com>
Cc: Deng, Emily <Emily.Deng@amd.com>; Gu, JiaWei (Will) <JiaWei.Gu@amd.com>
Subject: [PATCH] drm/amdgpu: Add vbios info ioctl interface

Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.

Provides a way for the user application to get the VBIOS information without having to parse the binary.
It is useful for the user to be able to display in a simple way the VBIOS version in their system if they happen to encounter an issue.

V2:
Use numeric serial.
Parse and expose vbios version string.

V3:
Remove redundant data in drm_amdgpu_info_vbios struct.

Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  15 ++
 drivers/gpu/drm/amd/amdgpu/atom.c          | 172 +++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/atom.h          |  10 ++
 drivers/gpu/drm/amd/include/atomfirmware.h |   5 +
 include/uapi/drm/amdgpu_drm.h              |  10 ++
 5 files changed, 212 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 8d12e474745a..524e4fe5efe8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -861,6 +861,21 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
 					    min((size_t)size, (size_t)(bios_size - bios_offset)))
 					? -EFAULT : 0;
 		}
+		case AMDGPU_INFO_VBIOS_INFO: {
+			struct drm_amdgpu_info_vbios vbios_info = {};
+			struct atom_context *atom_context;
+
+			atom_context = adev->mode_info.atom_context;
+			memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
+			memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
+			vbios_info.version = atom_context->version;
+			memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str,
+						sizeof(atom_context->vbios_ver_str));
+			memcpy(vbios_info.date, atom_context->date, 
+sizeof(atom_context->date));
+
+			return copy_to_user(out, &vbios_info,
+						min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
+		}
 		default:
 			DRM_DEBUG_KMS("Invalid request %d\n",
 					info->vbios_info.type);
diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c
index 3dcb8b32f48b..6fa2229b7229 100644
--- a/drivers/gpu/drm/amd/amdgpu/atom.c
+++ b/drivers/gpu/drm/amd/amdgpu/atom.c
@@ -31,6 +31,7 @@
 
 #define ATOM_DEBUG
 
+#include "atomfirmware.h"
 #include "atom.h"
 #include "atom-names.h"
 #include "atom-bits.h"
@@ -1299,12 +1300,168 @@ static void atom_index_iio(struct atom_context *ctx, int base)
 	}
 }
 
+static void atom_get_vbios_name(struct atom_context *ctx) {
+	unsigned char *p_rom;
+	unsigned char str_num;
+	unsigned short off_to_vbios_str;
+	unsigned char *c_ptr;
+	int name_size;
+	int i;
+
+	const char *na = "--N/A--";
+	char *back;
+
+	p_rom = ctx->bios;
+
+	str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
+	if (str_num != 0) {
+		off_to_vbios_str =
+			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
+
+		c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
+	} else {
+		/* do not know where to find name */
+		memcpy(ctx->name, na, 7);
+		ctx->name[7] = 0;
+		return;
+	}
+
+	/*
+	 * skip the atombios strings, usually 4
+	 * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
+	 */
+	for (i = 0; i < str_num; i++) {
+		while (*c_ptr != 0)
+			c_ptr++;
+		c_ptr++;
+	}
+
+	/* skip the following 2 chars: 0x0D 0x0A */
+	c_ptr += 2;
+
+	name_size = strnlen(c_ptr, STRLEN_LONG - 1);
+	memcpy(ctx->name, c_ptr, name_size);
+	back = ctx->name + name_size;
+	while ((*--back) == ' ')
+		;
+	*(back + 1) = '\0';
+}
+
+static void atom_get_vbios_date(struct atom_context *ctx) {
+	unsigned char *p_rom;
+	unsigned char *date_in_rom;
+
+	p_rom = ctx->bios;
+
+	date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
+
+	ctx->date[0] = '2';
+	ctx->date[1] = '0';
+	ctx->date[2] = date_in_rom[6];
+	ctx->date[3] = date_in_rom[7];
+	ctx->date[4] = '/';
+	ctx->date[5] = date_in_rom[0];
+	ctx->date[6] = date_in_rom[1];
+	ctx->date[7] = '/';
+	ctx->date[8] = date_in_rom[3];
+	ctx->date[9] = date_in_rom[4];
+	ctx->date[10] = ' ';
+	ctx->date[11] = date_in_rom[9];
+	ctx->date[12] = date_in_rom[10];
+	ctx->date[13] = date_in_rom[11];
+	ctx->date[14] = date_in_rom[12];
+	ctx->date[15] = date_in_rom[13];
+	ctx->date[16] = '\0';
+}
+
+static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
+					   int end, int maxlen)
+{
+	unsigned long str_off;
+	unsigned char *p_rom;
+	unsigned short str_len;
+
+	str_off = 0;
+	str_len = strnlen(str, maxlen);
+	p_rom = ctx->bios;
+
+	for (; start <= end; ++start) {
+		for (str_off = 0; str_off < str_len; ++str_off) {
+			if (str[str_off] != *(p_rom + start + str_off))
+				break;
+		}
+
+		if (str_off == str_len || str[str_off] == 0)
+			return p_rom + start;
+	}
+	return NULL;
+}
+
+static void atom_get_vbios_pn(struct atom_context *ctx) {
+	unsigned char *p_rom;
+	unsigned short off_to_vbios_str;
+	unsigned char *vbios_str;
+	int count;
+
+	off_to_vbios_str = 0;
+	p_rom = ctx->bios;
+
+	if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
+		off_to_vbios_str =
+			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
+
+		vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
+	} else {
+		vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
+	}
+
+	if (*vbios_str == 0) {
+		vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
+		if (vbios_str == NULL)
+			vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
+	}
+	if (vbios_str != NULL && *vbios_str == 0)
+		vbios_str++;
+
+	if (vbios_str != NULL) {
+		count = 0;
+		while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
+		       vbios_str[count] <= 'z') {
+			ctx->vbios_pn[count] = vbios_str[count];
+			count++;
+		}
+
+		ctx->vbios_pn[count] = 0;
+	}
+}
+
+static void atom_get_vbios_version(struct atom_context *ctx) {
+	unsigned char *vbios_ver;
+
+	/* find anchor ATOMBIOSBK-AMD */
+	vbios_ver = atom_find_str_in_rom(ctx, BIOS_VERSION_PREFIX, 3, 1024, 64);
+	if (vbios_ver != NULL) {
+		/* skip ATOMBIOSBK-AMD VER */
+		vbios_ver += 18;
+		memcpy(ctx->vbios_ver_str, vbios_ver, STRLEN_NORMAL);
+	} else {
+		ctx->vbios_ver_str[0] = '\0';
+	}
+}
+
 struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)  {
 	int base;
 	struct atom_context *ctx =
 	    kzalloc(sizeof(struct atom_context), GFP_KERNEL);
 	char *str;
+	struct _ATOM_ROM_HEADER *atom_rom_header;
+	struct _ATOM_MASTER_DATA_TABLE *master_table;
+	struct _ATOM_FIRMWARE_INFO *atom_fw_info;
 	u16 idx;
 
 	if (!ctx)
@@ -1353,6 +1510,21 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
 		strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
 	}
 
+	atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
+	if (atom_rom_header->usMasterDataTableOffset != 0) {
+		master_table = (struct _ATOM_MASTER_DATA_TABLE *)
+				CSTR(atom_rom_header->usMasterDataTableOffset);
+		if (master_table->ListOfDataTables.FirmwareInfo != 0) {
+			atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
+					CSTR(master_table->ListOfDataTables.FirmwareInfo);
+			ctx->version = atom_fw_info->ulFirmwareRevision;
+		}
+	}
+
+	atom_get_vbios_name(ctx);
+	atom_get_vbios_pn(ctx);
+	atom_get_vbios_date(ctx);
+	atom_get_vbios_version(ctx);
 
 	return ctx;
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h
index d279759cab47..0c1839824520 100644
--- a/drivers/gpu/drm/amd/amdgpu/atom.h
+++ b/drivers/gpu/drm/amd/amdgpu/atom.h
@@ -112,6 +112,10 @@ struct drm_device;
 #define ATOM_IO_SYSIO		2
 #define ATOM_IO_IIO		0x80
 
+#define STRLEN_NORMAL		32
+#define STRLEN_LONG		64
+#define STRLEN_VERYLONG		254
+
 struct card_info {
 	struct drm_device *dev;
 	void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
@@ -140,6 +144,12 @@ struct atom_context {
 	uint32_t *scratch;
 	int scratch_size_bytes;
 	char vbios_version[20];
+
+	uint8_t name[STRLEN_LONG];
+	uint8_t vbios_pn[STRLEN_LONG];
+	uint32_t version;
+	uint8_t vbios_ver_str[STRLEN_NORMAL];
+	uint8_t date[STRLEN_NORMAL];
 };
 
 extern int amdgpu_atom_debug;
diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
index 275468e4be60..28deecc2f990 100644
--- a/drivers/gpu/drm/amd/include/atomfirmware.h
+++ b/drivers/gpu/drm/amd/include/atomfirmware.h
@@ -197,6 +197,9 @@ enum atom_dp_vs_preemph_def{
   DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
 };
 
+#define BIOS_ATOM_PREFIX   "ATOMBIOS"
+#define BIOS_VERSION_PREFIX  "ATOMBIOSBK-AMD"
+#define BIOS_STRING_LENGTH 43
 
 /*
 enum atom_string_def{
@@ -215,6 +218,8 @@ enum atombios_image_offset{
   MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
   OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
   OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
+  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
+  OFFSET_TO_VBIOS_DATE                       = 0x50,
 };
 
 /****************************************************************************   
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 9169df7fadee..155fd9918b4d 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -756,6 +756,8 @@ struct drm_amdgpu_cs_chunk_data {
 	#define AMDGPU_INFO_VBIOS_SIZE		0x1
 	/* Subquery id: Query vbios image */
 	#define AMDGPU_INFO_VBIOS_IMAGE		0x2
+	/* Subquery id: Query vbios info */
+	#define AMDGPU_INFO_VBIOS_INFO		0x3
 /* Query UVD handles */
 #define AMDGPU_INFO_NUM_HANDLES			0x1C
 /* Query sensor related information */
@@ -949,6 +951,14 @@ struct drm_amdgpu_info_firmware {
 	__u32 feature;
 };
 
+struct drm_amdgpu_info_vbios {
+	__u8 name[64];
+	__u8 vbios_pn[64];
+	__u32 version;
+	__u8 vbios_ver_str[32];
+	__u8 date[32];
+};
+
 #define AMDGPU_VRAM_TYPE_UNKNOWN 0
 #define AMDGPU_VRAM_TYPE_GDDR1 1
 #define AMDGPU_VRAM_TYPE_DDR2  2
--
2.17.1
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-05-18 12:19 ` Gu, JiaWei (Will)
@ 2021-05-18 13:17   ` Christian König
  2021-05-18 13:25     ` StDenis, Tom
  0 siblings, 1 reply; 47+ messages in thread
From: Christian König @ 2021-05-18 13:17 UTC (permalink / raw)
  To: Gu, JiaWei (Will), amd-gfx, Nieto, David M, maraeo, Deucher, Alexander
  Cc: Deng, Emily

Well not an expert on that stuff, but looks like that should work for me.

Question is can you provide a patch to use that information in Mesa as 
well? Umr might be sufficient as well as justification for upstreaming, 
but I want to be better save than sorry.

Unless Marek has a better idea maybe add the vbios version to the string 
returned by GLX_MESA_query_renderer or something like that.

Thanks,
Christian.

Am 18.05.21 um 14:19 schrieb Gu, JiaWei (Will):
> [AMD Official Use Only - Internal Distribution Only]
>
> Hi all,
>
> Please help confirm that we're all fine with this new struct in uapi in this V3 patch:
>
> +struct drm_amdgpu_info_vbios {
> +	__u8 name[64];
> +	__u8 vbios_pn[64];
> +	__u32 version;
> +	__u8 vbios_ver_str[32];
> +	__u8 date[32];
> +};
>
> Best regards,
> Jiawei
>
> -----Original Message-----
> From: Jiawei Gu <Jiawei.Gu@amd.com>
> Sent: Tuesday, May 18, 2021 8:16 PM
> To: amd-gfx@lists.freedesktop.org; Koenig, Christian <Christian.Koenig@amd.com>; Nieto, David M <David.Nieto@amd.com>; maraeo@gmail.com; Deucher, Alexander <Alexander.Deucher@amd.com>
> Cc: Deng, Emily <Emily.Deng@amd.com>; Gu, JiaWei (Will) <JiaWei.Gu@amd.com>
> Subject: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.
>
> Provides a way for the user application to get the VBIOS information without having to parse the binary.
> It is useful for the user to be able to display in a simple way the VBIOS version in their system if they happen to encounter an issue.
>
> V2:
> Use numeric serial.
> Parse and expose vbios version string.
>
> V3:
> Remove redundant data in drm_amdgpu_info_vbios struct.
>
> Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  15 ++
>   drivers/gpu/drm/amd/amdgpu/atom.c          | 172 +++++++++++++++++++++
>   drivers/gpu/drm/amd/amdgpu/atom.h          |  10 ++
>   drivers/gpu/drm/amd/include/atomfirmware.h |   5 +
>   include/uapi/drm/amdgpu_drm.h              |  10 ++
>   5 files changed, 212 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index 8d12e474745a..524e4fe5efe8 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -861,6 +861,21 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
>   					    min((size_t)size, (size_t)(bios_size - bios_offset)))
>   					? -EFAULT : 0;
>   		}
> +		case AMDGPU_INFO_VBIOS_INFO: {
> +			struct drm_amdgpu_info_vbios vbios_info = {};
> +			struct atom_context *atom_context;
> +
> +			atom_context = adev->mode_info.atom_context;
> +			memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
> +			memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
> +			vbios_info.version = atom_context->version;
> +			memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str,
> +						sizeof(atom_context->vbios_ver_str));
> +			memcpy(vbios_info.date, atom_context->date,
> +sizeof(atom_context->date));
> +
> +			return copy_to_user(out, &vbios_info,
> +						min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
> +		}
>   		default:
>   			DRM_DEBUG_KMS("Invalid request %d\n",
>   					info->vbios_info.type);
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c
> index 3dcb8b32f48b..6fa2229b7229 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.c
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
> @@ -31,6 +31,7 @@
>   
>   #define ATOM_DEBUG
>   
> +#include "atomfirmware.h"
>   #include "atom.h"
>   #include "atom-names.h"
>   #include "atom-bits.h"
> @@ -1299,12 +1300,168 @@ static void atom_index_iio(struct atom_context *ctx, int base)
>   	}
>   }
>   
> +static void atom_get_vbios_name(struct atom_context *ctx) {
> +	unsigned char *p_rom;
> +	unsigned char str_num;
> +	unsigned short off_to_vbios_str;
> +	unsigned char *c_ptr;
> +	int name_size;
> +	int i;
> +
> +	const char *na = "--N/A--";
> +	char *back;
> +
> +	p_rom = ctx->bios;
> +
> +	str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
> +	if (str_num != 0) {
> +		off_to_vbios_str =
> +			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +		c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
> +	} else {
> +		/* do not know where to find name */
> +		memcpy(ctx->name, na, 7);
> +		ctx->name[7] = 0;
> +		return;
> +	}
> +
> +	/*
> +	 * skip the atombios strings, usually 4
> +	 * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
> +	 */
> +	for (i = 0; i < str_num; i++) {
> +		while (*c_ptr != 0)
> +			c_ptr++;
> +		c_ptr++;
> +	}
> +
> +	/* skip the following 2 chars: 0x0D 0x0A */
> +	c_ptr += 2;
> +
> +	name_size = strnlen(c_ptr, STRLEN_LONG - 1);
> +	memcpy(ctx->name, c_ptr, name_size);
> +	back = ctx->name + name_size;
> +	while ((*--back) == ' ')
> +		;
> +	*(back + 1) = '\0';
> +}
> +
> +static void atom_get_vbios_date(struct atom_context *ctx) {
> +	unsigned char *p_rom;
> +	unsigned char *date_in_rom;
> +
> +	p_rom = ctx->bios;
> +
> +	date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
> +
> +	ctx->date[0] = '2';
> +	ctx->date[1] = '0';
> +	ctx->date[2] = date_in_rom[6];
> +	ctx->date[3] = date_in_rom[7];
> +	ctx->date[4] = '/';
> +	ctx->date[5] = date_in_rom[0];
> +	ctx->date[6] = date_in_rom[1];
> +	ctx->date[7] = '/';
> +	ctx->date[8] = date_in_rom[3];
> +	ctx->date[9] = date_in_rom[4];
> +	ctx->date[10] = ' ';
> +	ctx->date[11] = date_in_rom[9];
> +	ctx->date[12] = date_in_rom[10];
> +	ctx->date[13] = date_in_rom[11];
> +	ctx->date[14] = date_in_rom[12];
> +	ctx->date[15] = date_in_rom[13];
> +	ctx->date[16] = '\0';
> +}
> +
> +static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
> +					   int end, int maxlen)
> +{
> +	unsigned long str_off;
> +	unsigned char *p_rom;
> +	unsigned short str_len;
> +
> +	str_off = 0;
> +	str_len = strnlen(str, maxlen);
> +	p_rom = ctx->bios;
> +
> +	for (; start <= end; ++start) {
> +		for (str_off = 0; str_off < str_len; ++str_off) {
> +			if (str[str_off] != *(p_rom + start + str_off))
> +				break;
> +		}
> +
> +		if (str_off == str_len || str[str_off] == 0)
> +			return p_rom + start;
> +	}
> +	return NULL;
> +}
> +
> +static void atom_get_vbios_pn(struct atom_context *ctx) {
> +	unsigned char *p_rom;
> +	unsigned short off_to_vbios_str;
> +	unsigned char *vbios_str;
> +	int count;
> +
> +	off_to_vbios_str = 0;
> +	p_rom = ctx->bios;
> +
> +	if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
> +		off_to_vbios_str =
> +			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +		vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
> +	} else {
> +		vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
> +	}
> +
> +	if (*vbios_str == 0) {
> +		vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
> +		if (vbios_str == NULL)
> +			vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
> +	}
> +	if (vbios_str != NULL && *vbios_str == 0)
> +		vbios_str++;
> +
> +	if (vbios_str != NULL) {
> +		count = 0;
> +		while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
> +		       vbios_str[count] <= 'z') {
> +			ctx->vbios_pn[count] = vbios_str[count];
> +			count++;
> +		}
> +
> +		ctx->vbios_pn[count] = 0;
> +	}
> +}
> +
> +static void atom_get_vbios_version(struct atom_context *ctx) {
> +	unsigned char *vbios_ver;
> +
> +	/* find anchor ATOMBIOSBK-AMD */
> +	vbios_ver = atom_find_str_in_rom(ctx, BIOS_VERSION_PREFIX, 3, 1024, 64);
> +	if (vbios_ver != NULL) {
> +		/* skip ATOMBIOSBK-AMD VER */
> +		vbios_ver += 18;
> +		memcpy(ctx->vbios_ver_str, vbios_ver, STRLEN_NORMAL);
> +	} else {
> +		ctx->vbios_ver_str[0] = '\0';
> +	}
> +}
> +
>   struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)  {
>   	int base;
>   	struct atom_context *ctx =
>   	    kzalloc(sizeof(struct atom_context), GFP_KERNEL);
>   	char *str;
> +	struct _ATOM_ROM_HEADER *atom_rom_header;
> +	struct _ATOM_MASTER_DATA_TABLE *master_table;
> +	struct _ATOM_FIRMWARE_INFO *atom_fw_info;
>   	u16 idx;
>   
>   	if (!ctx)
> @@ -1353,6 +1510,21 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>   		strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
>   	}
>   
> +	atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
> +	if (atom_rom_header->usMasterDataTableOffset != 0) {
> +		master_table = (struct _ATOM_MASTER_DATA_TABLE *)
> +				CSTR(atom_rom_header->usMasterDataTableOffset);
> +		if (master_table->ListOfDataTables.FirmwareInfo != 0) {
> +			atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
> +					CSTR(master_table->ListOfDataTables.FirmwareInfo);
> +			ctx->version = atom_fw_info->ulFirmwareRevision;
> +		}
> +	}
> +
> +	atom_get_vbios_name(ctx);
> +	atom_get_vbios_pn(ctx);
> +	atom_get_vbios_date(ctx);
> +	atom_get_vbios_version(ctx);
>   
>   	return ctx;
>   }
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h
> index d279759cab47..0c1839824520 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.h
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
> @@ -112,6 +112,10 @@ struct drm_device;
>   #define ATOM_IO_SYSIO		2
>   #define ATOM_IO_IIO		0x80
>   
> +#define STRLEN_NORMAL		32
> +#define STRLEN_LONG		64
> +#define STRLEN_VERYLONG		254
> +
>   struct card_info {
>   	struct drm_device *dev;
>   	void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
> @@ -140,6 +144,12 @@ struct atom_context {
>   	uint32_t *scratch;
>   	int scratch_size_bytes;
>   	char vbios_version[20];
> +
> +	uint8_t name[STRLEN_LONG];
> +	uint8_t vbios_pn[STRLEN_LONG];
> +	uint32_t version;
> +	uint8_t vbios_ver_str[STRLEN_NORMAL];
> +	uint8_t date[STRLEN_NORMAL];
>   };
>   
>   extern int amdgpu_atom_debug;
> diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
> index 275468e4be60..28deecc2f990 100644
> --- a/drivers/gpu/drm/amd/include/atomfirmware.h
> +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
> @@ -197,6 +197,9 @@ enum atom_dp_vs_preemph_def{
>     DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
>   };
>   
> +#define BIOS_ATOM_PREFIX   "ATOMBIOS"
> +#define BIOS_VERSION_PREFIX  "ATOMBIOSBK-AMD"
> +#define BIOS_STRING_LENGTH 43
>   
>   /*
>   enum atom_string_def{
> @@ -215,6 +218,8 @@ enum atombios_image_offset{
>     MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
>     OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
>     OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
> +  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
> +  OFFSET_TO_VBIOS_DATE                       = 0x50,
>   };
>   
>   /****************************************************************************
> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 9169df7fadee..155fd9918b4d 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -756,6 +756,8 @@ struct drm_amdgpu_cs_chunk_data {
>   	#define AMDGPU_INFO_VBIOS_SIZE		0x1
>   	/* Subquery id: Query vbios image */
>   	#define AMDGPU_INFO_VBIOS_IMAGE		0x2
> +	/* Subquery id: Query vbios info */
> +	#define AMDGPU_INFO_VBIOS_INFO		0x3
>   /* Query UVD handles */
>   #define AMDGPU_INFO_NUM_HANDLES			0x1C
>   /* Query sensor related information */
> @@ -949,6 +951,14 @@ struct drm_amdgpu_info_firmware {
>   	__u32 feature;
>   };
>   
> +struct drm_amdgpu_info_vbios {
> +	__u8 name[64];
> +	__u8 vbios_pn[64];
> +	__u32 version;
> +	__u8 vbios_ver_str[32];
> +	__u8 date[32];
> +};
> +
>   #define AMDGPU_VRAM_TYPE_UNKNOWN 0
>   #define AMDGPU_VRAM_TYPE_GDDR1 1
>   #define AMDGPU_VRAM_TYPE_DDR2  2
> --
> 2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-05-18 13:17   ` Christian König
@ 2021-05-18 13:25     ` StDenis, Tom
  2021-05-19  2:41       ` Gu, JiaWei (Will)
  0 siblings, 1 reply; 47+ messages in thread
From: StDenis, Tom @ 2021-05-18 13:25 UTC (permalink / raw)
  To: Koenig, Christian, Gu, JiaWei (Will),
	amd-gfx, Nieto, David M, maraeo, Deucher, Alexander
  Cc: Deng, Emily

[AMD Official Use Only - Internal Distribution Only]

If changing the ioctl is an issue why not just use sysfs?  umr already makes uses of all three for it's purposes so it's fine by me for either.

Tom

________________________________________
From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> on behalf of Christian König <christian.koenig@amd.com>
Sent: Tuesday, May 18, 2021 09:17
To: Gu, JiaWei (Will); amd-gfx@lists.freedesktop.org; Nieto, David M; maraeo@gmail.com; Deucher, Alexander
Cc: Deng, Emily
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

Well not an expert on that stuff, but looks like that should work for me.

Question is can you provide a patch to use that information in Mesa as
well? Umr might be sufficient as well as justification for upstreaming,
but I want to be better save than sorry.

Unless Marek has a better idea maybe add the vbios version to the string
returned by GLX_MESA_query_renderer or something like that.

Thanks,
Christian.

Am 18.05.21 um 14:19 schrieb Gu, JiaWei (Will):
> [AMD Official Use Only - Internal Distribution Only]
>
> Hi all,
>
> Please help confirm that we're all fine with this new struct in uapi in this V3 patch:
>
> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +};
>
> Best regards,
> Jiawei
>
> -----Original Message-----
> From: Jiawei Gu <Jiawei.Gu@amd.com>
> Sent: Tuesday, May 18, 2021 8:16 PM
> To: amd-gfx@lists.freedesktop.org; Koenig, Christian <Christian.Koenig@amd.com>; Nieto, David M <David.Nieto@amd.com>; maraeo@gmail.com; Deucher, Alexander <Alexander.Deucher@amd.com>
> Cc: Deng, Emily <Emily.Deng@amd.com>; Gu, JiaWei (Will) <JiaWei.Gu@amd.com>
> Subject: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.
>
> Provides a way for the user application to get the VBIOS information without having to parse the binary.
> It is useful for the user to be able to display in a simple way the VBIOS version in their system if they happen to encounter an issue.
>
> V2:
> Use numeric serial.
> Parse and expose vbios version string.
>
> V3:
> Remove redundant data in drm_amdgpu_info_vbios struct.
>
> Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  15 ++
>   drivers/gpu/drm/amd/amdgpu/atom.c          | 172 +++++++++++++++++++++
>   drivers/gpu/drm/amd/amdgpu/atom.h          |  10 ++
>   drivers/gpu/drm/amd/include/atomfirmware.h |   5 +
>   include/uapi/drm/amdgpu_drm.h              |  10 ++
>   5 files changed, 212 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index 8d12e474745a..524e4fe5efe8 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -861,6 +861,21 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
>                                           min((size_t)size, (size_t)(bios_size - bios_offset)))
>                                       ? -EFAULT : 0;
>               }
> +             case AMDGPU_INFO_VBIOS_INFO: {
> +                     struct drm_amdgpu_info_vbios vbios_info = {};
> +                     struct atom_context *atom_context;
> +
> +                     atom_context = adev->mode_info.atom_context;
> +                     memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
> +                     memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
> +                     vbios_info.version = atom_context->version;
> +                     memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str,
> +                                             sizeof(atom_context->vbios_ver_str));
> +                     memcpy(vbios_info.date, atom_context->date,
> +sizeof(atom_context->date));
> +
> +                     return copy_to_user(out, &vbios_info,
> +                                             min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
> +             }
>               default:
>                       DRM_DEBUG_KMS("Invalid request %d\n",
>                                       info->vbios_info.type);
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c
> index 3dcb8b32f48b..6fa2229b7229 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.c
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
> @@ -31,6 +31,7 @@
>
>   #define ATOM_DEBUG
>
> +#include "atomfirmware.h"
>   #include "atom.h"
>   #include "atom-names.h"
>   #include "atom-bits.h"
> @@ -1299,12 +1300,168 @@ static void atom_index_iio(struct atom_context *ctx, int base)
>       }
>   }
>
> +static void atom_get_vbios_name(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned char str_num;
> +     unsigned short off_to_vbios_str;
> +     unsigned char *c_ptr;
> +     int name_size;
> +     int i;
> +
> +     const char *na = "--N/A--";
> +     char *back;
> +
> +     p_rom = ctx->bios;
> +
> +     str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
> +     if (str_num != 0) {
> +             off_to_vbios_str =
> +                     *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +             c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
> +     } else {
> +             /* do not know where to find name */
> +             memcpy(ctx->name, na, 7);
> +             ctx->name[7] = 0;
> +             return;
> +     }
> +
> +     /*
> +      * skip the atombios strings, usually 4
> +      * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
> +      */
> +     for (i = 0; i < str_num; i++) {
> +             while (*c_ptr != 0)
> +                     c_ptr++;
> +             c_ptr++;
> +     }
> +
> +     /* skip the following 2 chars: 0x0D 0x0A */
> +     c_ptr += 2;
> +
> +     name_size = strnlen(c_ptr, STRLEN_LONG - 1);
> +     memcpy(ctx->name, c_ptr, name_size);
> +     back = ctx->name + name_size;
> +     while ((*--back) == ' ')
> +             ;
> +     *(back + 1) = '\0';
> +}
> +
> +static void atom_get_vbios_date(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned char *date_in_rom;
> +
> +     p_rom = ctx->bios;
> +
> +     date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
> +
> +     ctx->date[0] = '2';
> +     ctx->date[1] = '0';
> +     ctx->date[2] = date_in_rom[6];
> +     ctx->date[3] = date_in_rom[7];
> +     ctx->date[4] = '/';
> +     ctx->date[5] = date_in_rom[0];
> +     ctx->date[6] = date_in_rom[1];
> +     ctx->date[7] = '/';
> +     ctx->date[8] = date_in_rom[3];
> +     ctx->date[9] = date_in_rom[4];
> +     ctx->date[10] = ' ';
> +     ctx->date[11] = date_in_rom[9];
> +     ctx->date[12] = date_in_rom[10];
> +     ctx->date[13] = date_in_rom[11];
> +     ctx->date[14] = date_in_rom[12];
> +     ctx->date[15] = date_in_rom[13];
> +     ctx->date[16] = '\0';
> +}
> +
> +static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
> +                                        int end, int maxlen)
> +{
> +     unsigned long str_off;
> +     unsigned char *p_rom;
> +     unsigned short str_len;
> +
> +     str_off = 0;
> +     str_len = strnlen(str, maxlen);
> +     p_rom = ctx->bios;
> +
> +     for (; start <= end; ++start) {
> +             for (str_off = 0; str_off < str_len; ++str_off) {
> +                     if (str[str_off] != *(p_rom + start + str_off))
> +                             break;
> +             }
> +
> +             if (str_off == str_len || str[str_off] == 0)
> +                     return p_rom + start;
> +     }
> +     return NULL;
> +}
> +
> +static void atom_get_vbios_pn(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned short off_to_vbios_str;
> +     unsigned char *vbios_str;
> +     int count;
> +
> +     off_to_vbios_str = 0;
> +     p_rom = ctx->bios;
> +
> +     if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
> +             off_to_vbios_str =
> +                     *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +             vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
> +     } else {
> +             vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
> +     }
> +
> +     if (*vbios_str == 0) {
> +             vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
> +             if (vbios_str == NULL)
> +                     vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
> +     }
> +     if (vbios_str != NULL && *vbios_str == 0)
> +             vbios_str++;
> +
> +     if (vbios_str != NULL) {
> +             count = 0;
> +             while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
> +                    vbios_str[count] <= 'z') {
> +                     ctx->vbios_pn[count] = vbios_str[count];
> +                     count++;
> +             }
> +
> +             ctx->vbios_pn[count] = 0;
> +     }
> +}
> +
> +static void atom_get_vbios_version(struct atom_context *ctx) {
> +     unsigned char *vbios_ver;
> +
> +     /* find anchor ATOMBIOSBK-AMD */
> +     vbios_ver = atom_find_str_in_rom(ctx, BIOS_VERSION_PREFIX, 3, 1024, 64);
> +     if (vbios_ver != NULL) {
> +             /* skip ATOMBIOSBK-AMD VER */
> +             vbios_ver += 18;
> +             memcpy(ctx->vbios_ver_str, vbios_ver, STRLEN_NORMAL);
> +     } else {
> +             ctx->vbios_ver_str[0] = '\0';
> +     }
> +}
> +
>   struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)  {
>       int base;
>       struct atom_context *ctx =
>           kzalloc(sizeof(struct atom_context), GFP_KERNEL);
>       char *str;
> +     struct _ATOM_ROM_HEADER *atom_rom_header;
> +     struct _ATOM_MASTER_DATA_TABLE *master_table;
> +     struct _ATOM_FIRMWARE_INFO *atom_fw_info;
>       u16 idx;
>
>       if (!ctx)
> @@ -1353,6 +1510,21 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>               strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
>       }
>
> +     atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
> +     if (atom_rom_header->usMasterDataTableOffset != 0) {
> +             master_table = (struct _ATOM_MASTER_DATA_TABLE *)
> +                             CSTR(atom_rom_header->usMasterDataTableOffset);
> +             if (master_table->ListOfDataTables.FirmwareInfo != 0) {
> +                     atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
> +                                     CSTR(master_table->ListOfDataTables.FirmwareInfo);
> +                     ctx->version = atom_fw_info->ulFirmwareRevision;
> +             }
> +     }
> +
> +     atom_get_vbios_name(ctx);
> +     atom_get_vbios_pn(ctx);
> +     atom_get_vbios_date(ctx);
> +     atom_get_vbios_version(ctx);
>
>       return ctx;
>   }
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h
> index d279759cab47..0c1839824520 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.h
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
> @@ -112,6 +112,10 @@ struct drm_device;
>   #define ATOM_IO_SYSIO               2
>   #define ATOM_IO_IIO         0x80
>
> +#define STRLEN_NORMAL                32
> +#define STRLEN_LONG          64
> +#define STRLEN_VERYLONG              254
> +
>   struct card_info {
>       struct drm_device *dev;
>       void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
> @@ -140,6 +144,12 @@ struct atom_context {
>       uint32_t *scratch;
>       int scratch_size_bytes;
>       char vbios_version[20];
> +
> +     uint8_t name[STRLEN_LONG];
> +     uint8_t vbios_pn[STRLEN_LONG];
> +     uint32_t version;
> +     uint8_t vbios_ver_str[STRLEN_NORMAL];
> +     uint8_t date[STRLEN_NORMAL];
>   };
>
>   extern int amdgpu_atom_debug;
> diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
> index 275468e4be60..28deecc2f990 100644
> --- a/drivers/gpu/drm/amd/include/atomfirmware.h
> +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
> @@ -197,6 +197,9 @@ enum atom_dp_vs_preemph_def{
>     DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
>   };
>
> +#define BIOS_ATOM_PREFIX   "ATOMBIOS"
> +#define BIOS_VERSION_PREFIX  "ATOMBIOSBK-AMD"
> +#define BIOS_STRING_LENGTH 43
>
>   /*
>   enum atom_string_def{
> @@ -215,6 +218,8 @@ enum atombios_image_offset{
>     MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
>     OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
>     OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
> +  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
> +  OFFSET_TO_VBIOS_DATE                       = 0x50,
>   };
>
>   /****************************************************************************
> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 9169df7fadee..155fd9918b4d 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -756,6 +756,8 @@ struct drm_amdgpu_cs_chunk_data {
>       #define AMDGPU_INFO_VBIOS_SIZE          0x1
>       /* Subquery id: Query vbios image */
>       #define AMDGPU_INFO_VBIOS_IMAGE         0x2
> +     /* Subquery id: Query vbios info */
> +     #define AMDGPU_INFO_VBIOS_INFO          0x3
>   /* Query UVD handles */
>   #define AMDGPU_INFO_NUM_HANDLES                     0x1C
>   /* Query sensor related information */
> @@ -949,6 +951,14 @@ struct drm_amdgpu_info_firmware {
>       __u32 feature;
>   };
>
> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +};
> +
>   #define AMDGPU_VRAM_TYPE_UNKNOWN 0
>   #define AMDGPU_VRAM_TYPE_GDDR1 1
>   #define AMDGPU_VRAM_TYPE_DDR2  2
> --
> 2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&amp;data=04%7C01%7Ctom.stdenis%40amd.com%7C332524597a5e42ad491908d919ff414f%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637569406377960645%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=ZFBUbqu1VjvQkpnQ4Wy6Q4XE9CB2IcFltOq3Iv12F7U%3D&amp;reserved=0
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-05-18 13:25     ` StDenis, Tom
@ 2021-05-19  2:41       ` Gu, JiaWei (Will)
  2021-05-19  3:10         ` Marek Olšák
  0 siblings, 1 reply; 47+ messages in thread
From: Gu, JiaWei (Will) @ 2021-05-19  2:41 UTC (permalink / raw)
  To: StDenis, Tom, Koenig, Christian, amd-gfx, Nieto, David M, maraeo,
	Deucher, Alexander
  Cc: Deng, Emily

[AMD Official Use Only - Internal Distribution Only]

Thanks Tom's suggestion.
I'm fine to replace ioctl with sysfs.

Hi all, how about this sysfs alternative?

And if it's a must to insist on ioctl, is there any Mesa expert to help provide the patch?

Best regards,
Jiawei


-----Original Message-----
From: StDenis, Tom <Tom.StDenis@amd.com> 
Sent: Tuesday, May 18, 2021 9:26 PM
To: Koenig, Christian <Christian.Koenig@amd.com>; Gu, JiaWei (Will) <JiaWei.Gu@amd.com>; amd-gfx@lists.freedesktop.org; Nieto, David M <David.Nieto@amd.com>; maraeo@gmail.com; Deucher, Alexander <Alexander.Deucher@amd.com>
Cc: Deng, Emily <Emily.Deng@amd.com>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

[AMD Official Use Only - Internal Distribution Only]

If changing the ioctl is an issue why not just use sysfs?  umr already makes uses of all three for it's purposes so it's fine by me for either.

Tom

________________________________________
From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> on behalf of Christian König <christian.koenig@amd.com>
Sent: Tuesday, May 18, 2021 09:17
To: Gu, JiaWei (Will); amd-gfx@lists.freedesktop.org; Nieto, David M; maraeo@gmail.com; Deucher, Alexander
Cc: Deng, Emily
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

Well not an expert on that stuff, but looks like that should work for me.

Question is can you provide a patch to use that information in Mesa as well? Umr might be sufficient as well as justification for upstreaming, but I want to be better save than sorry.

Unless Marek has a better idea maybe add the vbios version to the string returned by GLX_MESA_query_renderer or something like that.

Thanks,
Christian.

Am 18.05.21 um 14:19 schrieb Gu, JiaWei (Will):
> [AMD Official Use Only - Internal Distribution Only]
>
> Hi all,
>
> Please help confirm that we're all fine with this new struct in uapi in this V3 patch:
>
> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +};
>
> Best regards,
> Jiawei
>
> -----Original Message-----
> From: Jiawei Gu <Jiawei.Gu@amd.com>
> Sent: Tuesday, May 18, 2021 8:16 PM
> To: amd-gfx@lists.freedesktop.org; Koenig, Christian 
> <Christian.Koenig@amd.com>; Nieto, David M <David.Nieto@amd.com>; 
> maraeo@gmail.com; Deucher, Alexander <Alexander.Deucher@amd.com>
> Cc: Deng, Emily <Emily.Deng@amd.com>; Gu, JiaWei (Will) 
> <JiaWei.Gu@amd.com>
> Subject: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.
>
> Provides a way for the user application to get the VBIOS information without having to parse the binary.
> It is useful for the user to be able to display in a simple way the VBIOS version in their system if they happen to encounter an issue.
>
> V2:
> Use numeric serial.
> Parse and expose vbios version string.
>
> V3:
> Remove redundant data in drm_amdgpu_info_vbios struct.
>
> Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  15 ++
>   drivers/gpu/drm/amd/amdgpu/atom.c          | 172 +++++++++++++++++++++
>   drivers/gpu/drm/amd/amdgpu/atom.h          |  10 ++
>   drivers/gpu/drm/amd/include/atomfirmware.h |   5 +
>   include/uapi/drm/amdgpu_drm.h              |  10 ++
>   5 files changed, 212 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index 8d12e474745a..524e4fe5efe8 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -861,6 +861,21 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
>                                           min((size_t)size, (size_t)(bios_size - bios_offset)))
>                                       ? -EFAULT : 0;
>               }
> +             case AMDGPU_INFO_VBIOS_INFO: {
> +                     struct drm_amdgpu_info_vbios vbios_info = {};
> +                     struct atom_context *atom_context;
> +
> +                     atom_context = adev->mode_info.atom_context;
> +                     memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
> +                     memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
> +                     vbios_info.version = atom_context->version;
> +                     memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str,
> +                                             sizeof(atom_context->vbios_ver_str));
> +                     memcpy(vbios_info.date, atom_context->date, 
> +sizeof(atom_context->date));
> +
> +                     return copy_to_user(out, &vbios_info,
> +                                             min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
> +             }
>               default:
>                       DRM_DEBUG_KMS("Invalid request %d\n",
>                                       info->vbios_info.type); diff 
> --git a/drivers/gpu/drm/amd/amdgpu/atom.c 
> b/drivers/gpu/drm/amd/amdgpu/atom.c
> index 3dcb8b32f48b..6fa2229b7229 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.c
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
> @@ -31,6 +31,7 @@
>
>   #define ATOM_DEBUG
>
> +#include "atomfirmware.h"
>   #include "atom.h"
>   #include "atom-names.h"
>   #include "atom-bits.h"
> @@ -1299,12 +1300,168 @@ static void atom_index_iio(struct atom_context *ctx, int base)
>       }
>   }
>
> +static void atom_get_vbios_name(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned char str_num;
> +     unsigned short off_to_vbios_str;
> +     unsigned char *c_ptr;
> +     int name_size;
> +     int i;
> +
> +     const char *na = "--N/A--";
> +     char *back;
> +
> +     p_rom = ctx->bios;
> +
> +     str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
> +     if (str_num != 0) {
> +             off_to_vbios_str =
> +                     *(unsigned short *)(p_rom + 
> + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +             c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
> +     } else {
> +             /* do not know where to find name */
> +             memcpy(ctx->name, na, 7);
> +             ctx->name[7] = 0;
> +             return;
> +     }
> +
> +     /*
> +      * skip the atombios strings, usually 4
> +      * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
> +      */
> +     for (i = 0; i < str_num; i++) {
> +             while (*c_ptr != 0)
> +                     c_ptr++;
> +             c_ptr++;
> +     }
> +
> +     /* skip the following 2 chars: 0x0D 0x0A */
> +     c_ptr += 2;
> +
> +     name_size = strnlen(c_ptr, STRLEN_LONG - 1);
> +     memcpy(ctx->name, c_ptr, name_size);
> +     back = ctx->name + name_size;
> +     while ((*--back) == ' ')
> +             ;
> +     *(back + 1) = '\0';
> +}
> +
> +static void atom_get_vbios_date(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned char *date_in_rom;
> +
> +     p_rom = ctx->bios;
> +
> +     date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
> +
> +     ctx->date[0] = '2';
> +     ctx->date[1] = '0';
> +     ctx->date[2] = date_in_rom[6];
> +     ctx->date[3] = date_in_rom[7];
> +     ctx->date[4] = '/';
> +     ctx->date[5] = date_in_rom[0];
> +     ctx->date[6] = date_in_rom[1];
> +     ctx->date[7] = '/';
> +     ctx->date[8] = date_in_rom[3];
> +     ctx->date[9] = date_in_rom[4];
> +     ctx->date[10] = ' ';
> +     ctx->date[11] = date_in_rom[9];
> +     ctx->date[12] = date_in_rom[10];
> +     ctx->date[13] = date_in_rom[11];
> +     ctx->date[14] = date_in_rom[12];
> +     ctx->date[15] = date_in_rom[13];
> +     ctx->date[16] = '\0';
> +}
> +
> +static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
> +                                        int end, int maxlen) {
> +     unsigned long str_off;
> +     unsigned char *p_rom;
> +     unsigned short str_len;
> +
> +     str_off = 0;
> +     str_len = strnlen(str, maxlen);
> +     p_rom = ctx->bios;
> +
> +     for (; start <= end; ++start) {
> +             for (str_off = 0; str_off < str_len; ++str_off) {
> +                     if (str[str_off] != *(p_rom + start + str_off))
> +                             break;
> +             }
> +
> +             if (str_off == str_len || str[str_off] == 0)
> +                     return p_rom + start;
> +     }
> +     return NULL;
> +}
> +
> +static void atom_get_vbios_pn(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned short off_to_vbios_str;
> +     unsigned char *vbios_str;
> +     int count;
> +
> +     off_to_vbios_str = 0;
> +     p_rom = ctx->bios;
> +
> +     if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
> +             off_to_vbios_str =
> +                     *(unsigned short *)(p_rom + 
> + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +             vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
> +     } else {
> +             vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
> +     }
> +
> +     if (*vbios_str == 0) {
> +             vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
> +             if (vbios_str == NULL)
> +                     vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
> +     }
> +     if (vbios_str != NULL && *vbios_str == 0)
> +             vbios_str++;
> +
> +     if (vbios_str != NULL) {
> +             count = 0;
> +             while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
> +                    vbios_str[count] <= 'z') {
> +                     ctx->vbios_pn[count] = vbios_str[count];
> +                     count++;
> +             }
> +
> +             ctx->vbios_pn[count] = 0;
> +     }
> +}
> +
> +static void atom_get_vbios_version(struct atom_context *ctx) {
> +     unsigned char *vbios_ver;
> +
> +     /* find anchor ATOMBIOSBK-AMD */
> +     vbios_ver = atom_find_str_in_rom(ctx, BIOS_VERSION_PREFIX, 3, 1024, 64);
> +     if (vbios_ver != NULL) {
> +             /* skip ATOMBIOSBK-AMD VER */
> +             vbios_ver += 18;
> +             memcpy(ctx->vbios_ver_str, vbios_ver, STRLEN_NORMAL);
> +     } else {
> +             ctx->vbios_ver_str[0] = '\0';
> +     }
> +}
> +
>   struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)  {
>       int base;
>       struct atom_context *ctx =
>           kzalloc(sizeof(struct atom_context), GFP_KERNEL);
>       char *str;
> +     struct _ATOM_ROM_HEADER *atom_rom_header;
> +     struct _ATOM_MASTER_DATA_TABLE *master_table;
> +     struct _ATOM_FIRMWARE_INFO *atom_fw_info;
>       u16 idx;
>
>       if (!ctx)
> @@ -1353,6 +1510,21 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>               strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
>       }
>
> +     atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
> +     if (atom_rom_header->usMasterDataTableOffset != 0) {
> +             master_table = (struct _ATOM_MASTER_DATA_TABLE *)
> +                             CSTR(atom_rom_header->usMasterDataTableOffset);
> +             if (master_table->ListOfDataTables.FirmwareInfo != 0) {
> +                     atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
> +                                     CSTR(master_table->ListOfDataTables.FirmwareInfo);
> +                     ctx->version = atom_fw_info->ulFirmwareRevision;
> +             }
> +     }
> +
> +     atom_get_vbios_name(ctx);
> +     atom_get_vbios_pn(ctx);
> +     atom_get_vbios_date(ctx);
> +     atom_get_vbios_version(ctx);
>
>       return ctx;
>   }
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h 
> b/drivers/gpu/drm/amd/amdgpu/atom.h
> index d279759cab47..0c1839824520 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.h
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
> @@ -112,6 +112,10 @@ struct drm_device;
>   #define ATOM_IO_SYSIO               2
>   #define ATOM_IO_IIO         0x80
>
> +#define STRLEN_NORMAL                32
> +#define STRLEN_LONG          64
> +#define STRLEN_VERYLONG              254
> +
>   struct card_info {
>       struct drm_device *dev;
>       void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
> @@ -140,6 +144,12 @@ struct atom_context {
>       uint32_t *scratch;
>       int scratch_size_bytes;
>       char vbios_version[20];
> +
> +     uint8_t name[STRLEN_LONG];
> +     uint8_t vbios_pn[STRLEN_LONG];
> +     uint32_t version;
> +     uint8_t vbios_ver_str[STRLEN_NORMAL];
> +     uint8_t date[STRLEN_NORMAL];
>   };
>
>   extern int amdgpu_atom_debug;
> diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h 
> b/drivers/gpu/drm/amd/include/atomfirmware.h
> index 275468e4be60..28deecc2f990 100644
> --- a/drivers/gpu/drm/amd/include/atomfirmware.h
> +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
> @@ -197,6 +197,9 @@ enum atom_dp_vs_preemph_def{
>     DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
>   };
>
> +#define BIOS_ATOM_PREFIX   "ATOMBIOS"
> +#define BIOS_VERSION_PREFIX  "ATOMBIOSBK-AMD"
> +#define BIOS_STRING_LENGTH 43
>
>   /*
>   enum atom_string_def{
> @@ -215,6 +218,8 @@ enum atombios_image_offset{
>     MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
>     OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
>     OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
> +  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
> +  OFFSET_TO_VBIOS_DATE                       = 0x50,
>   };
>
>   
> /*********************************************************************
> ******* diff --git a/include/uapi/drm/amdgpu_drm.h 
> b/include/uapi/drm/amdgpu_drm.h index 9169df7fadee..155fd9918b4d 
> 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -756,6 +756,8 @@ struct drm_amdgpu_cs_chunk_data {
>       #define AMDGPU_INFO_VBIOS_SIZE          0x1
>       /* Subquery id: Query vbios image */
>       #define AMDGPU_INFO_VBIOS_IMAGE         0x2
> +     /* Subquery id: Query vbios info */
> +     #define AMDGPU_INFO_VBIOS_INFO          0x3
>   /* Query UVD handles */
>   #define AMDGPU_INFO_NUM_HANDLES                     0x1C
>   /* Query sensor related information */ @@ -949,6 +951,14 @@ struct 
> drm_amdgpu_info_firmware {
>       __u32 feature;
>   };
>
> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +};
> +
>   #define AMDGPU_VRAM_TYPE_UNKNOWN 0
>   #define AMDGPU_VRAM_TYPE_GDDR1 1
>   #define AMDGPU_VRAM_TYPE_DDR2  2
> --
> 2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&amp;data=04%7C01%7Ctom.stdenis%40amd.com%7C332524597a5e42ad491908d919ff414f%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637569406377960645%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=ZFBUbqu1VjvQkpnQ4Wy6Q4XE9CB2IcFltOq3Iv12F7U%3D&amp;reserved=0
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-05-19  2:41       ` Gu, JiaWei (Will)
@ 2021-05-19  3:10         ` Marek Olšák
  0 siblings, 0 replies; 47+ messages in thread
From: Marek Olšák @ 2021-05-19  3:10 UTC (permalink / raw)
  To: Gu, JiaWei (Will)
  Cc: StDenis, Tom, amd-gfx mailing list, Deng, Emily, Deucher,
	Alexander, Koenig, Christian, Nieto, David M


[-- Attachment #1.1: Type: text/plain, Size: 16571 bytes --]

Mesa doesn't have any use for this. It should be ok to expose just the
ioctl without userspace because it's just vbios info.

Marek

On Tue., May 18, 2021, 22:41 Gu, JiaWei (Will), <JiaWei.Gu@amd.com> wrote:

> [AMD Official Use Only - Internal Distribution Only]
>
> Thanks Tom's suggestion.
> I'm fine to replace ioctl with sysfs.
>
> Hi all, how about this sysfs alternative?
>
> And if it's a must to insist on ioctl, is there any Mesa expert to help
> provide the patch?
>
> Best regards,
> Jiawei
>
>
> -----Original Message-----
> From: StDenis, Tom <Tom.StDenis@amd.com>
> Sent: Tuesday, May 18, 2021 9:26 PM
> To: Koenig, Christian <Christian.Koenig@amd.com>; Gu, JiaWei (Will) <
> JiaWei.Gu@amd.com>; amd-gfx@lists.freedesktop.org; Nieto, David M <
> David.Nieto@amd.com>; maraeo@gmail.com; Deucher, Alexander <
> Alexander.Deucher@amd.com>
> Cc: Deng, Emily <Emily.Deng@amd.com>
> Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> [AMD Official Use Only - Internal Distribution Only]
>
> If changing the ioctl is an issue why not just use sysfs?  umr already
> makes uses of all three for it's purposes so it's fine by me for either.
>
> Tom
>
> ________________________________________
> From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> on behalf of
> Christian König <christian.koenig@amd.com>
> Sent: Tuesday, May 18, 2021 09:17
> To: Gu, JiaWei (Will); amd-gfx@lists.freedesktop.org; Nieto, David M;
> maraeo@gmail.com; Deucher, Alexander
> Cc: Deng, Emily
> Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> Well not an expert on that stuff, but looks like that should work for me.
>
> Question is can you provide a patch to use that information in Mesa as
> well? Umr might be sufficient as well as justification for upstreaming, but
> I want to be better save than sorry.
>
> Unless Marek has a better idea maybe add the vbios version to the string
> returned by GLX_MESA_query_renderer or something like that.
>
> Thanks,
> Christian.
>
> Am 18.05.21 um 14:19 schrieb Gu, JiaWei (Will):
> > [AMD Official Use Only - Internal Distribution Only]
> >
> > Hi all,
> >
> > Please help confirm that we're all fine with this new struct in uapi in
> this V3 patch:
> >
> > +struct drm_amdgpu_info_vbios {
> > +     __u8 name[64];
> > +     __u8 vbios_pn[64];
> > +     __u32 version;
> > +     __u8 vbios_ver_str[32];
> > +     __u8 date[32];
> > +};
> >
> > Best regards,
> > Jiawei
> >
> > -----Original Message-----
> > From: Jiawei Gu <Jiawei.Gu@amd.com>
> > Sent: Tuesday, May 18, 2021 8:16 PM
> > To: amd-gfx@lists.freedesktop.org; Koenig, Christian
> > <Christian.Koenig@amd.com>; Nieto, David M <David.Nieto@amd.com>;
> > maraeo@gmail.com; Deucher, Alexander <Alexander.Deucher@amd.com>
> > Cc: Deng, Emily <Emily.Deng@amd.com>; Gu, JiaWei (Will)
> > <JiaWei.Gu@amd.com>
> > Subject: [PATCH] drm/amdgpu: Add vbios info ioctl interface
> >
> > Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.
> >
> > Provides a way for the user application to get the VBIOS information
> without having to parse the binary.
> > It is useful for the user to be able to display in a simple way the
> VBIOS version in their system if they happen to encounter an issue.
> >
> > V2:
> > Use numeric serial.
> > Parse and expose vbios version string.
> >
> > V3:
> > Remove redundant data in drm_amdgpu_info_vbios struct.
> >
> > Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com>
> > ---
> >   drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  15 ++
> >   drivers/gpu/drm/amd/amdgpu/atom.c          | 172 +++++++++++++++++++++
> >   drivers/gpu/drm/amd/amdgpu/atom.h          |  10 ++
> >   drivers/gpu/drm/amd/include/atomfirmware.h |   5 +
> >   include/uapi/drm/amdgpu_drm.h              |  10 ++
> >   5 files changed, 212 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> > index 8d12e474745a..524e4fe5efe8 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> > @@ -861,6 +861,21 @@ int amdgpu_info_ioctl(struct drm_device *dev, void
> *data, struct drm_file *filp)
> >                                           min((size_t)size,
> (size_t)(bios_size - bios_offset)))
> >                                       ? -EFAULT : 0;
> >               }
> > +             case AMDGPU_INFO_VBIOS_INFO: {
> > +                     struct drm_amdgpu_info_vbios vbios_info = {};
> > +                     struct atom_context *atom_context;
> > +
> > +                     atom_context = adev->mode_info.atom_context;
> > +                     memcpy(vbios_info.name, atom_context->name,
> sizeof(atom_context->name));
> > +                     memcpy(vbios_info.vbios_pn,
> atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
> > +                     vbios_info.version = atom_context->version;
> > +                     memcpy(vbios_info.vbios_ver_str,
> atom_context->vbios_ver_str,
> > +
>  sizeof(atom_context->vbios_ver_str));
> > +                     memcpy(vbios_info.date, atom_context->date,
> > +sizeof(atom_context->date));
> > +
> > +                     return copy_to_user(out, &vbios_info,
> > +                                             min((size_t)size,
> sizeof(vbios_info))) ? -EFAULT : 0;
> > +             }
> >               default:
> >                       DRM_DEBUG_KMS("Invalid request %d\n",
> >                                       info->vbios_info.type); diff
> > --git a/drivers/gpu/drm/amd/amdgpu/atom.c
> > b/drivers/gpu/drm/amd/amdgpu/atom.c
> > index 3dcb8b32f48b..6fa2229b7229 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/atom.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
> > @@ -31,6 +31,7 @@
> >
> >   #define ATOM_DEBUG
> >
> > +#include "atomfirmware.h"
> >   #include "atom.h"
> >   #include "atom-names.h"
> >   #include "atom-bits.h"
> > @@ -1299,12 +1300,168 @@ static void atom_index_iio(struct atom_context
> *ctx, int base)
> >       }
> >   }
> >
> > +static void atom_get_vbios_name(struct atom_context *ctx) {
> > +     unsigned char *p_rom;
> > +     unsigned char str_num;
> > +     unsigned short off_to_vbios_str;
> > +     unsigned char *c_ptr;
> > +     int name_size;
> > +     int i;
> > +
> > +     const char *na = "--N/A--";
> > +     char *back;
> > +
> > +     p_rom = ctx->bios;
> > +
> > +     str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
> > +     if (str_num != 0) {
> > +             off_to_vbios_str =
> > +                     *(unsigned short *)(p_rom +
> > + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> > +
> > +             c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
> > +     } else {
> > +             /* do not know where to find name */
> > +             memcpy(ctx->name, na, 7);
> > +             ctx->name[7] = 0;
> > +             return;
> > +     }
> > +
> > +     /*
> > +      * skip the atombios strings, usually 4
> > +      * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
> > +      */
> > +     for (i = 0; i < str_num; i++) {
> > +             while (*c_ptr != 0)
> > +                     c_ptr++;
> > +             c_ptr++;
> > +     }
> > +
> > +     /* skip the following 2 chars: 0x0D 0x0A */
> > +     c_ptr += 2;
> > +
> > +     name_size = strnlen(c_ptr, STRLEN_LONG - 1);
> > +     memcpy(ctx->name, c_ptr, name_size);
> > +     back = ctx->name + name_size;
> > +     while ((*--back) == ' ')
> > +             ;
> > +     *(back + 1) = '\0';
> > +}
> > +
> > +static void atom_get_vbios_date(struct atom_context *ctx) {
> > +     unsigned char *p_rom;
> > +     unsigned char *date_in_rom;
> > +
> > +     p_rom = ctx->bios;
> > +
> > +     date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
> > +
> > +     ctx->date[0] = '2';
> > +     ctx->date[1] = '0';
> > +     ctx->date[2] = date_in_rom[6];
> > +     ctx->date[3] = date_in_rom[7];
> > +     ctx->date[4] = '/';
> > +     ctx->date[5] = date_in_rom[0];
> > +     ctx->date[6] = date_in_rom[1];
> > +     ctx->date[7] = '/';
> > +     ctx->date[8] = date_in_rom[3];
> > +     ctx->date[9] = date_in_rom[4];
> > +     ctx->date[10] = ' ';
> > +     ctx->date[11] = date_in_rom[9];
> > +     ctx->date[12] = date_in_rom[10];
> > +     ctx->date[13] = date_in_rom[11];
> > +     ctx->date[14] = date_in_rom[12];
> > +     ctx->date[15] = date_in_rom[13];
> > +     ctx->date[16] = '\0';
> > +}
> > +
> > +static unsigned char *atom_find_str_in_rom(struct atom_context *ctx,
> char *str, int start,
> > +                                        int end, int maxlen) {
> > +     unsigned long str_off;
> > +     unsigned char *p_rom;
> > +     unsigned short str_len;
> > +
> > +     str_off = 0;
> > +     str_len = strnlen(str, maxlen);
> > +     p_rom = ctx->bios;
> > +
> > +     for (; start <= end; ++start) {
> > +             for (str_off = 0; str_off < str_len; ++str_off) {
> > +                     if (str[str_off] != *(p_rom + start + str_off))
> > +                             break;
> > +             }
> > +
> > +             if (str_off == str_len || str[str_off] == 0)
> > +                     return p_rom + start;
> > +     }
> > +     return NULL;
> > +}
> > +
> > +static void atom_get_vbios_pn(struct atom_context *ctx) {
> > +     unsigned char *p_rom;
> > +     unsigned short off_to_vbios_str;
> > +     unsigned char *vbios_str;
> > +     int count;
> > +
> > +     off_to_vbios_str = 0;
> > +     p_rom = ctx->bios;
> > +
> > +     if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
> > +             off_to_vbios_str =
> > +                     *(unsigned short *)(p_rom +
> > + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> > +
> > +             vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
> > +     } else {
> > +             vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
> > +     }
> > +
> > +     if (*vbios_str == 0) {
> > +             vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3,
> 1024, 64);
> > +             if (vbios_str == NULL)
> > +                     vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
> > +     }
> > +     if (vbios_str != NULL && *vbios_str == 0)
> > +             vbios_str++;
> > +
> > +     if (vbios_str != NULL) {
> > +             count = 0;
> > +             while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >=
> ' ' &&
> > +                    vbios_str[count] <= 'z') {
> > +                     ctx->vbios_pn[count] = vbios_str[count];
> > +                     count++;
> > +             }
> > +
> > +             ctx->vbios_pn[count] = 0;
> > +     }
> > +}
> > +
> > +static void atom_get_vbios_version(struct atom_context *ctx) {
> > +     unsigned char *vbios_ver;
> > +
> > +     /* find anchor ATOMBIOSBK-AMD */
> > +     vbios_ver = atom_find_str_in_rom(ctx, BIOS_VERSION_PREFIX, 3,
> 1024, 64);
> > +     if (vbios_ver != NULL) {
> > +             /* skip ATOMBIOSBK-AMD VER */
> > +             vbios_ver += 18;
> > +             memcpy(ctx->vbios_ver_str, vbios_ver, STRLEN_NORMAL);
> > +     } else {
> > +             ctx->vbios_ver_str[0] = '\0';
> > +     }
> > +}
> > +
> >   struct atom_context *amdgpu_atom_parse(struct card_info *card, void
> *bios)  {
> >       int base;
> >       struct atom_context *ctx =
> >           kzalloc(sizeof(struct atom_context), GFP_KERNEL);
> >       char *str;
> > +     struct _ATOM_ROM_HEADER *atom_rom_header;
> > +     struct _ATOM_MASTER_DATA_TABLE *master_table;
> > +     struct _ATOM_FIRMWARE_INFO *atom_fw_info;
> >       u16 idx;
> >
> >       if (!ctx)
> > @@ -1353,6 +1510,21 @@ struct atom_context *amdgpu_atom_parse(struct
> card_info *card, void *bios)
> >               strlcpy(ctx->vbios_version, str,
> sizeof(ctx->vbios_version));
> >       }
> >
> > +     atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
> > +     if (atom_rom_header->usMasterDataTableOffset != 0) {
> > +             master_table = (struct _ATOM_MASTER_DATA_TABLE *)
> > +
>  CSTR(atom_rom_header->usMasterDataTableOffset);
> > +             if (master_table->ListOfDataTables.FirmwareInfo != 0) {
> > +                     atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
> > +
>  CSTR(master_table->ListOfDataTables.FirmwareInfo);
> > +                     ctx->version = atom_fw_info->ulFirmwareRevision;
> > +             }
> > +     }
> > +
> > +     atom_get_vbios_name(ctx);
> > +     atom_get_vbios_pn(ctx);
> > +     atom_get_vbios_date(ctx);
> > +     atom_get_vbios_version(ctx);
> >
> >       return ctx;
> >   }
> > diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h
> > b/drivers/gpu/drm/amd/amdgpu/atom.h
> > index d279759cab47..0c1839824520 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/atom.h
> > +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
> > @@ -112,6 +112,10 @@ struct drm_device;
> >   #define ATOM_IO_SYSIO               2
> >   #define ATOM_IO_IIO         0x80
> >
> > +#define STRLEN_NORMAL                32
> > +#define STRLEN_LONG          64
> > +#define STRLEN_VERYLONG              254
> > +
> >   struct card_info {
> >       struct drm_device *dev;
> >       void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*
> filled by driver */
> > @@ -140,6 +144,12 @@ struct atom_context {
> >       uint32_t *scratch;
> >       int scratch_size_bytes;
> >       char vbios_version[20];
> > +
> > +     uint8_t name[STRLEN_LONG];
> > +     uint8_t vbios_pn[STRLEN_LONG];
> > +     uint32_t version;
> > +     uint8_t vbios_ver_str[STRLEN_NORMAL];
> > +     uint8_t date[STRLEN_NORMAL];
> >   };
> >
> >   extern int amdgpu_atom_debug;
> > diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h
> > b/drivers/gpu/drm/amd/include/atomfirmware.h
> > index 275468e4be60..28deecc2f990 100644
> > --- a/drivers/gpu/drm/amd/include/atomfirmware.h
> > +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
> > @@ -197,6 +197,9 @@ enum atom_dp_vs_preemph_def{
> >     DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
> >   };
> >
> > +#define BIOS_ATOM_PREFIX   "ATOMBIOS"
> > +#define BIOS_VERSION_PREFIX  "ATOMBIOSBK-AMD"
> > +#define BIOS_STRING_LENGTH 43
> >
> >   /*
> >   enum atom_string_def{
> > @@ -215,6 +218,8 @@ enum atombios_image_offset{
> >     MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the
> terminator 0x0!*/
> >     OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
> >     OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
> > +  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
> > +  OFFSET_TO_VBIOS_DATE                       = 0x50,
> >   };
> >
> >
> > /*********************************************************************
> > ******* diff --git a/include/uapi/drm/amdgpu_drm.h
> > b/include/uapi/drm/amdgpu_drm.h index 9169df7fadee..155fd9918b4d
> > 100644
> > --- a/include/uapi/drm/amdgpu_drm.h
> > +++ b/include/uapi/drm/amdgpu_drm.h
> > @@ -756,6 +756,8 @@ struct drm_amdgpu_cs_chunk_data {
> >       #define AMDGPU_INFO_VBIOS_SIZE          0x1
> >       /* Subquery id: Query vbios image */
> >       #define AMDGPU_INFO_VBIOS_IMAGE         0x2
> > +     /* Subquery id: Query vbios info */
> > +     #define AMDGPU_INFO_VBIOS_INFO          0x3
> >   /* Query UVD handles */
> >   #define AMDGPU_INFO_NUM_HANDLES                     0x1C
> >   /* Query sensor related information */ @@ -949,6 +951,14 @@ struct
> > drm_amdgpu_info_firmware {
> >       __u32 feature;
> >   };
> >
> > +struct drm_amdgpu_info_vbios {
> > +     __u8 name[64];
> > +     __u8 vbios_pn[64];
> > +     __u32 version;
> > +     __u8 vbios_ver_str[32];
> > +     __u8 date[32];
> > +};
> > +
> >   #define AMDGPU_VRAM_TYPE_UNKNOWN 0
> >   #define AMDGPU_VRAM_TYPE_GDDR1 1
> >   #define AMDGPU_VRAM_TYPE_DDR2  2
> > --
> > 2.17.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
>
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&amp;data=04%7C01%7Ctom.stdenis%40amd.com%7C332524597a5e42ad491908d919ff414f%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637569406377960645%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=ZFBUbqu1VjvQkpnQ4Wy6Q4XE9CB2IcFltOq3Iv12F7U%3D&amp;reserved=0
>

[-- Attachment #1.2: Type: text/html, Size: 22799 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-05-20  1:30                   ` Gu, JiaWei (Will)
@ 2021-05-20 10:58                     ` Christian König
  0 siblings, 0 replies; 47+ messages in thread
From: Christian König @ 2021-05-20 10:58 UTC (permalink / raw)
  To: Gu, JiaWei (Will),
	Deucher, Alexander, Nieto, David M, Koenig, Christian, amd-gfx,
	maraeo
  Cc: Deng, Emily


[-- Attachment #1.1: Type: text/plain, Size: 24977 bytes --]

Kudos should go to Nirmoy who mentioned that tool in one of our 
discussions. But, yeah it is rather useful :)

Regards,
Christian.

Am 20.05.21 um 03:30 schrieb Gu, JiaWei (Will):
>
> [AMD Official Use Only - Internal Distribution Only]
>
> Thanks Christian!
>
> Happy to learn new tricks.
>
> Best regards,
>
> Jiawei
>
> *From:* Christian König <ckoenig.leichtzumerken@gmail.com>
> *Sent:* Wednesday, May 19, 2021 9:23 PM
> *To:* Deucher, Alexander <Alexander.Deucher@amd.com>; Gu, JiaWei 
> (Will) <JiaWei.Gu@amd.com>; Nieto, David M <David.Nieto@amd.com>; 
> Koenig, Christian <Christian.Koenig@amd.com>; 
> amd-gfx@lists.freedesktop.org; maraeo@gmail.com
> *Cc:* Deng, Emily <Emily.Deng@amd.com>
> *Subject:* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> Good point.
>
> If you want to double check the alignment you can use something like 
> "pahole drivers/gpu/drm/amd/amdgpu/amdgpu.ko -C drm_amdgpu_info_vbios" 
> after building the kernel module.
>
> Regards,
> Christian.
>
> Am 19.05.21 um 15:09 schrieb Deucher, Alexander:
>
>     [Public]
>
>     The structure is not 64 bit aligned.  I think you want something like:
>
>     > +struct drm_amdgpu_info_vbios {
>     > +     __u8 name[64];
>     > +     __u8 vbios_pn[64];
>     > +     __u32 version;
>
>     > +     __u32 pad;
>
>     > +     __u8 vbios_ver_str[32];
>     > +     __u8 date[32];
>     > +};
>
>     ------------------------------------------------------------------------
>
>     *From:*Gu, JiaWei (Will) <JiaWei.Gu@amd.com>
>     <mailto:JiaWei.Gu@amd.com>
>     *Sent:* Tuesday, May 18, 2021 1:58 AM
>     *To:* Nieto, David M <David.Nieto@amd.com>
>     <mailto:David.Nieto@amd.com>; Koenig, Christian
>     <Christian.Koenig@amd.com> <mailto:Christian.Koenig@amd.com>;
>     amd-gfx@lists.freedesktop.org
>     <mailto:amd-gfx@lists.freedesktop.org>
>     <amd-gfx@lists.freedesktop.org>
>     <mailto:amd-gfx@lists.freedesktop.org>; maraeo@gmail.com
>     <mailto:maraeo@gmail.com> <maraeo@gmail.com>
>     <mailto:maraeo@gmail.com>; Deucher, Alexander
>     <Alexander.Deucher@amd.com> <mailto:Alexander.Deucher@amd.com>
>     *Cc:* Deng, Emily <Emily.Deng@amd.com> <mailto:Emily.Deng@amd.com>
>     *Subject:* RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
>     [Public]
>
>     Hi all,
>
>     Then the struct looks like:
>
>     > +struct drm_amdgpu_info_vbios {
>     > +     __u8 name[64];
>     > +     __u8 vbios_pn[64];
>     > +     __u32 version;
>     > +     __u8 vbios_ver_str[32];
>     > +     __u8 date[32];
>     > +};
>
>     Sample output:
>
>     vbios name : NAVI12 A0 XT D30501 8GB EVAL 1150e/334m HYN/SAM
>     vbios pn : 113-D3050100-104
>     vbios version : 285409288
>     vbios ver_str : 017.003.000.008.016956
>     vbios date : 2021/05/03 23:32
>
>     Please help double confirm that we’re all fine with it and there’s
>     no need to add & remove anything.
>
>     Best regards,
>
>     Jiawei
>
>     *From:* Nieto, David M <David.Nieto@amd.com>
>     <mailto:David.Nieto@amd.com>
>     *Sent:* Tuesday, May 18, 2021 12:40 PM
>     *To:* Gu, JiaWei (Will) <JiaWei.Gu@amd.com>
>     <mailto:JiaWei.Gu@amd.com>; Koenig, Christian
>     <Christian.Koenig@amd.com> <mailto:Christian.Koenig@amd.com>;
>     amd-gfx@lists.freedesktop.org
>     <mailto:amd-gfx@lists.freedesktop.org>; maraeo@gmail.com
>     <mailto:maraeo@gmail.com>; Deucher, Alexander
>     <Alexander.Deucher@amd.com> <mailto:Alexander.Deucher@amd.com>
>     *Cc:* Deng, Emily <Emily.Deng@amd.com> <mailto:Emily.Deng@amd.com>
>     *Subject:* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
>     [Public]
>
>     Yes, let's remove that too,
>
>     Thanks,
>
>     David
>
>     ------------------------------------------------------------------------
>
>     *From:*Gu, JiaWei (Will) <JiaWei.Gu@amd.com
>     <mailto:JiaWei.Gu@amd.com>>
>     *Sent:* Monday, May 17, 2021 8:07 PM
>     *To:* Nieto, David M <David.Nieto@amd.com
>     <mailto:David.Nieto@amd.com>>; Koenig, Christian
>     <Christian.Koenig@amd.com <mailto:Christian.Koenig@amd.com>>;
>     amd-gfx@lists.freedesktop.org
>     <mailto:amd-gfx@lists.freedesktop.org>
>     <amd-gfx@lists.freedesktop.org
>     <mailto:amd-gfx@lists.freedesktop.org>>; maraeo@gmail.com
>     <mailto:maraeo@gmail.com> <maraeo@gmail.com
>     <mailto:maraeo@gmail.com>>; Deucher, Alexander
>     <Alexander.Deucher@amd.com <mailto:Alexander.Deucher@amd.com>>
>     *Cc:* Deng, Emily <Emily.Deng@amd.com <mailto:Emily.Deng@amd.com>>
>     *Subject:* RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
>     [AMD Official Use Only - Internal Distribution Only]
>
>     OK let’s remove serial.
>
>     dbdf comes from this:
>
>     vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number,
>     adev->pdev->devfn);
>
>     I think we can remove dbdf as well.
>
>     Best regards,
>
>     Jiawei
>
>     *From:* Nieto, David M <David.Nieto@amd.com
>     <mailto:David.Nieto@amd.com>>
>     *Sent:* Tuesday, May 18, 2021 10:45 AM
>     *To:* Gu, JiaWei (Will) <JiaWei.Gu@amd.com
>     <mailto:JiaWei.Gu@amd.com>>; Koenig, Christian
>     <Christian.Koenig@amd.com <mailto:Christian.Koenig@amd.com>>;
>     amd-gfx@lists.freedesktop.org
>     <mailto:amd-gfx@lists.freedesktop.org>; maraeo@gmail.com
>     <mailto:maraeo@gmail.com>; Deucher, Alexander
>     <Alexander.Deucher@amd.com <mailto:Alexander.Deucher@amd.com>>
>     *Cc:* Deng, Emily <Emily.Deng@amd.com <mailto:Emily.Deng@amd.com>>
>     *Subject:* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
>     [AMD Official Use Only - Internal Distribution Only]
>
>     The serial number is ASIC information, not VBIOS information, and
>     it is still available as a sysfs node... I don't think we should
>     put it there.
>
>     Not sure what dbdf stands for.
>
>     ------------------------------------------------------------------------
>
>     *From:*Gu, JiaWei (Will) <JiaWei.Gu@amd.com
>     <mailto:JiaWei.Gu@amd.com>>
>     *Sent:* Monday, May 17, 2021 7:11 PM
>     *To:* Koenig, Christian <Christian.Koenig@amd.com
>     <mailto:Christian.Koenig@amd.com>>; amd-gfx@lists.freedesktop.org
>     <mailto:amd-gfx@lists.freedesktop.org>
>     <amd-gfx@lists.freedesktop.org
>     <mailto:amd-gfx@lists.freedesktop.org>>; Nieto, David M
>     <David.Nieto@amd.com <mailto:David.Nieto@amd.com>>;
>     maraeo@gmail.com <mailto:maraeo@gmail.com> <maraeo@gmail.com
>     <mailto:maraeo@gmail.com>>; Deucher, Alexander
>     <Alexander.Deucher@amd.com <mailto:Alexander.Deucher@amd.com>>
>     *Cc:* Deng, Emily <Emily.Deng@amd.com <mailto:Emily.Deng@amd.com>>
>     *Subject:* RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
>     [AMD Official Use Only - Internal Distribution Only]
>
>     So I guess the dbdf is also needed to be removed?
>     And how about serial?
>
>     > +struct drm_amdgpu_info_vbios {
>     > +     __u8 name[64];
>     > +     __u32 dbdf; // do we need this?
>     > +     __u8 vbios_pn[64];
>     > +     __u32 version;
>     > +     __u8 vbios_ver_str[32];
>     > +     __u8 date[32];
>     > +     __u64 serial; // do we need this?
>     > +};
>
>     Best regards,
>     Jiawei
>
>     -----Original Message-----
>     From: Koenig, Christian <Christian.Koenig@amd.com
>     <mailto:Christian.Koenig@amd.com>>
>     Sent: Monday, May 17, 2021 8:26 PM
>     To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com
>     <mailto:JiaWei.Gu@amd.com>>; amd-gfx@lists.freedesktop.org
>     <mailto:amd-gfx@lists.freedesktop.org>; Nieto, David M
>     <David.Nieto@amd.com <mailto:David.Nieto@amd.com>>;
>     maraeo@gmail.com <mailto:maraeo@gmail.com>; Deucher, Alexander
>     <Alexander.Deucher@amd.com <mailto:Alexander.Deucher@amd.com>>
>     Cc: Deng, Emily <Emily.Deng@amd.com <mailto:Emily.Deng@amd.com>>
>     Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
>     I'm not very familiar with the technical background why we have
>     the fields here once more.
>
>     But of hand we should at least remove everything which is also
>     available from the PCI information.
>
>     E.g. dev_id, rev_id, sub_dev_id, sub_ved_id.
>
>     Regards,
>     Christian.
>
>     Am 17.05.21 um 14:17 schrieb Gu, JiaWei (Will):
>     > [AMD Official Use Only - Internal Distribution Only]
>     >
>     > Hi all,
>     >
>     > Thanks Christian's suggestion.
>     > I reverted the previous patches and squash them into this single
>     one.
>     >
>     > As this patch shows, the current uapi change looks like this:
>     >
>     > +struct drm_amdgpu_info_vbios {
>     > +     __u8 name[64];
>     > +     __u32 dbdf;
>     > +     __u8 vbios_pn[64];
>     > +     __u32 version;
>     > +     __u8 vbios_ver_str[32];
>     > +     __u8 date[32];
>     > +     __u64 serial;
>     > +     __u32 dev_id;
>     > +     __u32 rev_id;
>     > +     __u32 sub_dev_id;
>     > +     __u32 sub_ved_id;
>     > +};
>     >
>     > As we know there's some redundant info in this struct.
>     > Please feel free to give any comments or suggestion about what
>     it should & shouldn't include.
>     >
>     > Best regards,
>     > Jiawei
>     >
>     > -----Original Message-----
>     > From: Jiawei Gu <Jiawei.Gu@amd.com <mailto:Jiawei.Gu@amd.com>>
>     > Sent: Monday, May 17, 2021 8:08 PM
>     > To: amd-gfx@lists.freedesktop.org
>     <mailto:amd-gfx@lists.freedesktop.org>; Koenig, Christian
>     > <Christian.Koenig@amd.com <mailto:Christian.Koenig@amd.com>>;
>     Nieto, David M <David.Nieto@amd.com <mailto:David.Nieto@amd.com>>;
>     > maraeo@gmail.com <mailto:maraeo@gmail.com>; Deucher, Alexander
>     <Alexander.Deucher@amd.com <mailto:Alexander.Deucher@amd.com>>
>     > Cc: Deng, Emily <Emily.Deng@amd.com
>     <mailto:Emily.Deng@amd.com>>; Gu, JiaWei (Will)
>     > <JiaWei.Gu@amd.com <mailto:JiaWei.Gu@amd.com>>
>     > Subject: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>     >
>     > Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.
>     >
>     > Provides a way for the user application to get the VBIOS
>     information without having to parse the binary.
>     > It is useful for the user to be able to display in a simple way
>     the VBIOS version in their system if they happen to encounter an
>     issue.
>     >
>     > V2:
>     > Use numeric serial.
>     > Parse and expose vbios version string.
>     >
>     > Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com
>     <mailto:Jiawei.Gu@amd.com>>
>     > Acked-by: Christian König <christian.koenig@amd.com
>     <mailto:christian.koenig@amd.com>>
>     > ---
>     > drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c |  21 +++
>     > drivers/gpu/drm/amd/amdgpu/atom.c | 174 +++++++++++++++++++++
>     > drivers/gpu/drm/amd/amdgpu/atom.h |  12 ++
>     > drivers/gpu/drm/amd/include/atomfirmware.h |   5 +
>     > include/uapi/drm/amdgpu_drm.h |  16 ++
>     >   5 files changed, 228 insertions(+)
>     >
>     > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>     > b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>     > index 8d12e474745a..30e4fed3de22 100644
>     > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>     > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>     > @@ -861,6 +861,27 @@ int amdgpu_info_ioctl(struct drm_device
>     *dev, void *data, struct drm_file *filp)
>     >                                            min((size_t)size,
>     (size_t)(bios_size - bios_offset)))
>     >                                        ? -EFAULT : 0;
>     >                }
>     > +             case AMDGPU_INFO_VBIOS_INFO: {
>     > +                     struct drm_amdgpu_info_vbios vbios_info = {};
>     > +                     struct atom_context *atom_context;
>     > +
>     > +                     atom_context = adev->mode_info.atom_context;
>     > + memcpy(vbios_info.name, atom_context->name,
>     sizeof(atom_context->name));
>     > + vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number,
>     adev->pdev->devfn);
>     > + memcpy(vbios_info.vbios_pn, atom_context->vbios_pn,
>     sizeof(atom_context->vbios_pn));
>     > + vbios_info.version = atom_context->version;
>     > + memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str,
>     > + sizeof(atom_context->vbios_ver_str));
>     > + memcpy(vbios_info.date, atom_context->date,
>     sizeof(atom_context->date));
>     > + vbios_info.serial = adev->unique_id;
>     > + vbios_info.dev_id = adev->pdev->device;
>     > + vbios_info.rev_id = adev->pdev->revision;
>     > + vbios_info.sub_dev_id = atom_context->sub_dev_id;
>     > + vbios_info.sub_ved_id = atom_context->sub_ved_id;
>     > +
>     > +                     return copy_to_user(out, &vbios_info,
>     > + min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
>     > +             }
>     >                default:
>     > DRM_DEBUG_KMS("Invalid request %d\n",
>     >                                        info->vbios_info.type);
>     > diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c
>     > b/drivers/gpu/drm/amd/amdgpu/atom.c
>     > index 3dcb8b32f48b..542b2c2414e4 100644
>     > --- a/drivers/gpu/drm/amd/amdgpu/atom.c
>     > +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
>     > @@ -31,6 +31,7 @@
>     >
>     >   #define ATOM_DEBUG
>     >
>     > +#include "atomfirmware.h"
>     >   #include "atom.h"
>     >   #include "atom-names.h"
>     >   #include "atom-bits.h"
>     > @@ -1299,12 +1300,168 @@ static void atom_index_iio(struct
>     atom_context *ctx, int base)
>     >        }
>     >   }
>     >
>     > +static void atom_get_vbios_name(struct atom_context *ctx) {
>     > +     unsigned char *p_rom;
>     > +     unsigned char str_num;
>     > +     unsigned short off_to_vbios_str;
>     > +     unsigned char *c_ptr;
>     > +     int name_size;
>     > +     int i;
>     > +
>     > +     const char *na = "--N/A--";
>     > +     char *back;
>     > +
>     > +     p_rom = ctx->bios;
>     > +
>     > +     str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
>     > +     if (str_num != 0) {
>     > +             off_to_vbios_str =
>     > +                     *(unsigned short *)(p_rom +
>     OFFSET_TO_GET_ATOMBIOS_STRING_START);
>     > +
>     > +             c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
>     > +     } else {
>     > +             /* do not know where to find name */
>     > +             memcpy(ctx->name, na, 7);
>     > +             ctx->name[7] = 0;
>     > +             return;
>     > +     }
>     > +
>     > +     /*
>     > +      * skip the atombios strings, usually 4
>     > +      * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory
>     type
>     > +      */
>     > +     for (i = 0; i < str_num; i++) {
>     > +             while (*c_ptr != 0)
>     > +                     c_ptr++;
>     > +             c_ptr++;
>     > +     }
>     > +
>     > +     /* skip the following 2 chars: 0x0D 0x0A */
>     > +     c_ptr += 2;
>     > +
>     > +     name_size = strnlen(c_ptr, STRLEN_LONG - 1);
>     > +     memcpy(ctx->name, c_ptr, name_size);
>     > +     back = ctx->name + name_size;
>     > +     while ((*--back) == ' ')
>     > +             ;
>     > +     *(back + 1) = '\0';
>     > +}
>     > +
>     > +static void atom_get_vbios_date(struct atom_context *ctx) {
>     > +     unsigned char *p_rom;
>     > +     unsigned char *date_in_rom;
>     > +
>     > +     p_rom = ctx->bios;
>     > +
>     > +     date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
>     > +
>     > +     ctx->date[0] = '2';
>     > +     ctx->date[1] = '0';
>     > +     ctx->date[2] = date_in_rom[6];
>     > +     ctx->date[3] = date_in_rom[7];
>     > +     ctx->date[4] = '/';
>     > +     ctx->date[5] = date_in_rom[0];
>     > +     ctx->date[6] = date_in_rom[1];
>     > +     ctx->date[7] = '/';
>     > +     ctx->date[8] = date_in_rom[3];
>     > +     ctx->date[9] = date_in_rom[4];
>     > +     ctx->date[10] = ' ';
>     > +     ctx->date[11] = date_in_rom[9];
>     > +     ctx->date[12] = date_in_rom[10];
>     > +     ctx->date[13] = date_in_rom[11];
>     > +     ctx->date[14] = date_in_rom[12];
>     > +     ctx->date[15] = date_in_rom[13];
>     > +     ctx->date[16] = '\0';
>     > +}
>     > +
>     > +static unsigned char *atom_find_str_in_rom(struct atom_context
>     *ctx, char *str, int start,
>     > + int end, int maxlen)
>     > +{
>     > +     unsigned long str_off;
>     > +     unsigned char *p_rom;
>     > +     unsigned short str_len;
>     > +
>     > +     str_off = 0;
>     > +     str_len = strnlen(str, maxlen);
>     > +     p_rom = ctx->bios;
>     > +
>     > +     for (; start <= end; ++start) {
>     > +             for (str_off = 0; str_off < str_len; ++str_off) {
>     > +                     if (str[str_off] != *(p_rom + start +
>     str_off))
>     > + break;
>     > +             }
>     > +
>     > +             if (str_off == str_len || str[str_off] == 0)
>     > +                     return p_rom + start;
>     > +     }
>     > +     return NULL;
>     > +}
>     > +
>     > +static void atom_get_vbios_pn(struct atom_context *ctx) {
>     > +     unsigned char *p_rom;
>     > +     unsigned short off_to_vbios_str;
>     > +     unsigned char *vbios_str;
>     > +     int count;
>     > +
>     > +     off_to_vbios_str = 0;
>     > +     p_rom = ctx->bios;
>     > +
>     > +     if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) !=
>     0) {
>     > +             off_to_vbios_str =
>     > +                     *(unsigned short *)(p_rom +
>     OFFSET_TO_GET_ATOMBIOS_STRING_START);
>     > +
>     > +             vbios_str = (unsigned char *)(p_rom +
>     off_to_vbios_str);
>     > +     } else {
>     > +             vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
>     > +     }
>     > +
>     > +     if (*vbios_str == 0) {
>     > +             vbios_str = atom_find_str_in_rom(ctx,
>     BIOS_ATOM_PREFIX, 3, 1024, 64);
>     > +             if (vbios_str == NULL)
>     > +                     vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
>     > +     }
>     > +     if (vbios_str != NULL && *vbios_str == 0)
>     > +             vbios_str++;
>     > +
>     > +     if (vbios_str != NULL) {
>     > +             count = 0;
>     > +             while ((count < BIOS_STRING_LENGTH) &&
>     vbios_str[count] >= ' ' &&
>     > + vbios_str[count] <= 'z') {
>     > + ctx->vbios_pn[count] = vbios_str[count];
>     > +                     count++;
>     > +             }
>     > +
>     > + ctx->vbios_pn[count] = 0;
>     > +     }
>     > +}
>     > +
>     > +static void atom_get_vbios_version(struct atom_context *ctx) {
>     > +     unsigned char *vbios_ver;
>     > +
>     > +     /* find anchor ATOMBIOSBK-AMD */
>     > +     vbios_ver = atom_find_str_in_rom(ctx, BIOS_VERSION_PREFIX,
>     3, 1024, 64);
>     > +     if (vbios_ver != NULL) {
>     > +             /* skip ATOMBIOSBK-AMD VER */
>     > +             vbios_ver += 18;
>     > + memcpy(ctx->vbios_ver_str, vbios_ver, STRLEN_NORMAL);
>     > +     } else {
>     > + ctx->vbios_ver_str[0] = '\0';
>     > +     }
>     > +}
>     > +
>     >   struct atom_context *amdgpu_atom_parse(struct card_info *card,
>     void *bios)  {
>     >        int base;
>     >        struct atom_context *ctx =
>     >            kzalloc(sizeof(struct atom_context), GFP_KERNEL);
>     >        char *str;
>     > +     struct _ATOM_ROM_HEADER *atom_rom_header;
>     > +     struct _ATOM_MASTER_DATA_TABLE *master_table;
>     > +     struct _ATOM_FIRMWARE_INFO *atom_fw_info;
>     >        u16 idx;
>     >
>     >        if (!ctx)
>     > @@ -1353,6 +1510,23 @@ struct atom_context
>     *amdgpu_atom_parse(struct card_info *card, void *bios)
>     > strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
>     >        }
>     >
>     > +     atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
>     > +     ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
>     > +     ctx->sub_ved_id = atom_rom_header->usSubsystemID;
>     > +     if (atom_rom_header->usMasterDataTableOffset != 0) {
>     > +             master_table = (struct _ATOM_MASTER_DATA_TABLE *)
>     > + CSTR(atom_rom_header->usMasterDataTableOffset);
>     > +             if (master_table->ListOfDataTables.FirmwareInfo !=
>     0) {
>     > +                     atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
>     > + CSTR(master_table->ListOfDataTables.FirmwareInfo);
>     > + ctx->version = atom_fw_info->ulFirmwareRevision;
>     > +             }
>     > +     }
>     > +
>     > +     atom_get_vbios_name(ctx);
>     > +     atom_get_vbios_pn(ctx);
>     > +     atom_get_vbios_date(ctx);
>     > +     atom_get_vbios_version(ctx);
>     >
>     >        return ctx;
>     >   }
>     > diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h
>     > b/drivers/gpu/drm/amd/amdgpu/atom.h
>     > index d279759cab47..6463ce6e756d 100644
>     > --- a/drivers/gpu/drm/amd/amdgpu/atom.h
>     > +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
>     > @@ -112,6 +112,10 @@ struct drm_device;
>     >   #define ATOM_IO_SYSIO               2
>     >   #define ATOM_IO_IIO         0x80
>     >
>     > +#define STRLEN_NORMAL                32
>     > +#define STRLEN_LONG          64
>     > +#define STRLEN_VERYLONG              254
>     > +
>     >   struct card_info {
>     >        struct drm_device *dev;
>     >        void (* reg_write)(struct card_info *, uint32_t,
>     uint32_t);   /* filled by driver */
>     > @@ -140,6 +144,14 @@ struct atom_context {
>     >        uint32_t *scratch;
>     >        int scratch_size_bytes;
>     >        char vbios_version[20];
>     > +
>     > +     uint8_t name[STRLEN_LONG];
>     > +     uint8_t vbios_pn[STRLEN_LONG];
>     > +     uint32_t version;
>     > +     uint8_t vbios_ver_str[STRLEN_NORMAL];
>     > +     uint8_t date[STRLEN_NORMAL];
>     > +     uint32_t sub_dev_id;
>     > +     uint32_t sub_ved_id;
>     >   };
>     >
>     >   extern int amdgpu_atom_debug;
>     > diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h
>     > b/drivers/gpu/drm/amd/include/atomfirmware.h
>     > index 275468e4be60..28deecc2f990 100644
>     > --- a/drivers/gpu/drm/amd/include/atomfirmware.h
>     > +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
>     > @@ -197,6 +197,9 @@ enum atom_dp_vs_preemph_def{
>     >     DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
>     >   };
>     >
>     > +#define BIOS_ATOM_PREFIX "ATOMBIOS"
>     > +#define BIOS_VERSION_PREFIX "ATOMBIOSBK-AMD"
>     > +#define BIOS_STRING_LENGTH 43
>     >
>     >   /*
>     >   enum atom_string_def{
>     > @@ -215,6 +218,8 @@ enum atombios_image_offset{
>     > MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE = 20,  /*including the
>     terminator 0x0!*/
>     > OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS = 0x2f,
>     > OFFSET_TO_GET_ATOMBIOS_STRING_START = 0x6e,
>     > + OFFSET_TO_VBIOS_PART_NUMBER = 0x80,
>     > + OFFSET_TO_VBIOS_DATE = 0x50,
>     >   };
>     >
>     >
>     >
>     /*********************************************************************
>     > ******* diff --git a/include/uapi/drm/amdgpu_drm.h
>     > b/include/uapi/drm/amdgpu_drm.h index 9169df7fadee..e0f98ca9a755
>     > 100644
>     > --- a/include/uapi/drm/amdgpu_drm.h
>     > +++ b/include/uapi/drm/amdgpu_drm.h
>     > @@ -756,6 +756,8 @@ struct drm_amdgpu_cs_chunk_data {
>     >        #define AMDGPU_INFO_VBIOS_SIZE          0x1
>     >        /* Subquery id: Query vbios image */
>     >        #define AMDGPU_INFO_VBIOS_IMAGE         0x2
>     > +     /* Subquery id: Query vbios info */
>     > +     #define AMDGPU_INFO_VBIOS_INFO          0x3
>     >   /* Query UVD handles */
>     >   #define AMDGPU_INFO_NUM_HANDLES 0x1C
>     >   /* Query sensor related information */ @@ -949,6 +951,20 @@
>     struct
>     > drm_amdgpu_info_firmware {
>     >        __u32 feature;
>     >   };
>     >
>     > +struct drm_amdgpu_info_vbios {
>     > +     __u8 name[64];
>     > +     __u32 dbdf;
>     > +     __u8 vbios_pn[64];
>     > +     __u32 version;
>     > +     __u8 vbios_ver_str[32];
>     > +     __u8 date[32];
>     > +     __u64 serial;
>     > +     __u32 dev_id;
>     > +     __u32 rev_id;
>     > +     __u32 sub_dev_id;
>     > +     __u32 sub_ved_id;
>     > +};
>     > +
>     >   #define AMDGPU_VRAM_TYPE_UNKNOWN 0
>     >   #define AMDGPU_VRAM_TYPE_GDDR1 1
>     >   #define AMDGPU_VRAM_TYPE_DDR2  2
>     > --
>     > 2.17.1
>
>     _______________________________________________
>
>     amd-gfx mailing list
>
>     amd-gfx@lists.freedesktop.org  <mailto:amd-gfx@lists.freedesktop.org>
>
>     https://lists.freedesktop.org/mailman/listinfo/amd-gfx  <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=04%7C01%7CJiaWei.Gu%40amd.com%7Ccd8e7257279a437d9b2208d91ac93b3e%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637570273857847028%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=zhrziSJ55q4VfYYd23yKYoIQdocTAtZ4v%2FyKvU9TJhs%3D&reserved=0>
>


[-- Attachment #1.2: Type: text/html, Size: 67643 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-05-20  2:58 Jiawei Gu
@ 2021-05-20  3:24 ` Alex Deucher
  0 siblings, 0 replies; 47+ messages in thread
From: Alex Deucher @ 2021-05-20  3:24 UTC (permalink / raw)
  To: Jiawei Gu
  Cc: Marek Olsak, amd-gfx list, Emily Deng, Deucher, Alexander,
	Christian Koenig, Nieto, David M

On Wed, May 19, 2021 at 10:59 PM Jiawei Gu <Jiawei.Gu@amd.com> wrote:
>
> Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.
>
> Provides a way for the user application to get the VBIOS
> information without having to parse the binary.
> It is useful for the user to be able to display in a simple way the VBIOS
> version in their system if they happen to encounter an issue.
>
> V2:
> Use numeric serial.
> Parse and expose vbios version string.
>
> V3:
> Remove redundant data in drm_amdgpu_info_vbios struct.
>
> V4:
> 64 bit alignment in drm_amdgpu_info_vbios.
>
> Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com>

Assuming you send out the updated umr patch,
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  15 ++
>  drivers/gpu/drm/amd/amdgpu/atom.c          | 172 +++++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/atom.h          |  10 ++
>  drivers/gpu/drm/amd/include/atomfirmware.h |   5 +
>  include/uapi/drm/amdgpu_drm.h              |  11 ++
>  5 files changed, 213 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index 8d12e474745a..524e4fe5efe8 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -861,6 +861,21 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
>                                             min((size_t)size, (size_t)(bios_size - bios_offset)))
>                                         ? -EFAULT : 0;
>                 }
> +               case AMDGPU_INFO_VBIOS_INFO: {
> +                       struct drm_amdgpu_info_vbios vbios_info = {};
> +                       struct atom_context *atom_context;
> +
> +                       atom_context = adev->mode_info.atom_context;
> +                       memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
> +                       memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
> +                       vbios_info.version = atom_context->version;
> +                       memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str,
> +                                               sizeof(atom_context->vbios_ver_str));
> +                       memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
> +
> +                       return copy_to_user(out, &vbios_info,
> +                                               min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
> +               }
>                 default:
>                         DRM_DEBUG_KMS("Invalid request %d\n",
>                                         info->vbios_info.type);
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c
> index 3dcb8b32f48b..6fa2229b7229 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.c
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
> @@ -31,6 +31,7 @@
>
>  #define ATOM_DEBUG
>
> +#include "atomfirmware.h"
>  #include "atom.h"
>  #include "atom-names.h"
>  #include "atom-bits.h"
> @@ -1299,12 +1300,168 @@ static void atom_index_iio(struct atom_context *ctx, int base)
>         }
>  }
>
> +static void atom_get_vbios_name(struct atom_context *ctx)
> +{
> +       unsigned char *p_rom;
> +       unsigned char str_num;
> +       unsigned short off_to_vbios_str;
> +       unsigned char *c_ptr;
> +       int name_size;
> +       int i;
> +
> +       const char *na = "--N/A--";
> +       char *back;
> +
> +       p_rom = ctx->bios;
> +
> +       str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
> +       if (str_num != 0) {
> +               off_to_vbios_str =
> +                       *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +               c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
> +       } else {
> +               /* do not know where to find name */
> +               memcpy(ctx->name, na, 7);
> +               ctx->name[7] = 0;
> +               return;
> +       }
> +
> +       /*
> +        * skip the atombios strings, usually 4
> +        * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
> +        */
> +       for (i = 0; i < str_num; i++) {
> +               while (*c_ptr != 0)
> +                       c_ptr++;
> +               c_ptr++;
> +       }
> +
> +       /* skip the following 2 chars: 0x0D 0x0A */
> +       c_ptr += 2;
> +
> +       name_size = strnlen(c_ptr, STRLEN_LONG - 1);
> +       memcpy(ctx->name, c_ptr, name_size);
> +       back = ctx->name + name_size;
> +       while ((*--back) == ' ')
> +               ;
> +       *(back + 1) = '\0';
> +}
> +
> +static void atom_get_vbios_date(struct atom_context *ctx)
> +{
> +       unsigned char *p_rom;
> +       unsigned char *date_in_rom;
> +
> +       p_rom = ctx->bios;
> +
> +       date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
> +
> +       ctx->date[0] = '2';
> +       ctx->date[1] = '0';
> +       ctx->date[2] = date_in_rom[6];
> +       ctx->date[3] = date_in_rom[7];
> +       ctx->date[4] = '/';
> +       ctx->date[5] = date_in_rom[0];
> +       ctx->date[6] = date_in_rom[1];
> +       ctx->date[7] = '/';
> +       ctx->date[8] = date_in_rom[3];
> +       ctx->date[9] = date_in_rom[4];
> +       ctx->date[10] = ' ';
> +       ctx->date[11] = date_in_rom[9];
> +       ctx->date[12] = date_in_rom[10];
> +       ctx->date[13] = date_in_rom[11];
> +       ctx->date[14] = date_in_rom[12];
> +       ctx->date[15] = date_in_rom[13];
> +       ctx->date[16] = '\0';
> +}
> +
> +static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
> +                                          int end, int maxlen)
> +{
> +       unsigned long str_off;
> +       unsigned char *p_rom;
> +       unsigned short str_len;
> +
> +       str_off = 0;
> +       str_len = strnlen(str, maxlen);
> +       p_rom = ctx->bios;
> +
> +       for (; start <= end; ++start) {
> +               for (str_off = 0; str_off < str_len; ++str_off) {
> +                       if (str[str_off] != *(p_rom + start + str_off))
> +                               break;
> +               }
> +
> +               if (str_off == str_len || str[str_off] == 0)
> +                       return p_rom + start;
> +       }
> +       return NULL;
> +}
> +
> +static void atom_get_vbios_pn(struct atom_context *ctx)
> +{
> +       unsigned char *p_rom;
> +       unsigned short off_to_vbios_str;
> +       unsigned char *vbios_str;
> +       int count;
> +
> +       off_to_vbios_str = 0;
> +       p_rom = ctx->bios;
> +
> +       if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
> +               off_to_vbios_str =
> +                       *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +               vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
> +       } else {
> +               vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
> +       }
> +
> +       if (*vbios_str == 0) {
> +               vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
> +               if (vbios_str == NULL)
> +                       vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
> +       }
> +       if (vbios_str != NULL && *vbios_str == 0)
> +               vbios_str++;
> +
> +       if (vbios_str != NULL) {
> +               count = 0;
> +               while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
> +                      vbios_str[count] <= 'z') {
> +                       ctx->vbios_pn[count] = vbios_str[count];
> +                       count++;
> +               }
> +
> +               ctx->vbios_pn[count] = 0;
> +       }
> +}
> +
> +static void atom_get_vbios_version(struct atom_context *ctx)
> +{
> +       unsigned char *vbios_ver;
> +
> +       /* find anchor ATOMBIOSBK-AMD */
> +       vbios_ver = atom_find_str_in_rom(ctx, BIOS_VERSION_PREFIX, 3, 1024, 64);
> +       if (vbios_ver != NULL) {
> +               /* skip ATOMBIOSBK-AMD VER */
> +               vbios_ver += 18;
> +               memcpy(ctx->vbios_ver_str, vbios_ver, STRLEN_NORMAL);
> +       } else {
> +               ctx->vbios_ver_str[0] = '\0';
> +       }
> +}
> +
>  struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>  {
>         int base;
>         struct atom_context *ctx =
>             kzalloc(sizeof(struct atom_context), GFP_KERNEL);
>         char *str;
> +       struct _ATOM_ROM_HEADER *atom_rom_header;
> +       struct _ATOM_MASTER_DATA_TABLE *master_table;
> +       struct _ATOM_FIRMWARE_INFO *atom_fw_info;
>         u16 idx;
>
>         if (!ctx)
> @@ -1353,6 +1510,21 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>                 strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
>         }
>
> +       atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
> +       if (atom_rom_header->usMasterDataTableOffset != 0) {
> +               master_table = (struct _ATOM_MASTER_DATA_TABLE *)
> +                               CSTR(atom_rom_header->usMasterDataTableOffset);
> +               if (master_table->ListOfDataTables.FirmwareInfo != 0) {
> +                       atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
> +                                       CSTR(master_table->ListOfDataTables.FirmwareInfo);
> +                       ctx->version = atom_fw_info->ulFirmwareRevision;
> +               }
> +       }
> +
> +       atom_get_vbios_name(ctx);
> +       atom_get_vbios_pn(ctx);
> +       atom_get_vbios_date(ctx);
> +       atom_get_vbios_version(ctx);
>
>         return ctx;
>  }
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h
> index d279759cab47..0c1839824520 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.h
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
> @@ -112,6 +112,10 @@ struct drm_device;
>  #define ATOM_IO_SYSIO          2
>  #define ATOM_IO_IIO            0x80
>
> +#define STRLEN_NORMAL          32
> +#define STRLEN_LONG            64
> +#define STRLEN_VERYLONG                254
> +
>  struct card_info {
>         struct drm_device *dev;
>         void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
> @@ -140,6 +144,12 @@ struct atom_context {
>         uint32_t *scratch;
>         int scratch_size_bytes;
>         char vbios_version[20];
> +
> +       uint8_t name[STRLEN_LONG];
> +       uint8_t vbios_pn[STRLEN_LONG];
> +       uint32_t version;
> +       uint8_t vbios_ver_str[STRLEN_NORMAL];
> +       uint8_t date[STRLEN_NORMAL];
>  };
>
>  extern int amdgpu_atom_debug;
> diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
> index 275468e4be60..28deecc2f990 100644
> --- a/drivers/gpu/drm/amd/include/atomfirmware.h
> +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
> @@ -197,6 +197,9 @@ enum atom_dp_vs_preemph_def{
>    DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
>  };
>
> +#define BIOS_ATOM_PREFIX   "ATOMBIOS"
> +#define BIOS_VERSION_PREFIX  "ATOMBIOSBK-AMD"
> +#define BIOS_STRING_LENGTH 43
>
>  /*
>  enum atom_string_def{
> @@ -215,6 +218,8 @@ enum atombios_image_offset{
>    MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
>    OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
>    OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
> +  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
> +  OFFSET_TO_VBIOS_DATE                       = 0x50,
>  };
>
>  /****************************************************************************
> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
> index 9169df7fadee..90bcd64c0147 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -756,6 +756,8 @@ struct drm_amdgpu_cs_chunk_data {
>         #define AMDGPU_INFO_VBIOS_SIZE          0x1
>         /* Subquery id: Query vbios image */
>         #define AMDGPU_INFO_VBIOS_IMAGE         0x2
> +       /* Subquery id: Query vbios info */
> +       #define AMDGPU_INFO_VBIOS_INFO          0x3
>  /* Query UVD handles */
>  #define AMDGPU_INFO_NUM_HANDLES                        0x1C
>  /* Query sensor related information */
> @@ -949,6 +951,15 @@ struct drm_amdgpu_info_firmware {
>         __u32 feature;
>  };
>
> +struct drm_amdgpu_info_vbios {
> +       __u8 name[64];
> +       __u8 vbios_pn[64];
> +       __u32 version;
> +       __u32 pad;
> +       __u8 vbios_ver_str[32];
> +       __u8 date[32];
> +};
> +
>  #define AMDGPU_VRAM_TYPE_UNKNOWN 0
>  #define AMDGPU_VRAM_TYPE_GDDR1 1
>  #define AMDGPU_VRAM_TYPE_DDR2  2
> --
> 2.17.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH] drm/amdgpu: Add vbios info ioctl interface
@ 2021-05-20  2:58 Jiawei Gu
  2021-05-20  3:24 ` Alex Deucher
  0 siblings, 1 reply; 47+ messages in thread
From: Jiawei Gu @ 2021-05-20  2:58 UTC (permalink / raw)
  To: amd-gfx, christian.koenig, david.nieto, maraeo, alexander.deucher
  Cc: emily.deng, Jiawei Gu

Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.

Provides a way for the user application to get the VBIOS
information without having to parse the binary.
It is useful for the user to be able to display in a simple way the VBIOS
version in their system if they happen to encounter an issue.

V2:
Use numeric serial.
Parse and expose vbios version string.

V3:
Remove redundant data in drm_amdgpu_info_vbios struct.

V4:
64 bit alignment in drm_amdgpu_info_vbios.

Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  15 ++
 drivers/gpu/drm/amd/amdgpu/atom.c          | 172 +++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/atom.h          |  10 ++
 drivers/gpu/drm/amd/include/atomfirmware.h |   5 +
 include/uapi/drm/amdgpu_drm.h              |  11 ++
 5 files changed, 213 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 8d12e474745a..524e4fe5efe8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -861,6 +861,21 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
 					    min((size_t)size, (size_t)(bios_size - bios_offset)))
 					? -EFAULT : 0;
 		}
+		case AMDGPU_INFO_VBIOS_INFO: {
+			struct drm_amdgpu_info_vbios vbios_info = {};
+			struct atom_context *atom_context;
+
+			atom_context = adev->mode_info.atom_context;
+			memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
+			memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
+			vbios_info.version = atom_context->version;
+			memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str,
+						sizeof(atom_context->vbios_ver_str));
+			memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
+
+			return copy_to_user(out, &vbios_info,
+						min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
+		}
 		default:
 			DRM_DEBUG_KMS("Invalid request %d\n",
 					info->vbios_info.type);
diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c
index 3dcb8b32f48b..6fa2229b7229 100644
--- a/drivers/gpu/drm/amd/amdgpu/atom.c
+++ b/drivers/gpu/drm/amd/amdgpu/atom.c
@@ -31,6 +31,7 @@
 
 #define ATOM_DEBUG
 
+#include "atomfirmware.h"
 #include "atom.h"
 #include "atom-names.h"
 #include "atom-bits.h"
@@ -1299,12 +1300,168 @@ static void atom_index_iio(struct atom_context *ctx, int base)
 	}
 }
 
+static void atom_get_vbios_name(struct atom_context *ctx)
+{
+	unsigned char *p_rom;
+	unsigned char str_num;
+	unsigned short off_to_vbios_str;
+	unsigned char *c_ptr;
+	int name_size;
+	int i;
+
+	const char *na = "--N/A--";
+	char *back;
+
+	p_rom = ctx->bios;
+
+	str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
+	if (str_num != 0) {
+		off_to_vbios_str =
+			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
+
+		c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
+	} else {
+		/* do not know where to find name */
+		memcpy(ctx->name, na, 7);
+		ctx->name[7] = 0;
+		return;
+	}
+
+	/*
+	 * skip the atombios strings, usually 4
+	 * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
+	 */
+	for (i = 0; i < str_num; i++) {
+		while (*c_ptr != 0)
+			c_ptr++;
+		c_ptr++;
+	}
+
+	/* skip the following 2 chars: 0x0D 0x0A */
+	c_ptr += 2;
+
+	name_size = strnlen(c_ptr, STRLEN_LONG - 1);
+	memcpy(ctx->name, c_ptr, name_size);
+	back = ctx->name + name_size;
+	while ((*--back) == ' ')
+		;
+	*(back + 1) = '\0';
+}
+
+static void atom_get_vbios_date(struct atom_context *ctx)
+{
+	unsigned char *p_rom;
+	unsigned char *date_in_rom;
+
+	p_rom = ctx->bios;
+
+	date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
+
+	ctx->date[0] = '2';
+	ctx->date[1] = '0';
+	ctx->date[2] = date_in_rom[6];
+	ctx->date[3] = date_in_rom[7];
+	ctx->date[4] = '/';
+	ctx->date[5] = date_in_rom[0];
+	ctx->date[6] = date_in_rom[1];
+	ctx->date[7] = '/';
+	ctx->date[8] = date_in_rom[3];
+	ctx->date[9] = date_in_rom[4];
+	ctx->date[10] = ' ';
+	ctx->date[11] = date_in_rom[9];
+	ctx->date[12] = date_in_rom[10];
+	ctx->date[13] = date_in_rom[11];
+	ctx->date[14] = date_in_rom[12];
+	ctx->date[15] = date_in_rom[13];
+	ctx->date[16] = '\0';
+}
+
+static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
+					   int end, int maxlen)
+{
+	unsigned long str_off;
+	unsigned char *p_rom;
+	unsigned short str_len;
+
+	str_off = 0;
+	str_len = strnlen(str, maxlen);
+	p_rom = ctx->bios;
+
+	for (; start <= end; ++start) {
+		for (str_off = 0; str_off < str_len; ++str_off) {
+			if (str[str_off] != *(p_rom + start + str_off))
+				break;
+		}
+
+		if (str_off == str_len || str[str_off] == 0)
+			return p_rom + start;
+	}
+	return NULL;
+}
+
+static void atom_get_vbios_pn(struct atom_context *ctx)
+{
+	unsigned char *p_rom;
+	unsigned short off_to_vbios_str;
+	unsigned char *vbios_str;
+	int count;
+
+	off_to_vbios_str = 0;
+	p_rom = ctx->bios;
+
+	if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
+		off_to_vbios_str =
+			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
+
+		vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
+	} else {
+		vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
+	}
+
+	if (*vbios_str == 0) {
+		vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
+		if (vbios_str == NULL)
+			vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
+	}
+	if (vbios_str != NULL && *vbios_str == 0)
+		vbios_str++;
+
+	if (vbios_str != NULL) {
+		count = 0;
+		while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
+		       vbios_str[count] <= 'z') {
+			ctx->vbios_pn[count] = vbios_str[count];
+			count++;
+		}
+
+		ctx->vbios_pn[count] = 0;
+	}
+}
+
+static void atom_get_vbios_version(struct atom_context *ctx)
+{
+	unsigned char *vbios_ver;
+
+	/* find anchor ATOMBIOSBK-AMD */
+	vbios_ver = atom_find_str_in_rom(ctx, BIOS_VERSION_PREFIX, 3, 1024, 64);
+	if (vbios_ver != NULL) {
+		/* skip ATOMBIOSBK-AMD VER */
+		vbios_ver += 18;
+		memcpy(ctx->vbios_ver_str, vbios_ver, STRLEN_NORMAL);
+	} else {
+		ctx->vbios_ver_str[0] = '\0';
+	}
+}
+
 struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
 {
 	int base;
 	struct atom_context *ctx =
 	    kzalloc(sizeof(struct atom_context), GFP_KERNEL);
 	char *str;
+	struct _ATOM_ROM_HEADER *atom_rom_header;
+	struct _ATOM_MASTER_DATA_TABLE *master_table;
+	struct _ATOM_FIRMWARE_INFO *atom_fw_info;
 	u16 idx;
 
 	if (!ctx)
@@ -1353,6 +1510,21 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
 		strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
 	}
 
+	atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
+	if (atom_rom_header->usMasterDataTableOffset != 0) {
+		master_table = (struct _ATOM_MASTER_DATA_TABLE *)
+				CSTR(atom_rom_header->usMasterDataTableOffset);
+		if (master_table->ListOfDataTables.FirmwareInfo != 0) {
+			atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
+					CSTR(master_table->ListOfDataTables.FirmwareInfo);
+			ctx->version = atom_fw_info->ulFirmwareRevision;
+		}
+	}
+
+	atom_get_vbios_name(ctx);
+	atom_get_vbios_pn(ctx);
+	atom_get_vbios_date(ctx);
+	atom_get_vbios_version(ctx);
 
 	return ctx;
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h
index d279759cab47..0c1839824520 100644
--- a/drivers/gpu/drm/amd/amdgpu/atom.h
+++ b/drivers/gpu/drm/amd/amdgpu/atom.h
@@ -112,6 +112,10 @@ struct drm_device;
 #define ATOM_IO_SYSIO		2
 #define ATOM_IO_IIO		0x80
 
+#define STRLEN_NORMAL		32
+#define STRLEN_LONG		64
+#define STRLEN_VERYLONG		254
+
 struct card_info {
 	struct drm_device *dev;
 	void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
@@ -140,6 +144,12 @@ struct atom_context {
 	uint32_t *scratch;
 	int scratch_size_bytes;
 	char vbios_version[20];
+
+	uint8_t name[STRLEN_LONG];
+	uint8_t vbios_pn[STRLEN_LONG];
+	uint32_t version;
+	uint8_t vbios_ver_str[STRLEN_NORMAL];
+	uint8_t date[STRLEN_NORMAL];
 };
 
 extern int amdgpu_atom_debug;
diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
index 275468e4be60..28deecc2f990 100644
--- a/drivers/gpu/drm/amd/include/atomfirmware.h
+++ b/drivers/gpu/drm/amd/include/atomfirmware.h
@@ -197,6 +197,9 @@ enum atom_dp_vs_preemph_def{
   DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
 };
 
+#define BIOS_ATOM_PREFIX   "ATOMBIOS"
+#define BIOS_VERSION_PREFIX  "ATOMBIOSBK-AMD"
+#define BIOS_STRING_LENGTH 43
 
 /*
 enum atom_string_def{
@@ -215,6 +218,8 @@ enum atombios_image_offset{
   MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
   OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
   OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
+  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
+  OFFSET_TO_VBIOS_DATE                       = 0x50,
 };
 
 /****************************************************************************   
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index 9169df7fadee..90bcd64c0147 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -756,6 +756,8 @@ struct drm_amdgpu_cs_chunk_data {
 	#define AMDGPU_INFO_VBIOS_SIZE		0x1
 	/* Subquery id: Query vbios image */
 	#define AMDGPU_INFO_VBIOS_IMAGE		0x2
+	/* Subquery id: Query vbios info */
+	#define AMDGPU_INFO_VBIOS_INFO		0x3
 /* Query UVD handles */
 #define AMDGPU_INFO_NUM_HANDLES			0x1C
 /* Query sensor related information */
@@ -949,6 +951,15 @@ struct drm_amdgpu_info_firmware {
 	__u32 feature;
 };
 
+struct drm_amdgpu_info_vbios {
+	__u8 name[64];
+	__u8 vbios_pn[64];
+	__u32 version;
+	__u32 pad;
+	__u8 vbios_ver_str[32];
+	__u8 date[32];
+};
+
 #define AMDGPU_VRAM_TYPE_UNKNOWN 0
 #define AMDGPU_VRAM_TYPE_GDDR1 1
 #define AMDGPU_VRAM_TYPE_DDR2  2
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-05-19 13:23                 ` Christian König
@ 2021-05-20  1:30                   ` Gu, JiaWei (Will)
  2021-05-20 10:58                     ` Christian König
  0 siblings, 1 reply; 47+ messages in thread
From: Gu, JiaWei (Will) @ 2021-05-20  1:30 UTC (permalink / raw)
  To: Christian König, Deucher, Alexander, Nieto, David M, Koenig,
	Christian, amd-gfx, maraeo
  Cc: Deng, Emily


[-- Attachment #1.1: Type: text/plain, Size: 22333 bytes --]

[AMD Official Use Only - Internal Distribution Only]

Thanks Christian!

Happy to learn new tricks.

Best regards,
Jiawei

From: Christian König <ckoenig.leichtzumerken@gmail.com>
Sent: Wednesday, May 19, 2021 9:23 PM
To: Deucher, Alexander <Alexander.Deucher@amd.com>; Gu, JiaWei (Will) <JiaWei.Gu@amd.com>; Nieto, David M <David.Nieto@amd.com>; Koenig, Christian <Christian.Koenig@amd.com>; amd-gfx@lists.freedesktop.org; maraeo@gmail.com
Cc: Deng, Emily <Emily.Deng@amd.com>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

Good point.

If you want to double check the alignment you can use something like "pahole drivers/gpu/drm/amd/amdgpu/amdgpu.ko -C drm_amdgpu_info_vbios" after building the kernel module.

Regards,
Christian.
Am 19.05.21 um 15:09 schrieb Deucher, Alexander:

[Public]

The structure is not 64 bit aligned.  I think you want something like:

> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u32 pad;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +};
________________________________
From: Gu, JiaWei (Will) <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com>
Sent: Tuesday, May 18, 2021 1:58 AM
To: Nieto, David M <David.Nieto@amd.com><mailto:David.Nieto@amd.com>; Koenig, Christian <Christian.Koenig@amd.com><mailto:Christian.Koenig@amd.com>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org><mailto:amd-gfx@lists.freedesktop.org>; maraeo@gmail.com<mailto:maraeo@gmail.com> <maraeo@gmail.com><mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com><mailto:Alexander.Deucher@amd.com>
Cc: Deng, Emily <Emily.Deng@amd.com><mailto:Emily.Deng@amd.com>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface


[Public]


Hi all,



Then the struct looks like:



> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +};



Sample output:



vbios name : NAVI12 A0 XT D30501 8GB EVAL 1150e/334m HYN/SAM
vbios pn : 113-D3050100-104
vbios version : 285409288
vbios ver_str : 017.003.000.008.016956
vbios date : 2021/05/03 23:32

Please help double confirm that we're all fine with it and there's no need to add & remove anything.



Best regards,

Jiawei



From: Nieto, David M <David.Nieto@amd.com><mailto:David.Nieto@amd.com>
Sent: Tuesday, May 18, 2021 12:40 PM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com>; Koenig, Christian <Christian.Koenig@amd.com><mailto:Christian.Koenig@amd.com>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>; maraeo@gmail.com<mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com><mailto:Alexander.Deucher@amd.com>
Cc: Deng, Emily <Emily.Deng@amd.com><mailto:Emily.Deng@amd.com>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface



[Public]



Yes, let's remove that too,



Thanks,



David

________________________________

From: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>
Sent: Monday, May 17, 2021 8:07 PM
To: Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>>; maraeo@gmail.com<mailto:maraeo@gmail.com> <maraeo@gmail.com<mailto:maraeo@gmail.com>>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface



[AMD Official Use Only - Internal Distribution Only]



OK let's remove serial.



dbdf comes from this:

vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);



I think we can remove dbdf as well.



Best regards,

Jiawei



From: Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>
Sent: Tuesday, May 18, 2021 10:45 AM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>; Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>; maraeo@gmail.com<mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface



[AMD Official Use Only - Internal Distribution Only]



The serial number is ASIC information, not VBIOS information, and it is still available as a sysfs node... I don't think we should put it there.



Not sure what dbdf stands for.

________________________________

From: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>
Sent: Monday, May 17, 2021 7:11 PM
To: Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>>; Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; maraeo@gmail.com<mailto:maraeo@gmail.com> <maraeo@gmail.com<mailto:maraeo@gmail.com>>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface



[AMD Official Use Only - Internal Distribution Only]

So I guess the dbdf is also needed to be removed?
And how about serial?

> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf; // do we need this?
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial; // do we need this?
> +};

Best regards,
Jiawei

-----Original Message-----
From: Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>
Sent: Monday, May 17, 2021 8:26 PM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>; Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; maraeo@gmail.com<mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

I'm not very familiar with the technical background why we have the fields here once more.

But of hand we should at least remove everything which is also available from the PCI information.

E.g. dev_id, rev_id, sub_dev_id, sub_ved_id.

Regards,
Christian.

Am 17.05.21 um 14:17 schrieb Gu, JiaWei (Will):
> [AMD Official Use Only - Internal Distribution Only]
>
> Hi all,
>
> Thanks Christian's suggestion.
> I reverted the previous patches and squash them into this single one.
>
> As this patch shows, the current uapi change looks like this:
>
> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf;
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial;
> +     __u32 dev_id;
> +     __u32 rev_id;
> +     __u32 sub_dev_id;
> +     __u32 sub_ved_id;
> +};
>
> As we know there's some redundant info in this struct.
> Please feel free to give any comments or suggestion about what it should & shouldn't include.
>
> Best regards,
> Jiawei
>
> -----Original Message-----
> From: Jiawei Gu <Jiawei.Gu@amd.com<mailto:Jiawei.Gu@amd.com>>
> Sent: Monday, May 17, 2021 8:08 PM
> To: amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>; Koenig, Christian
> <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>;
> maraeo@gmail.com<mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
> Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>; Gu, JiaWei (Will)
> <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>
> Subject: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.
>
> Provides a way for the user application to get the VBIOS information without having to parse the binary.
> It is useful for the user to be able to display in a simple way the VBIOS version in their system if they happen to encounter an issue.
>
> V2:
> Use numeric serial.
> Parse and expose vbios version string.
>
> Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com<mailto:Jiawei.Gu@amd.com>>
> Acked-by: Christian König <christian.koenig@amd.com<mailto:christian.koenig@amd.com>>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  21 +++
>   drivers/gpu/drm/amd/amdgpu/atom.c          | 174 +++++++++++++++++++++
>   drivers/gpu/drm/amd/amdgpu/atom.h          |  12 ++
>   drivers/gpu/drm/amd/include/atomfirmware.h |   5 +
>   include/uapi/drm/amdgpu_drm.h              |  16 ++
>   5 files changed, 228 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index 8d12e474745a..30e4fed3de22 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -861,6 +861,27 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
>                                            min((size_t)size, (size_t)(bios_size - bios_offset)))
>                                        ? -EFAULT : 0;
>                }
> +             case AMDGPU_INFO_VBIOS_INFO: {
> +                     struct drm_amdgpu_info_vbios vbios_info = {};
> +                     struct atom_context *atom_context;
> +
> +                     atom_context = adev->mode_info.atom_context;
> +                     memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
> +                     vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
> +                     memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
> +                     vbios_info.version = atom_context->version;
> +                     memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str,
> +                                             sizeof(atom_context->vbios_ver_str));
> +                     memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
> +                     vbios_info.serial = adev->unique_id;
> +                     vbios_info.dev_id = adev->pdev->device;
> +                     vbios_info.rev_id = adev->pdev->revision;
> +                     vbios_info.sub_dev_id = atom_context->sub_dev_id;
> +                     vbios_info.sub_ved_id = atom_context->sub_ved_id;
> +
> +                     return copy_to_user(out, &vbios_info,
> +                                             min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
> +             }
>                default:
>                        DRM_DEBUG_KMS("Invalid request %d\n",
>                                        info->vbios_info.type);
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c
> b/drivers/gpu/drm/amd/amdgpu/atom.c
> index 3dcb8b32f48b..542b2c2414e4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.c
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
> @@ -31,6 +31,7 @@
>
>   #define ATOM_DEBUG
>
> +#include "atomfirmware.h"
>   #include "atom.h"
>   #include "atom-names.h"
>   #include "atom-bits.h"
> @@ -1299,12 +1300,168 @@ static void atom_index_iio(struct atom_context *ctx, int base)
>        }
>   }
>
> +static void atom_get_vbios_name(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned char str_num;
> +     unsigned short off_to_vbios_str;
> +     unsigned char *c_ptr;
> +     int name_size;
> +     int i;
> +
> +     const char *na = "--N/A--";
> +     char *back;
> +
> +     p_rom = ctx->bios;
> +
> +     str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
> +     if (str_num != 0) {
> +             off_to_vbios_str =
> +                     *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +             c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
> +     } else {
> +             /* do not know where to find name */
> +             memcpy(ctx->name, na, 7);
> +             ctx->name[7] = 0;
> +             return;
> +     }
> +
> +     /*
> +      * skip the atombios strings, usually 4
> +      * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
> +      */
> +     for (i = 0; i < str_num; i++) {
> +             while (*c_ptr != 0)
> +                     c_ptr++;
> +             c_ptr++;
> +     }
> +
> +     /* skip the following 2 chars: 0x0D 0x0A */
> +     c_ptr += 2;
> +
> +     name_size = strnlen(c_ptr, STRLEN_LONG - 1);
> +     memcpy(ctx->name, c_ptr, name_size);
> +     back = ctx->name + name_size;
> +     while ((*--back) == ' ')
> +             ;
> +     *(back + 1) = '\0';
> +}
> +
> +static void atom_get_vbios_date(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned char *date_in_rom;
> +
> +     p_rom = ctx->bios;
> +
> +     date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
> +
> +     ctx->date[0] = '2';
> +     ctx->date[1] = '0';
> +     ctx->date[2] = date_in_rom[6];
> +     ctx->date[3] = date_in_rom[7];
> +     ctx->date[4] = '/';
> +     ctx->date[5] = date_in_rom[0];
> +     ctx->date[6] = date_in_rom[1];
> +     ctx->date[7] = '/';
> +     ctx->date[8] = date_in_rom[3];
> +     ctx->date[9] = date_in_rom[4];
> +     ctx->date[10] = ' ';
> +     ctx->date[11] = date_in_rom[9];
> +     ctx->date[12] = date_in_rom[10];
> +     ctx->date[13] = date_in_rom[11];
> +     ctx->date[14] = date_in_rom[12];
> +     ctx->date[15] = date_in_rom[13];
> +     ctx->date[16] = '\0';
> +}
> +
> +static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
> +                                        int end, int maxlen)
> +{
> +     unsigned long str_off;
> +     unsigned char *p_rom;
> +     unsigned short str_len;
> +
> +     str_off = 0;
> +     str_len = strnlen(str, maxlen);
> +     p_rom = ctx->bios;
> +
> +     for (; start <= end; ++start) {
> +             for (str_off = 0; str_off < str_len; ++str_off) {
> +                     if (str[str_off] != *(p_rom + start + str_off))
> +                             break;
> +             }
> +
> +             if (str_off == str_len || str[str_off] == 0)
> +                     return p_rom + start;
> +     }
> +     return NULL;
> +}
> +
> +static void atom_get_vbios_pn(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned short off_to_vbios_str;
> +     unsigned char *vbios_str;
> +     int count;
> +
> +     off_to_vbios_str = 0;
> +     p_rom = ctx->bios;
> +
> +     if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
> +             off_to_vbios_str =
> +                     *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +             vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
> +     } else {
> +             vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
> +     }
> +
> +     if (*vbios_str == 0) {
> +             vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
> +             if (vbios_str == NULL)
> +                     vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
> +     }
> +     if (vbios_str != NULL && *vbios_str == 0)
> +             vbios_str++;
> +
> +     if (vbios_str != NULL) {
> +             count = 0;
> +             while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
> +                    vbios_str[count] <= 'z') {
> +                     ctx->vbios_pn[count] = vbios_str[count];
> +                     count++;
> +             }
> +
> +             ctx->vbios_pn[count] = 0;
> +     }
> +}
> +
> +static void atom_get_vbios_version(struct atom_context *ctx) {
> +     unsigned char *vbios_ver;
> +
> +     /* find anchor ATOMBIOSBK-AMD */
> +     vbios_ver = atom_find_str_in_rom(ctx, BIOS_VERSION_PREFIX, 3, 1024, 64);
> +     if (vbios_ver != NULL) {
> +             /* skip ATOMBIOSBK-AMD VER */
> +             vbios_ver += 18;
> +             memcpy(ctx->vbios_ver_str, vbios_ver, STRLEN_NORMAL);
> +     } else {
> +             ctx->vbios_ver_str[0] = '\0';
> +     }
> +}
> +
>   struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)  {
>        int base;
>        struct atom_context *ctx =
>            kzalloc(sizeof(struct atom_context), GFP_KERNEL);
>        char *str;
> +     struct _ATOM_ROM_HEADER *atom_rom_header;
> +     struct _ATOM_MASTER_DATA_TABLE *master_table;
> +     struct _ATOM_FIRMWARE_INFO *atom_fw_info;
>        u16 idx;
>
>        if (!ctx)
> @@ -1353,6 +1510,23 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>                strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
>        }
>
> +     atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
> +     ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
> +     ctx->sub_ved_id = atom_rom_header->usSubsystemID;
> +     if (atom_rom_header->usMasterDataTableOffset != 0) {
> +             master_table = (struct _ATOM_MASTER_DATA_TABLE *)
> +                             CSTR(atom_rom_header->usMasterDataTableOffset);
> +             if (master_table->ListOfDataTables.FirmwareInfo != 0) {
> +                     atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
> +                                     CSTR(master_table->ListOfDataTables.FirmwareInfo);
> +                     ctx->version = atom_fw_info->ulFirmwareRevision;
> +             }
> +     }
> +
> +     atom_get_vbios_name(ctx);
> +     atom_get_vbios_pn(ctx);
> +     atom_get_vbios_date(ctx);
> +     atom_get_vbios_version(ctx);
>
>        return ctx;
>   }
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h
> b/drivers/gpu/drm/amd/amdgpu/atom.h
> index d279759cab47..6463ce6e756d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.h
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
> @@ -112,6 +112,10 @@ struct drm_device;
>   #define ATOM_IO_SYSIO               2
>   #define ATOM_IO_IIO         0x80
>
> +#define STRLEN_NORMAL                32
> +#define STRLEN_LONG          64
> +#define STRLEN_VERYLONG              254
> +
>   struct card_info {
>        struct drm_device *dev;
>        void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
> @@ -140,6 +144,14 @@ struct atom_context {
>        uint32_t *scratch;
>        int scratch_size_bytes;
>        char vbios_version[20];
> +
> +     uint8_t name[STRLEN_LONG];
> +     uint8_t vbios_pn[STRLEN_LONG];
> +     uint32_t version;
> +     uint8_t vbios_ver_str[STRLEN_NORMAL];
> +     uint8_t date[STRLEN_NORMAL];
> +     uint32_t sub_dev_id;
> +     uint32_t sub_ved_id;
>   };
>
>   extern int amdgpu_atom_debug;
> diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h
> b/drivers/gpu/drm/amd/include/atomfirmware.h
> index 275468e4be60..28deecc2f990 100644
> --- a/drivers/gpu/drm/amd/include/atomfirmware.h
> +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
> @@ -197,6 +197,9 @@ enum atom_dp_vs_preemph_def{
>     DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
>   };
>
> +#define BIOS_ATOM_PREFIX   "ATOMBIOS"
> +#define BIOS_VERSION_PREFIX  "ATOMBIOSBK-AMD"
> +#define BIOS_STRING_LENGTH 43
>
>   /*
>   enum atom_string_def{
> @@ -215,6 +218,8 @@ enum atombios_image_offset{
>     MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
>     OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
>     OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
> +  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
> +  OFFSET_TO_VBIOS_DATE                       = 0x50,
>   };
>
>
> /*********************************************************************
> ******* diff --git a/include/uapi/drm/amdgpu_drm.h
> b/include/uapi/drm/amdgpu_drm.h index 9169df7fadee..e0f98ca9a755
> 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -756,6 +756,8 @@ struct drm_amdgpu_cs_chunk_data {
>        #define AMDGPU_INFO_VBIOS_SIZE          0x1
>        /* Subquery id: Query vbios image */
>        #define AMDGPU_INFO_VBIOS_IMAGE         0x2
> +     /* Subquery id: Query vbios info */
> +     #define AMDGPU_INFO_VBIOS_INFO          0x3
>   /* Query UVD handles */
>   #define AMDGPU_INFO_NUM_HANDLES                     0x1C
>   /* Query sensor related information */ @@ -949,6 +951,20 @@ struct
> drm_amdgpu_info_firmware {
>        __u32 feature;
>   };
>
> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf;
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial;
> +     __u32 dev_id;
> +     __u32 rev_id;
> +     __u32 sub_dev_id;
> +     __u32 sub_ved_id;
> +};
> +
>   #define AMDGPU_VRAM_TYPE_UNKNOWN 0
>   #define AMDGPU_VRAM_TYPE_GDDR1 1
>   #define AMDGPU_VRAM_TYPE_DDR2  2
> --
> 2.17.1


_______________________________________________

amd-gfx mailing list

amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>

https://lists.freedesktop.org/mailman/listinfo/amd-gfx<https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=04%7C01%7CJiaWei.Gu%40amd.com%7Ccd8e7257279a437d9b2208d91ac93b3e%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637570273857847028%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=zhrziSJ55q4VfYYd23yKYoIQdocTAtZ4v%2FyKvU9TJhs%3D&reserved=0>


[-- Attachment #1.2: Type: text/html, Size: 47505 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-05-19 13:09               ` Deucher, Alexander
@ 2021-05-19 13:23                 ` Christian König
  2021-05-20  1:30                   ` Gu, JiaWei (Will)
  0 siblings, 1 reply; 47+ messages in thread
From: Christian König @ 2021-05-19 13:23 UTC (permalink / raw)
  To: Deucher, Alexander, Gu, JiaWei (Will),
	Nieto, David M, Koenig, Christian, amd-gfx, maraeo
  Cc: Deng, Emily


[-- Attachment #1.1: Type: text/plain, Size: 21080 bytes --]

Good point.

If you want to double check the alignment you can use something like 
"pahole drivers/gpu/drm/amd/amdgpu/amdgpu.ko -C drm_amdgpu_info_vbios" 
after building the kernel module.

Regards,
Christian.

Am 19.05.21 um 15:09 schrieb Deucher, Alexander:
>
> [Public]
>
>
> The structure is not 64 bit aligned.  I think you want something like:
>
> > +struct drm_amdgpu_info_vbios {
> > +     __u8 name[64];
> > +     __u8 vbios_pn[64];
> > +     __u32 version;
> > +     __u32 pad;
> > +     __u8 vbios_ver_str[32];
> > +     __u8 date[32];
> > +};
> ------------------------------------------------------------------------
> *From:* Gu, JiaWei (Will) <JiaWei.Gu@amd.com>
> *Sent:* Tuesday, May 18, 2021 1:58 AM
> *To:* Nieto, David M <David.Nieto@amd.com>; Koenig, Christian 
> <Christian.Koenig@amd.com>; amd-gfx@lists.freedesktop.org 
> <amd-gfx@lists.freedesktop.org>; maraeo@gmail.com <maraeo@gmail.com>; 
> Deucher, Alexander <Alexander.Deucher@amd.com>
> *Cc:* Deng, Emily <Emily.Deng@amd.com>
> *Subject:* RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> [Public]
>
>
> Hi all,
>
> Then the struct looks like:
>
> > +struct drm_amdgpu_info_vbios {
> > +     __u8 name[64];
> > +     __u8 vbios_pn[64];
> > +     __u32 version;
> > +     __u8 vbios_ver_str[32];
> > +     __u8 date[32];
> > +};
>
> Sample output:
>
> vbios name : NAVI12 A0 XT D30501 8GB EVAL 1150e/334m HYN/SAM
> vbios pn : 113-D3050100-104
> vbios version : 285409288
> vbios ver_str : 017.003.000.008.016956
> vbios date : 2021/05/03 23:32
>
> Please help double confirm that we’re all fine with it and there’s no 
> need to add & remove anything.
>
> Best regards,
>
> Jiawei
>
> *From:* Nieto, David M <David.Nieto@amd.com>
> *Sent:* Tuesday, May 18, 2021 12:40 PM
> *To:* Gu, JiaWei (Will) <JiaWei.Gu@amd.com>; Koenig, Christian 
> <Christian.Koenig@amd.com>; amd-gfx@lists.freedesktop.org; 
> maraeo@gmail.com; Deucher, Alexander <Alexander.Deucher@amd.com>
> *Cc:* Deng, Emily <Emily.Deng@amd.com>
> *Subject:* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> [Public]
>
> Yes, let's remove that too,
>
> Thanks,
>
> David
>
> ------------------------------------------------------------------------
>
> *From:*Gu, JiaWei (Will) <JiaWei.Gu@amd.com <mailto:JiaWei.Gu@amd.com>>
> *Sent:* Monday, May 17, 2021 8:07 PM
> *To:* Nieto, David M <David.Nieto@amd.com 
> <mailto:David.Nieto@amd.com>>; Koenig, Christian 
> <Christian.Koenig@amd.com <mailto:Christian.Koenig@amd.com>>; 
> amd-gfx@lists.freedesktop.org <mailto:amd-gfx@lists.freedesktop.org> 
> <amd-gfx@lists.freedesktop.org 
> <mailto:amd-gfx@lists.freedesktop.org>>; maraeo@gmail.com 
> <mailto:maraeo@gmail.com> <maraeo@gmail.com 
> <mailto:maraeo@gmail.com>>; Deucher, Alexander 
> <Alexander.Deucher@amd.com <mailto:Alexander.Deucher@amd.com>>
> *Cc:* Deng, Emily <Emily.Deng@amd.com <mailto:Emily.Deng@amd.com>>
> *Subject:* RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> [AMD Official Use Only - Internal Distribution Only]
>
> OK let’s remove serial.
>
> dbdf comes from this:
>
> vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
>
> I think we can remove dbdf as well.
>
> Best regards,
>
> Jiawei
>
> *From:* Nieto, David M <David.Nieto@amd.com <mailto:David.Nieto@amd.com>>
> *Sent:* Tuesday, May 18, 2021 10:45 AM
> *To:* Gu, JiaWei (Will) <JiaWei.Gu@amd.com 
> <mailto:JiaWei.Gu@amd.com>>; Koenig, Christian 
> <Christian.Koenig@amd.com <mailto:Christian.Koenig@amd.com>>; 
> amd-gfx@lists.freedesktop.org <mailto:amd-gfx@lists.freedesktop.org>; 
> maraeo@gmail.com <mailto:maraeo@gmail.com>; Deucher, Alexander 
> <Alexander.Deucher@amd.com <mailto:Alexander.Deucher@amd.com>>
> *Cc:* Deng, Emily <Emily.Deng@amd.com <mailto:Emily.Deng@amd.com>>
> *Subject:* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> [AMD Official Use Only - Internal Distribution Only]
>
> The serial number is ASIC information, not VBIOS information, and it 
> is still available as a sysfs node... I don't think we should put it 
> there.
>
> Not sure what dbdf stands for.
>
> ------------------------------------------------------------------------
>
> *From:*Gu, JiaWei (Will) <JiaWei.Gu@amd.com <mailto:JiaWei.Gu@amd.com>>
> *Sent:* Monday, May 17, 2021 7:11 PM
> *To:* Koenig, Christian <Christian.Koenig@amd.com 
> <mailto:Christian.Koenig@amd.com>>; amd-gfx@lists.freedesktop.org 
> <mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org 
> <mailto:amd-gfx@lists.freedesktop.org>>; Nieto, David M 
> <David.Nieto@amd.com <mailto:David.Nieto@amd.com>>; maraeo@gmail.com 
> <mailto:maraeo@gmail.com> <maraeo@gmail.com 
> <mailto:maraeo@gmail.com>>; Deucher, Alexander 
> <Alexander.Deucher@amd.com <mailto:Alexander.Deucher@amd.com>>
> *Cc:* Deng, Emily <Emily.Deng@amd.com <mailto:Emily.Deng@amd.com>>
> *Subject:* RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> [AMD Official Use Only - Internal Distribution Only]
>
> So I guess the dbdf is also needed to be removed?
> And how about serial?
>
> > +struct drm_amdgpu_info_vbios {
> > +     __u8 name[64];
> > +     __u32 dbdf; // do we need this?
> > +     __u8 vbios_pn[64];
> > +     __u32 version;
> > +     __u8 vbios_ver_str[32];
> > +     __u8 date[32];
> > +     __u64 serial; // do we need this?
> > +};
>
> Best regards,
> Jiawei
>
> -----Original Message-----
> From: Koenig, Christian <Christian.Koenig@amd.com 
> <mailto:Christian.Koenig@amd.com>>
> Sent: Monday, May 17, 2021 8:26 PM
> To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com <mailto:JiaWei.Gu@amd.com>>; 
> amd-gfx@lists.freedesktop.org <mailto:amd-gfx@lists.freedesktop.org>; 
> Nieto, David M <David.Nieto@amd.com <mailto:David.Nieto@amd.com>>; 
> maraeo@gmail.com <mailto:maraeo@gmail.com>; Deucher, Alexander 
> <Alexander.Deucher@amd.com <mailto:Alexander.Deucher@amd.com>>
> Cc: Deng, Emily <Emily.Deng@amd.com <mailto:Emily.Deng@amd.com>>
> Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> I'm not very familiar with the technical background why we have the 
> fields here once more.
>
> But of hand we should at least remove everything which is also 
> available from the PCI information.
>
> E.g. dev_id, rev_id, sub_dev_id, sub_ved_id.
>
> Regards,
> Christian.
>
> Am 17.05.21 um 14:17 schrieb Gu, JiaWei (Will):
> > [AMD Official Use Only - Internal Distribution Only]
> >
> > Hi all,
> >
> > Thanks Christian's suggestion.
> > I reverted the previous patches and squash them into this single one.
> >
> > As this patch shows, the current uapi change looks like this:
> >
> > +struct drm_amdgpu_info_vbios {
> > +     __u8 name[64];
> > +     __u32 dbdf;
> > +     __u8 vbios_pn[64];
> > +     __u32 version;
> > +     __u8 vbios_ver_str[32];
> > +     __u8 date[32];
> > +     __u64 serial;
> > +     __u32 dev_id;
> > +     __u32 rev_id;
> > +     __u32 sub_dev_id;
> > +     __u32 sub_ved_id;
> > +};
> >
> > As we know there's some redundant info in this struct.
> > Please feel free to give any comments or suggestion about what it 
> should & shouldn't include.
> >
> > Best regards,
> > Jiawei
> >
> > -----Original Message-----
> > From: Jiawei Gu <Jiawei.Gu@amd.com <mailto:Jiawei.Gu@amd.com>>
> > Sent: Monday, May 17, 2021 8:08 PM
> > To: amd-gfx@lists.freedesktop.org 
> <mailto:amd-gfx@lists.freedesktop.org>; Koenig, Christian
> > <Christian.Koenig@amd.com <mailto:Christian.Koenig@amd.com>>; Nieto, 
> David M <David.Nieto@amd.com <mailto:David.Nieto@amd.com>>;
> > maraeo@gmail.com <mailto:maraeo@gmail.com>; Deucher, Alexander 
> <Alexander.Deucher@amd.com <mailto:Alexander.Deucher@amd.com>>
> > Cc: Deng, Emily <Emily.Deng@amd.com <mailto:Emily.Deng@amd.com>>; 
> Gu, JiaWei (Will)
> > <JiaWei.Gu@amd.com <mailto:JiaWei.Gu@amd.com>>
> > Subject: [PATCH] drm/amdgpu: Add vbios info ioctl interface
> >
> > Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.
> >
> > Provides a way for the user application to get the VBIOS information 
> without having to parse the binary.
> > It is useful for the user to be able to display in a simple way the 
> VBIOS version in their system if they happen to encounter an issue.
> >
> > V2:
> > Use numeric serial.
> > Parse and expose vbios version string.
> >
> > Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com <mailto:Jiawei.Gu@amd.com>>
> > Acked-by: Christian König <christian.koenig@amd.com 
> <mailto:christian.koenig@amd.com>>
> > ---
> > drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c |  21 +++
> > drivers/gpu/drm/amd/amdgpu/atom.c          | 174 +++++++++++++++++++++
> > drivers/gpu/drm/amd/amdgpu/atom.h |  12 ++
> > drivers/gpu/drm/amd/include/atomfirmware.h |   5 +
> > include/uapi/drm/amdgpu_drm.h |  16 ++
> >   5 files changed, 228 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> > b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> > index 8d12e474745a..30e4fed3de22 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> > @@ -861,6 +861,27 @@ int amdgpu_info_ioctl(struct drm_device *dev, 
> void *data, struct drm_file *filp)
> >                                            min((size_t)size, 
> (size_t)(bios_size - bios_offset)))
> > ? -EFAULT : 0;
> >                }
> > +             case AMDGPU_INFO_VBIOS_INFO: {
> > +                     struct drm_amdgpu_info_vbios vbios_info = {};
> > +                     struct atom_context *atom_context;
> > +
> > +                     atom_context = adev->mode_info.atom_context;
> > + memcpy(vbios_info.name, atom_context->name, 
> sizeof(atom_context->name));
> > +                     vbios_info.dbdf = 
> PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
> > + memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, 
> sizeof(atom_context->vbios_pn));
> > + vbios_info.version = atom_context->version;
> > + memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str,
> > + sizeof(atom_context->vbios_ver_str));
> > + memcpy(vbios_info.date, atom_context->date, 
> sizeof(atom_context->date));
> > +                     vbios_info.serial = adev->unique_id;
> > +                     vbios_info.dev_id = adev->pdev->device;
> > +                     vbios_info.rev_id = adev->pdev->revision;
> > + vbios_info.sub_dev_id = atom_context->sub_dev_id;
> > + vbios_info.sub_ved_id = atom_context->sub_ved_id;
> > +
> > +                     return copy_to_user(out, &vbios_info,
> > + min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
> > +             }
> >                default:
> > DRM_DEBUG_KMS("Invalid request %d\n",
> > info->vbios_info.type);
> > diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c
> > b/drivers/gpu/drm/amd/amdgpu/atom.c
> > index 3dcb8b32f48b..542b2c2414e4 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/atom.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
> > @@ -31,6 +31,7 @@
> >
> >   #define ATOM_DEBUG
> >
> > +#include "atomfirmware.h"
> >   #include "atom.h"
> >   #include "atom-names.h"
> >   #include "atom-bits.h"
> > @@ -1299,12 +1300,168 @@ static void atom_index_iio(struct 
> atom_context *ctx, int base)
> >        }
> >   }
> >
> > +static void atom_get_vbios_name(struct atom_context *ctx) {
> > +     unsigned char *p_rom;
> > +     unsigned char str_num;
> > +     unsigned short off_to_vbios_str;
> > +     unsigned char *c_ptr;
> > +     int name_size;
> > +     int i;
> > +
> > +     const char *na = "--N/A--";
> > +     char *back;
> > +
> > +     p_rom = ctx->bios;
> > +
> > +     str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
> > +     if (str_num != 0) {
> > +             off_to_vbios_str =
> > +                     *(unsigned short *)(p_rom + 
> OFFSET_TO_GET_ATOMBIOS_STRING_START);
> > +
> > +             c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
> > +     } else {
> > +             /* do not know where to find name */
> > +             memcpy(ctx->name, na, 7);
> > +             ctx->name[7] = 0;
> > +             return;
> > +     }
> > +
> > +     /*
> > +      * skip the atombios strings, usually 4
> > +      * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
> > +      */
> > +     for (i = 0; i < str_num; i++) {
> > +             while (*c_ptr != 0)
> > +                     c_ptr++;
> > +             c_ptr++;
> > +     }
> > +
> > +     /* skip the following 2 chars: 0x0D 0x0A */
> > +     c_ptr += 2;
> > +
> > +     name_size = strnlen(c_ptr, STRLEN_LONG - 1);
> > +     memcpy(ctx->name, c_ptr, name_size);
> > +     back = ctx->name + name_size;
> > +     while ((*--back) == ' ')
> > +             ;
> > +     *(back + 1) = '\0';
> > +}
> > +
> > +static void atom_get_vbios_date(struct atom_context *ctx) {
> > +     unsigned char *p_rom;
> > +     unsigned char *date_in_rom;
> > +
> > +     p_rom = ctx->bios;
> > +
> > +     date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
> > +
> > +     ctx->date[0] = '2';
> > +     ctx->date[1] = '0';
> > +     ctx->date[2] = date_in_rom[6];
> > +     ctx->date[3] = date_in_rom[7];
> > +     ctx->date[4] = '/';
> > +     ctx->date[5] = date_in_rom[0];
> > +     ctx->date[6] = date_in_rom[1];
> > +     ctx->date[7] = '/';
> > +     ctx->date[8] = date_in_rom[3];
> > +     ctx->date[9] = date_in_rom[4];
> > +     ctx->date[10] = ' ';
> > +     ctx->date[11] = date_in_rom[9];
> > +     ctx->date[12] = date_in_rom[10];
> > +     ctx->date[13] = date_in_rom[11];
> > +     ctx->date[14] = date_in_rom[12];
> > +     ctx->date[15] = date_in_rom[13];
> > +     ctx->date[16] = '\0';
> > +}
> > +
> > +static unsigned char *atom_find_str_in_rom(struct atom_context 
> *ctx, char *str, int start,
> > +                                        int end, int maxlen)
> > +{
> > +     unsigned long str_off;
> > +     unsigned char *p_rom;
> > +     unsigned short str_len;
> > +
> > +     str_off = 0;
> > +     str_len = strnlen(str, maxlen);
> > +     p_rom = ctx->bios;
> > +
> > +     for (; start <= end; ++start) {
> > +             for (str_off = 0; str_off < str_len; ++str_off) {
> > +                     if (str[str_off] != *(p_rom + start + str_off))
> > +                             break;
> > +             }
> > +
> > +             if (str_off == str_len || str[str_off] == 0)
> > +                     return p_rom + start;
> > +     }
> > +     return NULL;
> > +}
> > +
> > +static void atom_get_vbios_pn(struct atom_context *ctx) {
> > +     unsigned char *p_rom;
> > +     unsigned short off_to_vbios_str;
> > +     unsigned char *vbios_str;
> > +     int count;
> > +
> > +     off_to_vbios_str = 0;
> > +     p_rom = ctx->bios;
> > +
> > +     if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
> > +             off_to_vbios_str =
> > +                     *(unsigned short *)(p_rom + 
> OFFSET_TO_GET_ATOMBIOS_STRING_START);
> > +
> > +             vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
> > +     } else {
> > +             vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
> > +     }
> > +
> > +     if (*vbios_str == 0) {
> > +             vbios_str = atom_find_str_in_rom(ctx, 
> BIOS_ATOM_PREFIX, 3, 1024, 64);
> > +             if (vbios_str == NULL)
> > +                     vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
> > +     }
> > +     if (vbios_str != NULL && *vbios_str == 0)
> > +             vbios_str++;
> > +
> > +     if (vbios_str != NULL) {
> > +             count = 0;
> > +             while ((count < BIOS_STRING_LENGTH) && 
> vbios_str[count] >= ' ' &&
> > +                    vbios_str[count] <= 'z') {
> > + ctx->vbios_pn[count] = vbios_str[count];
> > +                     count++;
> > +             }
> > +
> > +             ctx->vbios_pn[count] = 0;
> > +     }
> > +}
> > +
> > +static void atom_get_vbios_version(struct atom_context *ctx) {
> > +     unsigned char *vbios_ver;
> > +
> > +     /* find anchor ATOMBIOSBK-AMD */
> > +     vbios_ver = atom_find_str_in_rom(ctx, BIOS_VERSION_PREFIX, 3, 
> 1024, 64);
> > +     if (vbios_ver != NULL) {
> > +             /* skip ATOMBIOSBK-AMD VER */
> > +             vbios_ver += 18;
> > + memcpy(ctx->vbios_ver_str, vbios_ver, STRLEN_NORMAL);
> > +     } else {
> > +             ctx->vbios_ver_str[0] = '\0';
> > +     }
> > +}
> > +
> >   struct atom_context *amdgpu_atom_parse(struct card_info *card, 
> void *bios)  {
> >        int base;
> >        struct atom_context *ctx =
> >            kzalloc(sizeof(struct atom_context), GFP_KERNEL);
> >        char *str;
> > +     struct _ATOM_ROM_HEADER *atom_rom_header;
> > +     struct _ATOM_MASTER_DATA_TABLE *master_table;
> > +     struct _ATOM_FIRMWARE_INFO *atom_fw_info;
> >        u16 idx;
> >
> >        if (!ctx)
> > @@ -1353,6 +1510,23 @@ struct atom_context *amdgpu_atom_parse(struct 
> card_info *card, void *bios)
> > strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
> >        }
> >
> > +     atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
> > +     ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
> > +     ctx->sub_ved_id = atom_rom_header->usSubsystemID;
> > +     if (atom_rom_header->usMasterDataTableOffset != 0) {
> > +             master_table = (struct _ATOM_MASTER_DATA_TABLE *)
> > + CSTR(atom_rom_header->usMasterDataTableOffset);
> > +             if (master_table->ListOfDataTables.FirmwareInfo != 0) {
> > +                     atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
> > + CSTR(master_table->ListOfDataTables.FirmwareInfo);
> > +                     ctx->version = atom_fw_info->ulFirmwareRevision;
> > +             }
> > +     }
> > +
> > +     atom_get_vbios_name(ctx);
> > +     atom_get_vbios_pn(ctx);
> > +     atom_get_vbios_date(ctx);
> > +     atom_get_vbios_version(ctx);
> >
> >        return ctx;
> >   }
> > diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h
> > b/drivers/gpu/drm/amd/amdgpu/atom.h
> > index d279759cab47..6463ce6e756d 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/atom.h
> > +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
> > @@ -112,6 +112,10 @@ struct drm_device;
> >   #define ATOM_IO_SYSIO               2
> >   #define ATOM_IO_IIO         0x80
> >
> > +#define STRLEN_NORMAL 32
> > +#define STRLEN_LONG          64
> > +#define STRLEN_VERYLONG 254
> > +
> >   struct card_info {
> >        struct drm_device *dev;
> >        void (* reg_write)(struct card_info *, uint32_t, uint32_t);   
> /* filled by driver */
> > @@ -140,6 +144,14 @@ struct atom_context {
> >        uint32_t *scratch;
> >        int scratch_size_bytes;
> >        char vbios_version[20];
> > +
> > +     uint8_t name[STRLEN_LONG];
> > +     uint8_t vbios_pn[STRLEN_LONG];
> > +     uint32_t version;
> > +     uint8_t vbios_ver_str[STRLEN_NORMAL];
> > +     uint8_t date[STRLEN_NORMAL];
> > +     uint32_t sub_dev_id;
> > +     uint32_t sub_ved_id;
> >   };
> >
> >   extern int amdgpu_atom_debug;
> > diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h
> > b/drivers/gpu/drm/amd/include/atomfirmware.h
> > index 275468e4be60..28deecc2f990 100644
> > --- a/drivers/gpu/drm/amd/include/atomfirmware.h
> > +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
> > @@ -197,6 +197,9 @@ enum atom_dp_vs_preemph_def{
> >     DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
> >   };
> >
> > +#define BIOS_ATOM_PREFIX   "ATOMBIOS"
> > +#define BIOS_VERSION_PREFIX "ATOMBIOSBK-AMD"
> > +#define BIOS_STRING_LENGTH 43
> >
> >   /*
> >   enum atom_string_def{
> > @@ -215,6 +218,8 @@ enum atombios_image_offset{
> > MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the 
> terminator 0x0!*/
> > OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
> > OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
> > + OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
> > + OFFSET_TO_VBIOS_DATE                       = 0x50,
> >   };
> >
> >
> > /*********************************************************************
> > ******* diff --git a/include/uapi/drm/amdgpu_drm.h
> > b/include/uapi/drm/amdgpu_drm.h index 9169df7fadee..e0f98ca9a755
> > 100644
> > --- a/include/uapi/drm/amdgpu_drm.h
> > +++ b/include/uapi/drm/amdgpu_drm.h
> > @@ -756,6 +756,8 @@ struct drm_amdgpu_cs_chunk_data {
> >        #define AMDGPU_INFO_VBIOS_SIZE          0x1
> >        /* Subquery id: Query vbios image */
> >        #define AMDGPU_INFO_VBIOS_IMAGE         0x2
> > +     /* Subquery id: Query vbios info */
> > +     #define AMDGPU_INFO_VBIOS_INFO          0x3
> >   /* Query UVD handles */
> >   #define AMDGPU_INFO_NUM_HANDLES 0x1C
> >   /* Query sensor related information */ @@ -949,6 +951,20 @@ struct
> > drm_amdgpu_info_firmware {
> >        __u32 feature;
> >   };
> >
> > +struct drm_amdgpu_info_vbios {
> > +     __u8 name[64];
> > +     __u32 dbdf;
> > +     __u8 vbios_pn[64];
> > +     __u32 version;
> > +     __u8 vbios_ver_str[32];
> > +     __u8 date[32];
> > +     __u64 serial;
> > +     __u32 dev_id;
> > +     __u32 rev_id;
> > +     __u32 sub_dev_id;
> > +     __u32 sub_ved_id;
> > +};
> > +
> >   #define AMDGPU_VRAM_TYPE_UNKNOWN 0
> >   #define AMDGPU_VRAM_TYPE_GDDR1 1
> >   #define AMDGPU_VRAM_TYPE_DDR2  2
> > --
> > 2.17.1
>
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[-- Attachment #1.2: Type: text/html, Size: 56333 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-05-18  5:58             ` Gu, JiaWei (Will)
  2021-05-18  7:23               ` Nieto, David M
  2021-05-18 10:50               ` Lazar, Lijo
@ 2021-05-19 13:09               ` Deucher, Alexander
  2021-05-19 13:23                 ` Christian König
  2 siblings, 1 reply; 47+ messages in thread
From: Deucher, Alexander @ 2021-05-19 13:09 UTC (permalink / raw)
  To: Gu, JiaWei (Will), Nieto, David M, Koenig, Christian, amd-gfx, maraeo
  Cc: Deng, Emily


[-- Attachment #1.1: Type: text/plain, Size: 20400 bytes --]

[Public]

The structure is not 64 bit aligned.  I think you want something like:

> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u32 pad;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +};
________________________________
From: Gu, JiaWei (Will) <JiaWei.Gu@amd.com>
Sent: Tuesday, May 18, 2021 1:58 AM
To: Nieto, David M <David.Nieto@amd.com>; Koenig, Christian <Christian.Koenig@amd.com>; amd-gfx@lists.freedesktop.org <amd-gfx@lists.freedesktop.org>; maraeo@gmail.com <maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com>
Cc: Deng, Emily <Emily.Deng@amd.com>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface


[Public]


Hi all,



Then the struct looks like:



> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +};



Sample output:



vbios name : NAVI12 A0 XT D30501 8GB EVAL 1150e/334m HYN/SAM
vbios pn : 113-D3050100-104
vbios version : 285409288
vbios ver_str : 017.003.000.008.016956
vbios date : 2021/05/03 23:32


Please help double confirm that we’re all fine with it and there’s no need to add & remove anything.



Best regards,

Jiawei



From: Nieto, David M <David.Nieto@amd.com>
Sent: Tuesday, May 18, 2021 12:40 PM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com>; Koenig, Christian <Christian.Koenig@amd.com>; amd-gfx@lists.freedesktop.org; maraeo@gmail.com; Deucher, Alexander <Alexander.Deucher@amd.com>
Cc: Deng, Emily <Emily.Deng@amd.com>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface



[Public]



Yes, let's remove that too,



Thanks,



David

________________________________

From: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>
Sent: Monday, May 17, 2021 8:07 PM
To: Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>>; maraeo@gmail.com<mailto:maraeo@gmail.com> <maraeo@gmail.com<mailto:maraeo@gmail.com>>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface



[AMD Official Use Only - Internal Distribution Only]



OK let’s remove serial.



dbdf comes from this:

vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);



I think we can remove dbdf as well.



Best regards,

Jiawei



From: Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>
Sent: Tuesday, May 18, 2021 10:45 AM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>; Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>; maraeo@gmail.com<mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface



[AMD Official Use Only - Internal Distribution Only]



The serial number is ASIC information, not VBIOS information, and it is still available as a sysfs node... I don't think we should put it there.



Not sure what dbdf stands for.

________________________________

From: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>
Sent: Monday, May 17, 2021 7:11 PM
To: Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>>; Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; maraeo@gmail.com<mailto:maraeo@gmail.com> <maraeo@gmail.com<mailto:maraeo@gmail.com>>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface



[AMD Official Use Only - Internal Distribution Only]

So I guess the dbdf is also needed to be removed?
And how about serial?

> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf; // do we need this?
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial; // do we need this?
> +};

Best regards,
Jiawei

-----Original Message-----
From: Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>
Sent: Monday, May 17, 2021 8:26 PM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>; Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; maraeo@gmail.com<mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

I'm not very familiar with the technical background why we have the fields here once more.

But of hand we should at least remove everything which is also available from the PCI information.

E.g. dev_id, rev_id, sub_dev_id, sub_ved_id.

Regards,
Christian.

Am 17.05.21 um 14:17 schrieb Gu, JiaWei (Will):
> [AMD Official Use Only - Internal Distribution Only]
>
> Hi all,
>
> Thanks Christian's suggestion.
> I reverted the previous patches and squash them into this single one.
>
> As this patch shows, the current uapi change looks like this:
>
> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf;
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial;
> +     __u32 dev_id;
> +     __u32 rev_id;
> +     __u32 sub_dev_id;
> +     __u32 sub_ved_id;
> +};
>
> As we know there's some redundant info in this struct.
> Please feel free to give any comments or suggestion about what it should & shouldn't include.
>
> Best regards,
> Jiawei
>
> -----Original Message-----
> From: Jiawei Gu <Jiawei.Gu@amd.com<mailto:Jiawei.Gu@amd.com>>
> Sent: Monday, May 17, 2021 8:08 PM
> To: amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>; Koenig, Christian
> <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>;
> maraeo@gmail.com<mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
> Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>; Gu, JiaWei (Will)
> <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>
> Subject: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.
>
> Provides a way for the user application to get the VBIOS information without having to parse the binary.
> It is useful for the user to be able to display in a simple way the VBIOS version in their system if they happen to encounter an issue.
>
> V2:
> Use numeric serial.
> Parse and expose vbios version string.
>
> Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com<mailto:Jiawei.Gu@amd.com>>
> Acked-by: Christian König <christian.koenig@amd.com<mailto:christian.koenig@amd.com>>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  21 +++
>   drivers/gpu/drm/amd/amdgpu/atom.c          | 174 +++++++++++++++++++++
>   drivers/gpu/drm/amd/amdgpu/atom.h          |  12 ++
>   drivers/gpu/drm/amd/include/atomfirmware.h |   5 +
>   include/uapi/drm/amdgpu_drm.h              |  16 ++
>   5 files changed, 228 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index 8d12e474745a..30e4fed3de22 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -861,6 +861,27 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
>                                            min((size_t)size, (size_t)(bios_size - bios_offset)))
>                                        ? -EFAULT : 0;
>                }
> +             case AMDGPU_INFO_VBIOS_INFO: {
> +                     struct drm_amdgpu_info_vbios vbios_info = {};
> +                     struct atom_context *atom_context;
> +
> +                     atom_context = adev->mode_info.atom_context;
> +                     memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
> +                     vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
> +                     memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
> +                     vbios_info.version = atom_context->version;
> +                     memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str,
> +                                             sizeof(atom_context->vbios_ver_str));
> +                     memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
> +                     vbios_info.serial = adev->unique_id;
> +                     vbios_info.dev_id = adev->pdev->device;
> +                     vbios_info.rev_id = adev->pdev->revision;
> +                     vbios_info.sub_dev_id = atom_context->sub_dev_id;
> +                     vbios_info.sub_ved_id = atom_context->sub_ved_id;
> +
> +                     return copy_to_user(out, &vbios_info,
> +                                             min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
> +             }
>                default:
>                        DRM_DEBUG_KMS("Invalid request %d\n",
>                                        info->vbios_info.type);
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c
> b/drivers/gpu/drm/amd/amdgpu/atom.c
> index 3dcb8b32f48b..542b2c2414e4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.c
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
> @@ -31,6 +31,7 @@
>
>   #define ATOM_DEBUG
>
> +#include "atomfirmware.h"
>   #include "atom.h"
>   #include "atom-names.h"
>   #include "atom-bits.h"
> @@ -1299,12 +1300,168 @@ static void atom_index_iio(struct atom_context *ctx, int base)
>        }
>   }
>
> +static void atom_get_vbios_name(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned char str_num;
> +     unsigned short off_to_vbios_str;
> +     unsigned char *c_ptr;
> +     int name_size;
> +     int i;
> +
> +     const char *na = "--N/A--";
> +     char *back;
> +
> +     p_rom = ctx->bios;
> +
> +     str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
> +     if (str_num != 0) {
> +             off_to_vbios_str =
> +                     *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +             c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
> +     } else {
> +             /* do not know where to find name */
> +             memcpy(ctx->name, na, 7);
> +             ctx->name[7] = 0;
> +             return;
> +     }
> +
> +     /*
> +      * skip the atombios strings, usually 4
> +      * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
> +      */
> +     for (i = 0; i < str_num; i++) {
> +             while (*c_ptr != 0)
> +                     c_ptr++;
> +             c_ptr++;
> +     }
> +
> +     /* skip the following 2 chars: 0x0D 0x0A */
> +     c_ptr += 2;
> +
> +     name_size = strnlen(c_ptr, STRLEN_LONG - 1);
> +     memcpy(ctx->name, c_ptr, name_size);
> +     back = ctx->name + name_size;
> +     while ((*--back) == ' ')
> +             ;
> +     *(back + 1) = '\0';
> +}
> +
> +static void atom_get_vbios_date(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned char *date_in_rom;
> +
> +     p_rom = ctx->bios;
> +
> +     date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
> +
> +     ctx->date[0] = '2';
> +     ctx->date[1] = '0';
> +     ctx->date[2] = date_in_rom[6];
> +     ctx->date[3] = date_in_rom[7];
> +     ctx->date[4] = '/';
> +     ctx->date[5] = date_in_rom[0];
> +     ctx->date[6] = date_in_rom[1];
> +     ctx->date[7] = '/';
> +     ctx->date[8] = date_in_rom[3];
> +     ctx->date[9] = date_in_rom[4];
> +     ctx->date[10] = ' ';
> +     ctx->date[11] = date_in_rom[9];
> +     ctx->date[12] = date_in_rom[10];
> +     ctx->date[13] = date_in_rom[11];
> +     ctx->date[14] = date_in_rom[12];
> +     ctx->date[15] = date_in_rom[13];
> +     ctx->date[16] = '\0';
> +}
> +
> +static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
> +                                        int end, int maxlen)
> +{
> +     unsigned long str_off;
> +     unsigned char *p_rom;
> +     unsigned short str_len;
> +
> +     str_off = 0;
> +     str_len = strnlen(str, maxlen);
> +     p_rom = ctx->bios;
> +
> +     for (; start <= end; ++start) {
> +             for (str_off = 0; str_off < str_len; ++str_off) {
> +                     if (str[str_off] != *(p_rom + start + str_off))
> +                             break;
> +             }
> +
> +             if (str_off == str_len || str[str_off] == 0)
> +                     return p_rom + start;
> +     }
> +     return NULL;
> +}
> +
> +static void atom_get_vbios_pn(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned short off_to_vbios_str;
> +     unsigned char *vbios_str;
> +     int count;
> +
> +     off_to_vbios_str = 0;
> +     p_rom = ctx->bios;
> +
> +     if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
> +             off_to_vbios_str =
> +                     *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +             vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
> +     } else {
> +             vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
> +     }
> +
> +     if (*vbios_str == 0) {
> +             vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
> +             if (vbios_str == NULL)
> +                     vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
> +     }
> +     if (vbios_str != NULL && *vbios_str == 0)
> +             vbios_str++;
> +
> +     if (vbios_str != NULL) {
> +             count = 0;
> +             while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
> +                    vbios_str[count] <= 'z') {
> +                     ctx->vbios_pn[count] = vbios_str[count];
> +                     count++;
> +             }
> +
> +             ctx->vbios_pn[count] = 0;
> +     }
> +}
> +
> +static void atom_get_vbios_version(struct atom_context *ctx) {
> +     unsigned char *vbios_ver;
> +
> +     /* find anchor ATOMBIOSBK-AMD */
> +     vbios_ver = atom_find_str_in_rom(ctx, BIOS_VERSION_PREFIX, 3, 1024, 64);
> +     if (vbios_ver != NULL) {
> +             /* skip ATOMBIOSBK-AMD VER */
> +             vbios_ver += 18;
> +             memcpy(ctx->vbios_ver_str, vbios_ver, STRLEN_NORMAL);
> +     } else {
> +             ctx->vbios_ver_str[0] = '\0';
> +     }
> +}
> +
>   struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)  {
>        int base;
>        struct atom_context *ctx =
>            kzalloc(sizeof(struct atom_context), GFP_KERNEL);
>        char *str;
> +     struct _ATOM_ROM_HEADER *atom_rom_header;
> +     struct _ATOM_MASTER_DATA_TABLE *master_table;
> +     struct _ATOM_FIRMWARE_INFO *atom_fw_info;
>        u16 idx;
>
>        if (!ctx)
> @@ -1353,6 +1510,23 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>                strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
>        }
>
> +     atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
> +     ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
> +     ctx->sub_ved_id = atom_rom_header->usSubsystemID;
> +     if (atom_rom_header->usMasterDataTableOffset != 0) {
> +             master_table = (struct _ATOM_MASTER_DATA_TABLE *)
> +                             CSTR(atom_rom_header->usMasterDataTableOffset);
> +             if (master_table->ListOfDataTables.FirmwareInfo != 0) {
> +                     atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
> +                                     CSTR(master_table->ListOfDataTables.FirmwareInfo);
> +                     ctx->version = atom_fw_info->ulFirmwareRevision;
> +             }
> +     }
> +
> +     atom_get_vbios_name(ctx);
> +     atom_get_vbios_pn(ctx);
> +     atom_get_vbios_date(ctx);
> +     atom_get_vbios_version(ctx);
>
>        return ctx;
>   }
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h
> b/drivers/gpu/drm/amd/amdgpu/atom.h
> index d279759cab47..6463ce6e756d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.h
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
> @@ -112,6 +112,10 @@ struct drm_device;
>   #define ATOM_IO_SYSIO               2
>   #define ATOM_IO_IIO         0x80
>
> +#define STRLEN_NORMAL                32
> +#define STRLEN_LONG          64
> +#define STRLEN_VERYLONG              254
> +
>   struct card_info {
>        struct drm_device *dev;
>        void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
> @@ -140,6 +144,14 @@ struct atom_context {
>        uint32_t *scratch;
>        int scratch_size_bytes;
>        char vbios_version[20];
> +
> +     uint8_t name[STRLEN_LONG];
> +     uint8_t vbios_pn[STRLEN_LONG];
> +     uint32_t version;
> +     uint8_t vbios_ver_str[STRLEN_NORMAL];
> +     uint8_t date[STRLEN_NORMAL];
> +     uint32_t sub_dev_id;
> +     uint32_t sub_ved_id;
>   };
>
>   extern int amdgpu_atom_debug;
> diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h
> b/drivers/gpu/drm/amd/include/atomfirmware.h
> index 275468e4be60..28deecc2f990 100644
> --- a/drivers/gpu/drm/amd/include/atomfirmware.h
> +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
> @@ -197,6 +197,9 @@ enum atom_dp_vs_preemph_def{
>     DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
>   };
>
> +#define BIOS_ATOM_PREFIX   "ATOMBIOS"
> +#define BIOS_VERSION_PREFIX  "ATOMBIOSBK-AMD"
> +#define BIOS_STRING_LENGTH 43
>
>   /*
>   enum atom_string_def{
> @@ -215,6 +218,8 @@ enum atombios_image_offset{
>     MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
>     OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
>     OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
> +  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
> +  OFFSET_TO_VBIOS_DATE                       = 0x50,
>   };
>
>
> /*********************************************************************
> ******* diff --git a/include/uapi/drm/amdgpu_drm.h
> b/include/uapi/drm/amdgpu_drm.h index 9169df7fadee..e0f98ca9a755
> 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -756,6 +756,8 @@ struct drm_amdgpu_cs_chunk_data {
>        #define AMDGPU_INFO_VBIOS_SIZE          0x1
>        /* Subquery id: Query vbios image */
>        #define AMDGPU_INFO_VBIOS_IMAGE         0x2
> +     /* Subquery id: Query vbios info */
> +     #define AMDGPU_INFO_VBIOS_INFO          0x3
>   /* Query UVD handles */
>   #define AMDGPU_INFO_NUM_HANDLES                     0x1C
>   /* Query sensor related information */ @@ -949,6 +951,20 @@ struct
> drm_amdgpu_info_firmware {
>        __u32 feature;
>   };
>
> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf;
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial;
> +     __u32 dev_id;
> +     __u32 rev_id;
> +     __u32 sub_dev_id;
> +     __u32 sub_ved_id;
> +};
> +
>   #define AMDGPU_VRAM_TYPE_UNKNOWN 0
>   #define AMDGPU_VRAM_TYPE_GDDR1 1
>   #define AMDGPU_VRAM_TYPE_DDR2  2
> --
> 2.17.1

[-- Attachment #1.2: Type: text/html, Size: 41639 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-05-18 10:50               ` Lazar, Lijo
@ 2021-05-19  3:17                 ` Nieto, David M
  0 siblings, 0 replies; 47+ messages in thread
From: Nieto, David M @ 2021-05-19  3:17 UTC (permalink / raw)
  To: Lazar, Lijo, Gu, JiaWei (Will),
	Koenig, Christian, amd-gfx, maraeo, Deucher, Alexander
  Cc: Deng, Emily


[-- Attachment #1.1: Type: text/plain, Size: 21070 bytes --]

[Public]

That is correct, it is 0x11030008, that matches the FW information.
________________________________
From: Lazar, Lijo <Lijo.Lazar@amd.com>
Sent: Tuesday, May 18, 2021 3:50 AM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com>; Nieto, David M <David.Nieto@amd.com>; Koenig, Christian <Christian.Koenig@amd.com>; amd-gfx@lists.freedesktop.org <amd-gfx@lists.freedesktop.org>; maraeo@gmail.com <maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com>
Cc: Deng, Emily <Emily.Deng@amd.com>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface


[Public]


Not sure about this one –  vbios version : 285409288



Windows driver reports VBIOS version from atom_firmware_info_v3_1 / firmware_revision.



Thanks,

Lijo



From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Gu, JiaWei (Will)
Sent: Tuesday, May 18, 2021 11:28 AM
To: Nieto, David M <David.Nieto@amd.com>; Koenig, Christian <Christian.Koenig@amd.com>; amd-gfx@lists.freedesktop.org; maraeo@gmail.com; Deucher, Alexander <Alexander.Deucher@amd.com>
Cc: Deng, Emily <Emily.Deng@amd.com>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface



[Public]



[Public]



Hi all,



Then the struct looks like:



> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +};



Sample output:



vbios name : NAVI12 A0 XT D30501 8GB EVAL 1150e/334m HYN/SAM
vbios pn : 113-D3050100-104
vbios version : 285409288
vbios ver_str : 017.003.000.008.016956
vbios date : 2021/05/03 23:32

Please help double confirm that we’re all fine with it and there’s no need to add & remove anything.



Best regards,

Jiawei



From: Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>
Sent: Tuesday, May 18, 2021 12:40 PM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>; Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>; maraeo@gmail.com<mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface



[Public]



Yes, let's remove that too,



Thanks,



David

________________________________

From: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>
Sent: Monday, May 17, 2021 8:07 PM
To: Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>>; maraeo@gmail.com<mailto:maraeo@gmail.com> <maraeo@gmail.com<mailto:maraeo@gmail.com>>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface



[AMD Official Use Only - Internal Distribution Only]



OK let’s remove serial.



dbdf comes from this:

vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);



I think we can remove dbdf as well.



Best regards,

Jiawei



From: Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>
Sent: Tuesday, May 18, 2021 10:45 AM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>; Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>; maraeo@gmail.com<mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface



[AMD Official Use Only - Internal Distribution Only]



The serial number is ASIC information, not VBIOS information, and it is still available as a sysfs node... I don't think we should put it there.



Not sure what dbdf stands for.

________________________________

From: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>
Sent: Monday, May 17, 2021 7:11 PM
To: Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>>; Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; maraeo@gmail.com<mailto:maraeo@gmail.com> <maraeo@gmail.com<mailto:maraeo@gmail.com>>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface



[AMD Official Use Only - Internal Distribution Only]

So I guess the dbdf is also needed to be removed?
And how about serial?

> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf; // do we need this?
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial; // do we need this?
> +};

Best regards,
Jiawei

-----Original Message-----
From: Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>
Sent: Monday, May 17, 2021 8:26 PM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>; Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; maraeo@gmail.com<mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

I'm not very familiar with the technical background why we have the fields here once more.

But of hand we should at least remove everything which is also available from the PCI information.

E.g. dev_id, rev_id, sub_dev_id, sub_ved_id.

Regards,
Christian.

Am 17.05.21 um 14:17 schrieb Gu, JiaWei (Will):
> [AMD Official Use Only - Internal Distribution Only]
>
> Hi all,
>
> Thanks Christian's suggestion.
> I reverted the previous patches and squash them into this single one.
>
> As this patch shows, the current uapi change looks like this:
>
> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf;
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial;
> +     __u32 dev_id;
> +     __u32 rev_id;
> +     __u32 sub_dev_id;
> +     __u32 sub_ved_id;
> +};
>
> As we know there's some redundant info in this struct.
> Please feel free to give any comments or suggestion about what it should & shouldn't include.
>
> Best regards,
> Jiawei
>
> -----Original Message-----
> From: Jiawei Gu <Jiawei.Gu@amd.com<mailto:Jiawei.Gu@amd.com>>
> Sent: Monday, May 17, 2021 8:08 PM
> To: amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>; Koenig, Christian
> <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>;
> maraeo@gmail.com<mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
> Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>; Gu, JiaWei (Will)
> <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>
> Subject: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.
>
> Provides a way for the user application to get the VBIOS information without having to parse the binary.
> It is useful for the user to be able to display in a simple way the VBIOS version in their system if they happen to encounter an issue.
>
> V2:
> Use numeric serial.
> Parse and expose vbios version string.
>
> Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com<mailto:Jiawei.Gu@amd.com>>
> Acked-by: Christian König <christian.koenig@amd.com<mailto:christian.koenig@amd.com>>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  21 +++
>   drivers/gpu/drm/amd/amdgpu/atom.c          | 174 +++++++++++++++++++++
>   drivers/gpu/drm/amd/amdgpu/atom.h          |  12 ++
>   drivers/gpu/drm/amd/include/atomfirmware.h |   5 +
>   include/uapi/drm/amdgpu_drm.h              |  16 ++
>   5 files changed, 228 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index 8d12e474745a..30e4fed3de22 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -861,6 +861,27 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
>                                            min((size_t)size, (size_t)(bios_size - bios_offset)))
>                                        ? -EFAULT : 0;
>                }
> +             case AMDGPU_INFO_VBIOS_INFO: {
> +                     struct drm_amdgpu_info_vbios vbios_info = {};
> +                     struct atom_context *atom_context;
> +
> +                     atom_context = adev->mode_info.atom_context;
> +                     memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
> +                     vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
> +                     memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
> +                     vbios_info.version = atom_context->version;
> +                     memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str,
> +                                             sizeof(atom_context->vbios_ver_str));
> +                     memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
> +                     vbios_info.serial = adev->unique_id;
> +                     vbios_info.dev_id = adev->pdev->device;
> +                     vbios_info.rev_id = adev->pdev->revision;
> +                     vbios_info.sub_dev_id = atom_context->sub_dev_id;
> +                     vbios_info.sub_ved_id = atom_context->sub_ved_id;
> +
> +                     return copy_to_user(out, &vbios_info,
> +                                             min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
> +             }
>                default:
>                        DRM_DEBUG_KMS("Invalid request %d\n",
>                                        info->vbios_info.type);
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c
> b/drivers/gpu/drm/amd/amdgpu/atom.c
> index 3dcb8b32f48b..542b2c2414e4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.c
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
> @@ -31,6 +31,7 @@
>
>   #define ATOM_DEBUG
>
> +#include "atomfirmware.h"
>   #include "atom.h"
>   #include "atom-names.h"
>   #include "atom-bits.h"
> @@ -1299,12 +1300,168 @@ static void atom_index_iio(struct atom_context *ctx, int base)
>        }
>   }
>
> +static void atom_get_vbios_name(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned char str_num;
> +     unsigned short off_to_vbios_str;
> +     unsigned char *c_ptr;
> +     int name_size;
> +     int i;
> +
> +     const char *na = "--N/A--";
> +     char *back;
> +
> +     p_rom = ctx->bios;
> +
> +     str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
> +     if (str_num != 0) {
> +             off_to_vbios_str =
> +                     *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +             c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
> +     } else {
> +             /* do not know where to find name */
> +             memcpy(ctx->name, na, 7);
> +             ctx->name[7] = 0;
> +             return;
> +     }
> +
> +     /*
> +      * skip the atombios strings, usually 4
> +      * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
> +      */
> +     for (i = 0; i < str_num; i++) {
> +             while (*c_ptr != 0)
> +                     c_ptr++;
> +             c_ptr++;
> +     }
> +
> +     /* skip the following 2 chars: 0x0D 0x0A */
> +     c_ptr += 2;
> +
> +     name_size = strnlen(c_ptr, STRLEN_LONG - 1);
> +     memcpy(ctx->name, c_ptr, name_size);
> +     back = ctx->name + name_size;
> +     while ((*--back) == ' ')
> +             ;
> +     *(back + 1) = '\0';
> +}
> +
> +static void atom_get_vbios_date(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned char *date_in_rom;
> +
> +     p_rom = ctx->bios;
> +
> +     date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
> +
> +     ctx->date[0] = '2';
> +     ctx->date[1] = '0';
> +     ctx->date[2] = date_in_rom[6];
> +     ctx->date[3] = date_in_rom[7];
> +     ctx->date[4] = '/';
> +     ctx->date[5] = date_in_rom[0];
> +     ctx->date[6] = date_in_rom[1];
> +     ctx->date[7] = '/';
> +     ctx->date[8] = date_in_rom[3];
> +     ctx->date[9] = date_in_rom[4];
> +     ctx->date[10] = ' ';
> +     ctx->date[11] = date_in_rom[9];
> +     ctx->date[12] = date_in_rom[10];
> +     ctx->date[13] = date_in_rom[11];
> +     ctx->date[14] = date_in_rom[12];
> +     ctx->date[15] = date_in_rom[13];
> +     ctx->date[16] = '\0';
> +}
> +
> +static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
> +                                        int end, int maxlen)
> +{
> +     unsigned long str_off;
> +     unsigned char *p_rom;
> +     unsigned short str_len;
> +
> +     str_off = 0;
> +     str_len = strnlen(str, maxlen);
> +     p_rom = ctx->bios;
> +
> +     for (; start <= end; ++start) {
> +             for (str_off = 0; str_off < str_len; ++str_off) {
> +                     if (str[str_off] != *(p_rom + start + str_off))
> +                             break;
> +             }
> +
> +             if (str_off == str_len || str[str_off] == 0)
> +                     return p_rom + start;
> +     }
> +     return NULL;
> +}
> +
> +static void atom_get_vbios_pn(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned short off_to_vbios_str;
> +     unsigned char *vbios_str;
> +     int count;
> +
> +     off_to_vbios_str = 0;
> +     p_rom = ctx->bios;
> +
> +     if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
> +             off_to_vbios_str =
> +                     *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +             vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
> +     } else {
> +             vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
> +     }
> +
> +     if (*vbios_str == 0) {
> +             vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
> +             if (vbios_str == NULL)
> +                     vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
> +     }
> +     if (vbios_str != NULL && *vbios_str == 0)
> +             vbios_str++;
> +
> +     if (vbios_str != NULL) {
> +             count = 0;
> +             while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
> +                    vbios_str[count] <= 'z') {
> +                     ctx->vbios_pn[count] = vbios_str[count];
> +                     count++;
> +             }
> +
> +             ctx->vbios_pn[count] = 0;
> +     }
> +}
> +
> +static void atom_get_vbios_version(struct atom_context *ctx) {
> +     unsigned char *vbios_ver;
> +
> +     /* find anchor ATOMBIOSBK-AMD */
> +     vbios_ver = atom_find_str_in_rom(ctx, BIOS_VERSION_PREFIX, 3, 1024, 64);
> +     if (vbios_ver != NULL) {
> +             /* skip ATOMBIOSBK-AMD VER */
> +             vbios_ver += 18;
> +             memcpy(ctx->vbios_ver_str, vbios_ver, STRLEN_NORMAL);
> +     } else {
> +             ctx->vbios_ver_str[0] = '\0';
> +     }
> +}
> +
>   struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)  {
>        int base;
>        struct atom_context *ctx =
>            kzalloc(sizeof(struct atom_context), GFP_KERNEL);
>        char *str;
> +     struct _ATOM_ROM_HEADER *atom_rom_header;
> +     struct _ATOM_MASTER_DATA_TABLE *master_table;
> +     struct _ATOM_FIRMWARE_INFO *atom_fw_info;
>        u16 idx;
>
>        if (!ctx)
> @@ -1353,6 +1510,23 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>                strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
>        }
>
> +     atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
> +     ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
> +     ctx->sub_ved_id = atom_rom_header->usSubsystemID;
> +     if (atom_rom_header->usMasterDataTableOffset != 0) {
> +             master_table = (struct _ATOM_MASTER_DATA_TABLE *)
> +                             CSTR(atom_rom_header->usMasterDataTableOffset);
> +             if (master_table->ListOfDataTables.FirmwareInfo != 0) {
> +                     atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
> +                                     CSTR(master_table->ListOfDataTables.FirmwareInfo);
> +                     ctx->version = atom_fw_info->ulFirmwareRevision;
> +             }
> +     }
> +
> +     atom_get_vbios_name(ctx);
> +     atom_get_vbios_pn(ctx);
> +     atom_get_vbios_date(ctx);
> +     atom_get_vbios_version(ctx);
>
>        return ctx;
>   }
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h
> b/drivers/gpu/drm/amd/amdgpu/atom.h
> index d279759cab47..6463ce6e756d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.h
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
> @@ -112,6 +112,10 @@ struct drm_device;
>   #define ATOM_IO_SYSIO               2
>   #define ATOM_IO_IIO         0x80
>
> +#define STRLEN_NORMAL                32
> +#define STRLEN_LONG          64
> +#define STRLEN_VERYLONG              254
> +
>   struct card_info {
>        struct drm_device *dev;
>        void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
> @@ -140,6 +144,14 @@ struct atom_context {
>        uint32_t *scratch;
>        int scratch_size_bytes;
>        char vbios_version[20];
> +
> +     uint8_t name[STRLEN_LONG];
> +     uint8_t vbios_pn[STRLEN_LONG];
> +     uint32_t version;
> +     uint8_t vbios_ver_str[STRLEN_NORMAL];
> +     uint8_t date[STRLEN_NORMAL];
> +     uint32_t sub_dev_id;
> +     uint32_t sub_ved_id;
>   };
>
>   extern int amdgpu_atom_debug;
> diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h
> b/drivers/gpu/drm/amd/include/atomfirmware.h
> index 275468e4be60..28deecc2f990 100644
> --- a/drivers/gpu/drm/amd/include/atomfirmware.h
> +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
> @@ -197,6 +197,9 @@ enum atom_dp_vs_preemph_def{
>     DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
>   };
>
> +#define BIOS_ATOM_PREFIX   "ATOMBIOS"
> +#define BIOS_VERSION_PREFIX  "ATOMBIOSBK-AMD"
> +#define BIOS_STRING_LENGTH 43
>
>   /*
>   enum atom_string_def{
> @@ -215,6 +218,8 @@ enum atombios_image_offset{
>     MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
>     OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
>     OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
> +  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
> +  OFFSET_TO_VBIOS_DATE                       = 0x50,
>   };
>
>
> /*********************************************************************
> ******* diff --git a/include/uapi/drm/amdgpu_drm.h
> b/include/uapi/drm/amdgpu_drm.h index 9169df7fadee..e0f98ca9a755
> 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -756,6 +756,8 @@ struct drm_amdgpu_cs_chunk_data {
>        #define AMDGPU_INFO_VBIOS_SIZE          0x1
>        /* Subquery id: Query vbios image */
>        #define AMDGPU_INFO_VBIOS_IMAGE         0x2
> +     /* Subquery id: Query vbios info */
> +     #define AMDGPU_INFO_VBIOS_INFO          0x3
>   /* Query UVD handles */
>   #define AMDGPU_INFO_NUM_HANDLES                     0x1C
>   /* Query sensor related information */ @@ -949,6 +951,20 @@ struct
> drm_amdgpu_info_firmware {
>        __u32 feature;
>   };
>
> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf;
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial;
> +     __u32 dev_id;
> +     __u32 rev_id;
> +     __u32 sub_dev_id;
> +     __u32 sub_ved_id;
> +};
> +
>   #define AMDGPU_VRAM_TYPE_UNKNOWN 0
>   #define AMDGPU_VRAM_TYPE_GDDR1 1
>   #define AMDGPU_VRAM_TYPE_DDR2  2
> --
> 2.17.1

[-- Attachment #1.2: Type: text/html, Size: 42653 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-05-18  5:58             ` Gu, JiaWei (Will)
  2021-05-18  7:23               ` Nieto, David M
@ 2021-05-18 10:50               ` Lazar, Lijo
  2021-05-19  3:17                 ` Nieto, David M
  2021-05-19 13:09               ` Deucher, Alexander
  2 siblings, 1 reply; 47+ messages in thread
From: Lazar, Lijo @ 2021-05-18 10:50 UTC (permalink / raw)
  To: Gu, JiaWei (Will),
	Nieto, David M, Koenig, Christian, amd-gfx, maraeo, Deucher,
	Alexander
  Cc: Deng, Emily


[-- Attachment #1.1: Type: text/plain, Size: 20424 bytes --]

[Public]

Not sure about this one -  vbios version : 285409288

Windows driver reports VBIOS version from atom_firmware_info_v3_1 / firmware_revision.

Thanks,
Lijo

From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Gu, JiaWei (Will)
Sent: Tuesday, May 18, 2021 11:28 AM
To: Nieto, David M <David.Nieto@amd.com>; Koenig, Christian <Christian.Koenig@amd.com>; amd-gfx@lists.freedesktop.org; maraeo@gmail.com; Deucher, Alexander <Alexander.Deucher@amd.com>
Cc: Deng, Emily <Emily.Deng@amd.com>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface


[Public]


[Public]

Hi all,

Then the struct looks like:

> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +};

Sample output:

vbios name : NAVI12 A0 XT D30501 8GB EVAL 1150e/334m HYN/SAM
vbios pn : 113-D3050100-104
vbios version : 285409288
vbios ver_str : 017.003.000.008.016956
vbios date : 2021/05/03 23:32
Please help double confirm that we're all fine with it and there's no need to add & remove anything.

Best regards,
Jiawei

From: Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>
Sent: Tuesday, May 18, 2021 12:40 PM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>; Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>; maraeo@gmail.com<mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface


[Public]

Yes, let's remove that too,

Thanks,

David
________________________________
From: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>
Sent: Monday, May 17, 2021 8:07 PM
To: Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>>; maraeo@gmail.com<mailto:maraeo@gmail.com> <maraeo@gmail.com<mailto:maraeo@gmail.com>>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface


[AMD Official Use Only - Internal Distribution Only]



OK let's remove serial.



dbdf comes from this:

vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);



I think we can remove dbdf as well.



Best regards,

Jiawei



From: Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>
Sent: Tuesday, May 18, 2021 10:45 AM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>; Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>; maraeo@gmail.com<mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface



[AMD Official Use Only - Internal Distribution Only]



The serial number is ASIC information, not VBIOS information, and it is still available as a sysfs node... I don't think we should put it there.



Not sure what dbdf stands for.

________________________________

From: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>
Sent: Monday, May 17, 2021 7:11 PM
To: Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>>; Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; maraeo@gmail.com<mailto:maraeo@gmail.com> <maraeo@gmail.com<mailto:maraeo@gmail.com>>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface



[AMD Official Use Only - Internal Distribution Only]

So I guess the dbdf is also needed to be removed?
And how about serial?

> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf; // do we need this?
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial; // do we need this?
> +};

Best regards,
Jiawei

-----Original Message-----
From: Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>
Sent: Monday, May 17, 2021 8:26 PM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>; Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; maraeo@gmail.com<mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

I'm not very familiar with the technical background why we have the fields here once more.

But of hand we should at least remove everything which is also available from the PCI information.

E.g. dev_id, rev_id, sub_dev_id, sub_ved_id.

Regards,
Christian.

Am 17.05.21 um 14:17 schrieb Gu, JiaWei (Will):
> [AMD Official Use Only - Internal Distribution Only]
>
> Hi all,
>
> Thanks Christian's suggestion.
> I reverted the previous patches and squash them into this single one.
>
> As this patch shows, the current uapi change looks like this:
>
> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf;
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial;
> +     __u32 dev_id;
> +     __u32 rev_id;
> +     __u32 sub_dev_id;
> +     __u32 sub_ved_id;
> +};
>
> As we know there's some redundant info in this struct.
> Please feel free to give any comments or suggestion about what it should & shouldn't include.
>
> Best regards,
> Jiawei
>
> -----Original Message-----
> From: Jiawei Gu <Jiawei.Gu@amd.com<mailto:Jiawei.Gu@amd.com>>
> Sent: Monday, May 17, 2021 8:08 PM
> To: amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>; Koenig, Christian
> <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>;
> maraeo@gmail.com<mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
> Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>; Gu, JiaWei (Will)
> <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>
> Subject: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.
>
> Provides a way for the user application to get the VBIOS information without having to parse the binary.
> It is useful for the user to be able to display in a simple way the VBIOS version in their system if they happen to encounter an issue.
>
> V2:
> Use numeric serial.
> Parse and expose vbios version string.
>
> Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com<mailto:Jiawei.Gu@amd.com>>
> Acked-by: Christian König <christian.koenig@amd.com<mailto:christian.koenig@amd.com>>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  21 +++
>   drivers/gpu/drm/amd/amdgpu/atom.c          | 174 +++++++++++++++++++++
>   drivers/gpu/drm/amd/amdgpu/atom.h          |  12 ++
>   drivers/gpu/drm/amd/include/atomfirmware.h |   5 +
>   include/uapi/drm/amdgpu_drm.h              |  16 ++
>   5 files changed, 228 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index 8d12e474745a..30e4fed3de22 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -861,6 +861,27 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
>                                            min((size_t)size, (size_t)(bios_size - bios_offset)))
>                                        ? -EFAULT : 0;
>                }
> +             case AMDGPU_INFO_VBIOS_INFO: {
> +                     struct drm_amdgpu_info_vbios vbios_info = {};
> +                     struct atom_context *atom_context;
> +
> +                     atom_context = adev->mode_info.atom_context;
> +                     memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
> +                     vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
> +                     memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
> +                     vbios_info.version = atom_context->version;
> +                     memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str,
> +                                             sizeof(atom_context->vbios_ver_str));
> +                     memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
> +                     vbios_info.serial = adev->unique_id;
> +                     vbios_info.dev_id = adev->pdev->device;
> +                     vbios_info.rev_id = adev->pdev->revision;
> +                     vbios_info.sub_dev_id = atom_context->sub_dev_id;
> +                     vbios_info.sub_ved_id = atom_context->sub_ved_id;
> +
> +                     return copy_to_user(out, &vbios_info,
> +                                             min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
> +             }
>                default:
>                        DRM_DEBUG_KMS("Invalid request %d\n",
>                                        info->vbios_info.type);
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c
> b/drivers/gpu/drm/amd/amdgpu/atom.c
> index 3dcb8b32f48b..542b2c2414e4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.c
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
> @@ -31,6 +31,7 @@
>
>   #define ATOM_DEBUG
>
> +#include "atomfirmware.h"
>   #include "atom.h"
>   #include "atom-names.h"
>   #include "atom-bits.h"
> @@ -1299,12 +1300,168 @@ static void atom_index_iio(struct atom_context *ctx, int base)
>        }
>   }
>
> +static void atom_get_vbios_name(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned char str_num;
> +     unsigned short off_to_vbios_str;
> +     unsigned char *c_ptr;
> +     int name_size;
> +     int i;
> +
> +     const char *na = "--N/A--";
> +     char *back;
> +
> +     p_rom = ctx->bios;
> +
> +     str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
> +     if (str_num != 0) {
> +             off_to_vbios_str =
> +                     *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +             c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
> +     } else {
> +             /* do not know where to find name */
> +             memcpy(ctx->name, na, 7);
> +             ctx->name[7] = 0;
> +             return;
> +     }
> +
> +     /*
> +      * skip the atombios strings, usually 4
> +      * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
> +      */
> +     for (i = 0; i < str_num; i++) {
> +             while (*c_ptr != 0)
> +                     c_ptr++;
> +             c_ptr++;
> +     }
> +
> +     /* skip the following 2 chars: 0x0D 0x0A */
> +     c_ptr += 2;
> +
> +     name_size = strnlen(c_ptr, STRLEN_LONG - 1);
> +     memcpy(ctx->name, c_ptr, name_size);
> +     back = ctx->name + name_size;
> +     while ((*--back) == ' ')
> +             ;
> +     *(back + 1) = '\0';
> +}
> +
> +static void atom_get_vbios_date(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned char *date_in_rom;
> +
> +     p_rom = ctx->bios;
> +
> +     date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
> +
> +     ctx->date[0] = '2';
> +     ctx->date[1] = '0';
> +     ctx->date[2] = date_in_rom[6];
> +     ctx->date[3] = date_in_rom[7];
> +     ctx->date[4] = '/';
> +     ctx->date[5] = date_in_rom[0];
> +     ctx->date[6] = date_in_rom[1];
> +     ctx->date[7] = '/';
> +     ctx->date[8] = date_in_rom[3];
> +     ctx->date[9] = date_in_rom[4];
> +     ctx->date[10] = ' ';
> +     ctx->date[11] = date_in_rom[9];
> +     ctx->date[12] = date_in_rom[10];
> +     ctx->date[13] = date_in_rom[11];
> +     ctx->date[14] = date_in_rom[12];
> +     ctx->date[15] = date_in_rom[13];
> +     ctx->date[16] = '\0';
> +}
> +
> +static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
> +                                        int end, int maxlen)
> +{
> +     unsigned long str_off;
> +     unsigned char *p_rom;
> +     unsigned short str_len;
> +
> +     str_off = 0;
> +     str_len = strnlen(str, maxlen);
> +     p_rom = ctx->bios;
> +
> +     for (; start <= end; ++start) {
> +             for (str_off = 0; str_off < str_len; ++str_off) {
> +                     if (str[str_off] != *(p_rom + start + str_off))
> +                             break;
> +             }
> +
> +             if (str_off == str_len || str[str_off] == 0)
> +                     return p_rom + start;
> +     }
> +     return NULL;
> +}
> +
> +static void atom_get_vbios_pn(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned short off_to_vbios_str;
> +     unsigned char *vbios_str;
> +     int count;
> +
> +     off_to_vbios_str = 0;
> +     p_rom = ctx->bios;
> +
> +     if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
> +             off_to_vbios_str =
> +                     *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +             vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
> +     } else {
> +             vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
> +     }
> +
> +     if (*vbios_str == 0) {
> +             vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
> +             if (vbios_str == NULL)
> +                     vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
> +     }
> +     if (vbios_str != NULL && *vbios_str == 0)
> +             vbios_str++;
> +
> +     if (vbios_str != NULL) {
> +             count = 0;
> +             while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
> +                    vbios_str[count] <= 'z') {
> +                     ctx->vbios_pn[count] = vbios_str[count];
> +                     count++;
> +             }
> +
> +             ctx->vbios_pn[count] = 0;
> +     }
> +}
> +
> +static void atom_get_vbios_version(struct atom_context *ctx) {
> +     unsigned char *vbios_ver;
> +
> +     /* find anchor ATOMBIOSBK-AMD */
> +     vbios_ver = atom_find_str_in_rom(ctx, BIOS_VERSION_PREFIX, 3, 1024, 64);
> +     if (vbios_ver != NULL) {
> +             /* skip ATOMBIOSBK-AMD VER */
> +             vbios_ver += 18;
> +             memcpy(ctx->vbios_ver_str, vbios_ver, STRLEN_NORMAL);
> +     } else {
> +             ctx->vbios_ver_str[0] = '\0';
> +     }
> +}
> +
>   struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)  {
>        int base;
>        struct atom_context *ctx =
>            kzalloc(sizeof(struct atom_context), GFP_KERNEL);
>        char *str;
> +     struct _ATOM_ROM_HEADER *atom_rom_header;
> +     struct _ATOM_MASTER_DATA_TABLE *master_table;
> +     struct _ATOM_FIRMWARE_INFO *atom_fw_info;
>        u16 idx;
>
>        if (!ctx)
> @@ -1353,6 +1510,23 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>                strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
>        }
>
> +     atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
> +     ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
> +     ctx->sub_ved_id = atom_rom_header->usSubsystemID;
> +     if (atom_rom_header->usMasterDataTableOffset != 0) {
> +             master_table = (struct _ATOM_MASTER_DATA_TABLE *)
> +                             CSTR(atom_rom_header->usMasterDataTableOffset);
> +             if (master_table->ListOfDataTables.FirmwareInfo != 0) {
> +                     atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
> +                                     CSTR(master_table->ListOfDataTables.FirmwareInfo);
> +                     ctx->version = atom_fw_info->ulFirmwareRevision;
> +             }
> +     }
> +
> +     atom_get_vbios_name(ctx);
> +     atom_get_vbios_pn(ctx);
> +     atom_get_vbios_date(ctx);
> +     atom_get_vbios_version(ctx);
>
>        return ctx;
>   }
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h
> b/drivers/gpu/drm/amd/amdgpu/atom.h
> index d279759cab47..6463ce6e756d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.h
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
> @@ -112,6 +112,10 @@ struct drm_device;
>   #define ATOM_IO_SYSIO               2
>   #define ATOM_IO_IIO         0x80
>
> +#define STRLEN_NORMAL                32
> +#define STRLEN_LONG          64
> +#define STRLEN_VERYLONG              254
> +
>   struct card_info {
>        struct drm_device *dev;
>        void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
> @@ -140,6 +144,14 @@ struct atom_context {
>        uint32_t *scratch;
>        int scratch_size_bytes;
>        char vbios_version[20];
> +
> +     uint8_t name[STRLEN_LONG];
> +     uint8_t vbios_pn[STRLEN_LONG];
> +     uint32_t version;
> +     uint8_t vbios_ver_str[STRLEN_NORMAL];
> +     uint8_t date[STRLEN_NORMAL];
> +     uint32_t sub_dev_id;
> +     uint32_t sub_ved_id;
>   };
>
>   extern int amdgpu_atom_debug;
> diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h
> b/drivers/gpu/drm/amd/include/atomfirmware.h
> index 275468e4be60..28deecc2f990 100644
> --- a/drivers/gpu/drm/amd/include/atomfirmware.h
> +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
> @@ -197,6 +197,9 @@ enum atom_dp_vs_preemph_def{
>     DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
>   };
>
> +#define BIOS_ATOM_PREFIX   "ATOMBIOS"
> +#define BIOS_VERSION_PREFIX  "ATOMBIOSBK-AMD"
> +#define BIOS_STRING_LENGTH 43
>
>   /*
>   enum atom_string_def{
> @@ -215,6 +218,8 @@ enum atombios_image_offset{
>     MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
>     OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
>     OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
> +  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
> +  OFFSET_TO_VBIOS_DATE                       = 0x50,
>   };
>
>
> /*********************************************************************
> ******* diff --git a/include/uapi/drm/amdgpu_drm.h
> b/include/uapi/drm/amdgpu_drm.h index 9169df7fadee..e0f98ca9a755
> 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -756,6 +756,8 @@ struct drm_amdgpu_cs_chunk_data {
>        #define AMDGPU_INFO_VBIOS_SIZE          0x1
>        /* Subquery id: Query vbios image */
>        #define AMDGPU_INFO_VBIOS_IMAGE         0x2
> +     /* Subquery id: Query vbios info */
> +     #define AMDGPU_INFO_VBIOS_INFO          0x3
>   /* Query UVD handles */
>   #define AMDGPU_INFO_NUM_HANDLES                     0x1C
>   /* Query sensor related information */ @@ -949,6 +951,20 @@ struct
> drm_amdgpu_info_firmware {
>        __u32 feature;
>   };
>
> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf;
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial;
> +     __u32 dev_id;
> +     __u32 rev_id;
> +     __u32 sub_dev_id;
> +     __u32 sub_ved_id;
> +};
> +
>   #define AMDGPU_VRAM_TYPE_UNKNOWN 0
>   #define AMDGPU_VRAM_TYPE_GDDR1 1
>   #define AMDGPU_VRAM_TYPE_DDR2  2
> --
> 2.17.1

[-- Attachment #1.2: Type: text/html, Size: 43035 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-05-18  5:58             ` Gu, JiaWei (Will)
@ 2021-05-18  7:23               ` Nieto, David M
  2021-05-18 10:50               ` Lazar, Lijo
  2021-05-19 13:09               ` Deucher, Alexander
  2 siblings, 0 replies; 47+ messages in thread
From: Nieto, David M @ 2021-05-18  7:23 UTC (permalink / raw)
  To: Gu, JiaWei (Will),
	Koenig, Christian, amd-gfx, maraeo, Deucher, Alexander
  Cc: Deng, Emily


[-- Attachment #1.1: Type: text/plain, Size: 20172 bytes --]

[Public]

That looks like the right output to me.
________________________________
From: Gu, JiaWei (Will) <JiaWei.Gu@amd.com>
Sent: Monday, May 17, 2021 10:58 PM
To: Nieto, David M <David.Nieto@amd.com>; Koenig, Christian <Christian.Koenig@amd.com>; amd-gfx@lists.freedesktop.org <amd-gfx@lists.freedesktop.org>; maraeo@gmail.com <maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com>
Cc: Deng, Emily <Emily.Deng@amd.com>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface


[Public]


Hi all,



Then the struct looks like:



> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +};



Sample output:



vbios name : NAVI12 A0 XT D30501 8GB EVAL 1150e/334m HYN/SAM
vbios pn : 113-D3050100-104
vbios version : 285409288
vbios ver_str : 017.003.000.008.016956
vbios date : 2021/05/03 23:32


Please help double confirm that we’re all fine with it and there’s no need to add & remove anything.



Best regards,

Jiawei



From: Nieto, David M <David.Nieto@amd.com>
Sent: Tuesday, May 18, 2021 12:40 PM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com>; Koenig, Christian <Christian.Koenig@amd.com>; amd-gfx@lists.freedesktop.org; maraeo@gmail.com; Deucher, Alexander <Alexander.Deucher@amd.com>
Cc: Deng, Emily <Emily.Deng@amd.com>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface



[Public]



Yes, let's remove that too,



Thanks,



David

________________________________

From: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>
Sent: Monday, May 17, 2021 8:07 PM
To: Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>>; maraeo@gmail.com<mailto:maraeo@gmail.com> <maraeo@gmail.com<mailto:maraeo@gmail.com>>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface



[AMD Official Use Only - Internal Distribution Only]



OK let’s remove serial.



dbdf comes from this:

vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);



I think we can remove dbdf as well.



Best regards,

Jiawei



From: Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>
Sent: Tuesday, May 18, 2021 10:45 AM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>; Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>; maraeo@gmail.com<mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface



[AMD Official Use Only - Internal Distribution Only]



The serial number is ASIC information, not VBIOS information, and it is still available as a sysfs node... I don't think we should put it there.



Not sure what dbdf stands for.

________________________________

From: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>
Sent: Monday, May 17, 2021 7:11 PM
To: Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>>; Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; maraeo@gmail.com<mailto:maraeo@gmail.com> <maraeo@gmail.com<mailto:maraeo@gmail.com>>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface



[AMD Official Use Only - Internal Distribution Only]

So I guess the dbdf is also needed to be removed?
And how about serial?

> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf; // do we need this?
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial; // do we need this?
> +};

Best regards,
Jiawei

-----Original Message-----
From: Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>
Sent: Monday, May 17, 2021 8:26 PM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>; Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; maraeo@gmail.com<mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

I'm not very familiar with the technical background why we have the fields here once more.

But of hand we should at least remove everything which is also available from the PCI information.

E.g. dev_id, rev_id, sub_dev_id, sub_ved_id.

Regards,
Christian.

Am 17.05.21 um 14:17 schrieb Gu, JiaWei (Will):
> [AMD Official Use Only - Internal Distribution Only]
>
> Hi all,
>
> Thanks Christian's suggestion.
> I reverted the previous patches and squash them into this single one.
>
> As this patch shows, the current uapi change looks like this:
>
> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf;
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial;
> +     __u32 dev_id;
> +     __u32 rev_id;
> +     __u32 sub_dev_id;
> +     __u32 sub_ved_id;
> +};
>
> As we know there's some redundant info in this struct.
> Please feel free to give any comments or suggestion about what it should & shouldn't include.
>
> Best regards,
> Jiawei
>
> -----Original Message-----
> From: Jiawei Gu <Jiawei.Gu@amd.com<mailto:Jiawei.Gu@amd.com>>
> Sent: Monday, May 17, 2021 8:08 PM
> To: amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>; Koenig, Christian
> <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>;
> maraeo@gmail.com<mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
> Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>; Gu, JiaWei (Will)
> <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>
> Subject: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.
>
> Provides a way for the user application to get the VBIOS information without having to parse the binary.
> It is useful for the user to be able to display in a simple way the VBIOS version in their system if they happen to encounter an issue.
>
> V2:
> Use numeric serial.
> Parse and expose vbios version string.
>
> Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com<mailto:Jiawei.Gu@amd.com>>
> Acked-by: Christian König <christian.koenig@amd.com<mailto:christian.koenig@amd.com>>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  21 +++
>   drivers/gpu/drm/amd/amdgpu/atom.c          | 174 +++++++++++++++++++++
>   drivers/gpu/drm/amd/amdgpu/atom.h          |  12 ++
>   drivers/gpu/drm/amd/include/atomfirmware.h |   5 +
>   include/uapi/drm/amdgpu_drm.h              |  16 ++
>   5 files changed, 228 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index 8d12e474745a..30e4fed3de22 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -861,6 +861,27 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
>                                            min((size_t)size, (size_t)(bios_size - bios_offset)))
>                                        ? -EFAULT : 0;
>                }
> +             case AMDGPU_INFO_VBIOS_INFO: {
> +                     struct drm_amdgpu_info_vbios vbios_info = {};
> +                     struct atom_context *atom_context;
> +
> +                     atom_context = adev->mode_info.atom_context;
> +                     memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
> +                     vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
> +                     memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
> +                     vbios_info.version = atom_context->version;
> +                     memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str,
> +                                             sizeof(atom_context->vbios_ver_str));
> +                     memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
> +                     vbios_info.serial = adev->unique_id;
> +                     vbios_info.dev_id = adev->pdev->device;
> +                     vbios_info.rev_id = adev->pdev->revision;
> +                     vbios_info.sub_dev_id = atom_context->sub_dev_id;
> +                     vbios_info.sub_ved_id = atom_context->sub_ved_id;
> +
> +                     return copy_to_user(out, &vbios_info,
> +                                             min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
> +             }
>                default:
>                        DRM_DEBUG_KMS("Invalid request %d\n",
>                                        info->vbios_info.type);
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c
> b/drivers/gpu/drm/amd/amdgpu/atom.c
> index 3dcb8b32f48b..542b2c2414e4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.c
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
> @@ -31,6 +31,7 @@
>
>   #define ATOM_DEBUG
>
> +#include "atomfirmware.h"
>   #include "atom.h"
>   #include "atom-names.h"
>   #include "atom-bits.h"
> @@ -1299,12 +1300,168 @@ static void atom_index_iio(struct atom_context *ctx, int base)
>        }
>   }
>
> +static void atom_get_vbios_name(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned char str_num;
> +     unsigned short off_to_vbios_str;
> +     unsigned char *c_ptr;
> +     int name_size;
> +     int i;
> +
> +     const char *na = "--N/A--";
> +     char *back;
> +
> +     p_rom = ctx->bios;
> +
> +     str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
> +     if (str_num != 0) {
> +             off_to_vbios_str =
> +                     *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +             c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
> +     } else {
> +             /* do not know where to find name */
> +             memcpy(ctx->name, na, 7);
> +             ctx->name[7] = 0;
> +             return;
> +     }
> +
> +     /*
> +      * skip the atombios strings, usually 4
> +      * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
> +      */
> +     for (i = 0; i < str_num; i++) {
> +             while (*c_ptr != 0)
> +                     c_ptr++;
> +             c_ptr++;
> +     }
> +
> +     /* skip the following 2 chars: 0x0D 0x0A */
> +     c_ptr += 2;
> +
> +     name_size = strnlen(c_ptr, STRLEN_LONG - 1);
> +     memcpy(ctx->name, c_ptr, name_size);
> +     back = ctx->name + name_size;
> +     while ((*--back) == ' ')
> +             ;
> +     *(back + 1) = '\0';
> +}
> +
> +static void atom_get_vbios_date(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned char *date_in_rom;
> +
> +     p_rom = ctx->bios;
> +
> +     date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
> +
> +     ctx->date[0] = '2';
> +     ctx->date[1] = '0';
> +     ctx->date[2] = date_in_rom[6];
> +     ctx->date[3] = date_in_rom[7];
> +     ctx->date[4] = '/';
> +     ctx->date[5] = date_in_rom[0];
> +     ctx->date[6] = date_in_rom[1];
> +     ctx->date[7] = '/';
> +     ctx->date[8] = date_in_rom[3];
> +     ctx->date[9] = date_in_rom[4];
> +     ctx->date[10] = ' ';
> +     ctx->date[11] = date_in_rom[9];
> +     ctx->date[12] = date_in_rom[10];
> +     ctx->date[13] = date_in_rom[11];
> +     ctx->date[14] = date_in_rom[12];
> +     ctx->date[15] = date_in_rom[13];
> +     ctx->date[16] = '\0';
> +}
> +
> +static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
> +                                        int end, int maxlen)
> +{
> +     unsigned long str_off;
> +     unsigned char *p_rom;
> +     unsigned short str_len;
> +
> +     str_off = 0;
> +     str_len = strnlen(str, maxlen);
> +     p_rom = ctx->bios;
> +
> +     for (; start <= end; ++start) {
> +             for (str_off = 0; str_off < str_len; ++str_off) {
> +                     if (str[str_off] != *(p_rom + start + str_off))
> +                             break;
> +             }
> +
> +             if (str_off == str_len || str[str_off] == 0)
> +                     return p_rom + start;
> +     }
> +     return NULL;
> +}
> +
> +static void atom_get_vbios_pn(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned short off_to_vbios_str;
> +     unsigned char *vbios_str;
> +     int count;
> +
> +     off_to_vbios_str = 0;
> +     p_rom = ctx->bios;
> +
> +     if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
> +             off_to_vbios_str =
> +                     *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +             vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
> +     } else {
> +             vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
> +     }
> +
> +     if (*vbios_str == 0) {
> +             vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
> +             if (vbios_str == NULL)
> +                     vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
> +     }
> +     if (vbios_str != NULL && *vbios_str == 0)
> +             vbios_str++;
> +
> +     if (vbios_str != NULL) {
> +             count = 0;
> +             while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
> +                    vbios_str[count] <= 'z') {
> +                     ctx->vbios_pn[count] = vbios_str[count];
> +                     count++;
> +             }
> +
> +             ctx->vbios_pn[count] = 0;
> +     }
> +}
> +
> +static void atom_get_vbios_version(struct atom_context *ctx) {
> +     unsigned char *vbios_ver;
> +
> +     /* find anchor ATOMBIOSBK-AMD */
> +     vbios_ver = atom_find_str_in_rom(ctx, BIOS_VERSION_PREFIX, 3, 1024, 64);
> +     if (vbios_ver != NULL) {
> +             /* skip ATOMBIOSBK-AMD VER */
> +             vbios_ver += 18;
> +             memcpy(ctx->vbios_ver_str, vbios_ver, STRLEN_NORMAL);
> +     } else {
> +             ctx->vbios_ver_str[0] = '\0';
> +     }
> +}
> +
>   struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)  {
>        int base;
>        struct atom_context *ctx =
>            kzalloc(sizeof(struct atom_context), GFP_KERNEL);
>        char *str;
> +     struct _ATOM_ROM_HEADER *atom_rom_header;
> +     struct _ATOM_MASTER_DATA_TABLE *master_table;
> +     struct _ATOM_FIRMWARE_INFO *atom_fw_info;
>        u16 idx;
>
>        if (!ctx)
> @@ -1353,6 +1510,23 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>                strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
>        }
>
> +     atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
> +     ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
> +     ctx->sub_ved_id = atom_rom_header->usSubsystemID;
> +     if (atom_rom_header->usMasterDataTableOffset != 0) {
> +             master_table = (struct _ATOM_MASTER_DATA_TABLE *)
> +                             CSTR(atom_rom_header->usMasterDataTableOffset);
> +             if (master_table->ListOfDataTables.FirmwareInfo != 0) {
> +                     atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
> +                                     CSTR(master_table->ListOfDataTables.FirmwareInfo);
> +                     ctx->version = atom_fw_info->ulFirmwareRevision;
> +             }
> +     }
> +
> +     atom_get_vbios_name(ctx);
> +     atom_get_vbios_pn(ctx);
> +     atom_get_vbios_date(ctx);
> +     atom_get_vbios_version(ctx);
>
>        return ctx;
>   }
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h
> b/drivers/gpu/drm/amd/amdgpu/atom.h
> index d279759cab47..6463ce6e756d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.h
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
> @@ -112,6 +112,10 @@ struct drm_device;
>   #define ATOM_IO_SYSIO               2
>   #define ATOM_IO_IIO         0x80
>
> +#define STRLEN_NORMAL                32
> +#define STRLEN_LONG          64
> +#define STRLEN_VERYLONG              254
> +
>   struct card_info {
>        struct drm_device *dev;
>        void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
> @@ -140,6 +144,14 @@ struct atom_context {
>        uint32_t *scratch;
>        int scratch_size_bytes;
>        char vbios_version[20];
> +
> +     uint8_t name[STRLEN_LONG];
> +     uint8_t vbios_pn[STRLEN_LONG];
> +     uint32_t version;
> +     uint8_t vbios_ver_str[STRLEN_NORMAL];
> +     uint8_t date[STRLEN_NORMAL];
> +     uint32_t sub_dev_id;
> +     uint32_t sub_ved_id;
>   };
>
>   extern int amdgpu_atom_debug;
> diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h
> b/drivers/gpu/drm/amd/include/atomfirmware.h
> index 275468e4be60..28deecc2f990 100644
> --- a/drivers/gpu/drm/amd/include/atomfirmware.h
> +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
> @@ -197,6 +197,9 @@ enum atom_dp_vs_preemph_def{
>     DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
>   };
>
> +#define BIOS_ATOM_PREFIX   "ATOMBIOS"
> +#define BIOS_VERSION_PREFIX  "ATOMBIOSBK-AMD"
> +#define BIOS_STRING_LENGTH 43
>
>   /*
>   enum atom_string_def{
> @@ -215,6 +218,8 @@ enum atombios_image_offset{
>     MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
>     OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
>     OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
> +  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
> +  OFFSET_TO_VBIOS_DATE                       = 0x50,
>   };
>
>
> /*********************************************************************
> ******* diff --git a/include/uapi/drm/amdgpu_drm.h
> b/include/uapi/drm/amdgpu_drm.h index 9169df7fadee..e0f98ca9a755
> 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -756,6 +756,8 @@ struct drm_amdgpu_cs_chunk_data {
>        #define AMDGPU_INFO_VBIOS_SIZE          0x1
>        /* Subquery id: Query vbios image */
>        #define AMDGPU_INFO_VBIOS_IMAGE         0x2
> +     /* Subquery id: Query vbios info */
> +     #define AMDGPU_INFO_VBIOS_INFO          0x3
>   /* Query UVD handles */
>   #define AMDGPU_INFO_NUM_HANDLES                     0x1C
>   /* Query sensor related information */ @@ -949,6 +951,20 @@ struct
> drm_amdgpu_info_firmware {
>        __u32 feature;
>   };
>
> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf;
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial;
> +     __u32 dev_id;
> +     __u32 rev_id;
> +     __u32 sub_dev_id;
> +     __u32 sub_ved_id;
> +};
> +
>   #define AMDGPU_VRAM_TYPE_UNKNOWN 0
>   #define AMDGPU_VRAM_TYPE_GDDR1 1
>   #define AMDGPU_VRAM_TYPE_DDR2  2
> --
> 2.17.1

[-- Attachment #1.2: Type: text/html, Size: 40818 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-05-18  4:40           ` Nieto, David M
@ 2021-05-18  5:58             ` Gu, JiaWei (Will)
  2021-05-18  7:23               ` Nieto, David M
                                 ` (2 more replies)
  0 siblings, 3 replies; 47+ messages in thread
From: Gu, JiaWei (Will) @ 2021-05-18  5:58 UTC (permalink / raw)
  To: Nieto, David M, Koenig, Christian, amd-gfx, maraeo, Deucher, Alexander
  Cc: Deng, Emily


[-- Attachment #1.1: Type: text/plain, Size: 19610 bytes --]

[Public]

Hi all,

Then the struct looks like:

> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +};

Sample output:

vbios name : NAVI12 A0 XT D30501 8GB EVAL 1150e/334m HYN/SAM
vbios pn : 113-D3050100-104
vbios version : 285409288
vbios ver_str : 017.003.000.008.016956
vbios date : 2021/05/03 23:32

Please help double confirm that we're all fine with it and there's no need to add & remove anything.

Best regards,
Jiawei

From: Nieto, David M <David.Nieto@amd.com>
Sent: Tuesday, May 18, 2021 12:40 PM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com>; Koenig, Christian <Christian.Koenig@amd.com>; amd-gfx@lists.freedesktop.org; maraeo@gmail.com; Deucher, Alexander <Alexander.Deucher@amd.com>
Cc: Deng, Emily <Emily.Deng@amd.com>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface


[Public]

Yes, let's remove that too,

Thanks,

David
________________________________
From: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>
Sent: Monday, May 17, 2021 8:07 PM
To: Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>>; maraeo@gmail.com<mailto:maraeo@gmail.com> <maraeo@gmail.com<mailto:maraeo@gmail.com>>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface


[AMD Official Use Only - Internal Distribution Only]



OK let's remove serial.



dbdf comes from this:

vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);



I think we can remove dbdf as well.



Best regards,

Jiawei



From: Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>
Sent: Tuesday, May 18, 2021 10:45 AM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>; Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>; maraeo@gmail.com<mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface



[AMD Official Use Only - Internal Distribution Only]



The serial number is ASIC information, not VBIOS information, and it is still available as a sysfs node... I don't think we should put it there.



Not sure what dbdf stands for.

________________________________

From: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>
Sent: Monday, May 17, 2021 7:11 PM
To: Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>>; Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; maraeo@gmail.com<mailto:maraeo@gmail.com> <maraeo@gmail.com<mailto:maraeo@gmail.com>>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface



[AMD Official Use Only - Internal Distribution Only]

So I guess the dbdf is also needed to be removed?
And how about serial?

> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf; // do we need this?
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial; // do we need this?
> +};

Best regards,
Jiawei

-----Original Message-----
From: Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>
Sent: Monday, May 17, 2021 8:26 PM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>; Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; maraeo@gmail.com<mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

I'm not very familiar with the technical background why we have the fields here once more.

But of hand we should at least remove everything which is also available from the PCI information.

E.g. dev_id, rev_id, sub_dev_id, sub_ved_id.

Regards,
Christian.

Am 17.05.21 um 14:17 schrieb Gu, JiaWei (Will):
> [AMD Official Use Only - Internal Distribution Only]
>
> Hi all,
>
> Thanks Christian's suggestion.
> I reverted the previous patches and squash them into this single one.
>
> As this patch shows, the current uapi change looks like this:
>
> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf;
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial;
> +     __u32 dev_id;
> +     __u32 rev_id;
> +     __u32 sub_dev_id;
> +     __u32 sub_ved_id;
> +};
>
> As we know there's some redundant info in this struct.
> Please feel free to give any comments or suggestion about what it should & shouldn't include.
>
> Best regards,
> Jiawei
>
> -----Original Message-----
> From: Jiawei Gu <Jiawei.Gu@amd.com<mailto:Jiawei.Gu@amd.com>>
> Sent: Monday, May 17, 2021 8:08 PM
> To: amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>; Koenig, Christian
> <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>;
> maraeo@gmail.com<mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
> Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>; Gu, JiaWei (Will)
> <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>
> Subject: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.
>
> Provides a way for the user application to get the VBIOS information without having to parse the binary.
> It is useful for the user to be able to display in a simple way the VBIOS version in their system if they happen to encounter an issue.
>
> V2:
> Use numeric serial.
> Parse and expose vbios version string.
>
> Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com<mailto:Jiawei.Gu@amd.com>>
> Acked-by: Christian König <christian.koenig@amd.com<mailto:christian.koenig@amd.com>>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  21 +++
>   drivers/gpu/drm/amd/amdgpu/atom.c          | 174 +++++++++++++++++++++
>   drivers/gpu/drm/amd/amdgpu/atom.h          |  12 ++
>   drivers/gpu/drm/amd/include/atomfirmware.h |   5 +
>   include/uapi/drm/amdgpu_drm.h              |  16 ++
>   5 files changed, 228 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index 8d12e474745a..30e4fed3de22 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -861,6 +861,27 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
>                                            min((size_t)size, (size_t)(bios_size - bios_offset)))
>                                        ? -EFAULT : 0;
>                }
> +             case AMDGPU_INFO_VBIOS_INFO: {
> +                     struct drm_amdgpu_info_vbios vbios_info = {};
> +                     struct atom_context *atom_context;
> +
> +                     atom_context = adev->mode_info.atom_context;
> +                     memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
> +                     vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
> +                     memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
> +                     vbios_info.version = atom_context->version;
> +                     memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str,
> +                                             sizeof(atom_context->vbios_ver_str));
> +                     memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
> +                     vbios_info.serial = adev->unique_id;
> +                     vbios_info.dev_id = adev->pdev->device;
> +                     vbios_info.rev_id = adev->pdev->revision;
> +                     vbios_info.sub_dev_id = atom_context->sub_dev_id;
> +                     vbios_info.sub_ved_id = atom_context->sub_ved_id;
> +
> +                     return copy_to_user(out, &vbios_info,
> +                                             min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
> +             }
>                default:
>                        DRM_DEBUG_KMS("Invalid request %d\n",
>                                        info->vbios_info.type);
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c
> b/drivers/gpu/drm/amd/amdgpu/atom.c
> index 3dcb8b32f48b..542b2c2414e4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.c
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
> @@ -31,6 +31,7 @@
>
>   #define ATOM_DEBUG
>
> +#include "atomfirmware.h"
>   #include "atom.h"
>   #include "atom-names.h"
>   #include "atom-bits.h"
> @@ -1299,12 +1300,168 @@ static void atom_index_iio(struct atom_context *ctx, int base)
>        }
>   }
>
> +static void atom_get_vbios_name(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned char str_num;
> +     unsigned short off_to_vbios_str;
> +     unsigned char *c_ptr;
> +     int name_size;
> +     int i;
> +
> +     const char *na = "--N/A--";
> +     char *back;
> +
> +     p_rom = ctx->bios;
> +
> +     str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
> +     if (str_num != 0) {
> +             off_to_vbios_str =
> +                     *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +             c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
> +     } else {
> +             /* do not know where to find name */
> +             memcpy(ctx->name, na, 7);
> +             ctx->name[7] = 0;
> +             return;
> +     }
> +
> +     /*
> +      * skip the atombios strings, usually 4
> +      * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
> +      */
> +     for (i = 0; i < str_num; i++) {
> +             while (*c_ptr != 0)
> +                     c_ptr++;
> +             c_ptr++;
> +     }
> +
> +     /* skip the following 2 chars: 0x0D 0x0A */
> +     c_ptr += 2;
> +
> +     name_size = strnlen(c_ptr, STRLEN_LONG - 1);
> +     memcpy(ctx->name, c_ptr, name_size);
> +     back = ctx->name + name_size;
> +     while ((*--back) == ' ')
> +             ;
> +     *(back + 1) = '\0';
> +}
> +
> +static void atom_get_vbios_date(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned char *date_in_rom;
> +
> +     p_rom = ctx->bios;
> +
> +     date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
> +
> +     ctx->date[0] = '2';
> +     ctx->date[1] = '0';
> +     ctx->date[2] = date_in_rom[6];
> +     ctx->date[3] = date_in_rom[7];
> +     ctx->date[4] = '/';
> +     ctx->date[5] = date_in_rom[0];
> +     ctx->date[6] = date_in_rom[1];
> +     ctx->date[7] = '/';
> +     ctx->date[8] = date_in_rom[3];
> +     ctx->date[9] = date_in_rom[4];
> +     ctx->date[10] = ' ';
> +     ctx->date[11] = date_in_rom[9];
> +     ctx->date[12] = date_in_rom[10];
> +     ctx->date[13] = date_in_rom[11];
> +     ctx->date[14] = date_in_rom[12];
> +     ctx->date[15] = date_in_rom[13];
> +     ctx->date[16] = '\0';
> +}
> +
> +static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
> +                                        int end, int maxlen)
> +{
> +     unsigned long str_off;
> +     unsigned char *p_rom;
> +     unsigned short str_len;
> +
> +     str_off = 0;
> +     str_len = strnlen(str, maxlen);
> +     p_rom = ctx->bios;
> +
> +     for (; start <= end; ++start) {
> +             for (str_off = 0; str_off < str_len; ++str_off) {
> +                     if (str[str_off] != *(p_rom + start + str_off))
> +                             break;
> +             }
> +
> +             if (str_off == str_len || str[str_off] == 0)
> +                     return p_rom + start;
> +     }
> +     return NULL;
> +}
> +
> +static void atom_get_vbios_pn(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned short off_to_vbios_str;
> +     unsigned char *vbios_str;
> +     int count;
> +
> +     off_to_vbios_str = 0;
> +     p_rom = ctx->bios;
> +
> +     if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
> +             off_to_vbios_str =
> +                     *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +             vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
> +     } else {
> +             vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
> +     }
> +
> +     if (*vbios_str == 0) {
> +             vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
> +             if (vbios_str == NULL)
> +                     vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
> +     }
> +     if (vbios_str != NULL && *vbios_str == 0)
> +             vbios_str++;
> +
> +     if (vbios_str != NULL) {
> +             count = 0;
> +             while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
> +                    vbios_str[count] <= 'z') {
> +                     ctx->vbios_pn[count] = vbios_str[count];
> +                     count++;
> +             }
> +
> +             ctx->vbios_pn[count] = 0;
> +     }
> +}
> +
> +static void atom_get_vbios_version(struct atom_context *ctx) {
> +     unsigned char *vbios_ver;
> +
> +     /* find anchor ATOMBIOSBK-AMD */
> +     vbios_ver = atom_find_str_in_rom(ctx, BIOS_VERSION_PREFIX, 3, 1024, 64);
> +     if (vbios_ver != NULL) {
> +             /* skip ATOMBIOSBK-AMD VER */
> +             vbios_ver += 18;
> +             memcpy(ctx->vbios_ver_str, vbios_ver, STRLEN_NORMAL);
> +     } else {
> +             ctx->vbios_ver_str[0] = '\0';
> +     }
> +}
> +
>   struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)  {
>        int base;
>        struct atom_context *ctx =
>            kzalloc(sizeof(struct atom_context), GFP_KERNEL);
>        char *str;
> +     struct _ATOM_ROM_HEADER *atom_rom_header;
> +     struct _ATOM_MASTER_DATA_TABLE *master_table;
> +     struct _ATOM_FIRMWARE_INFO *atom_fw_info;
>        u16 idx;
>
>        if (!ctx)
> @@ -1353,6 +1510,23 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>                strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
>        }
>
> +     atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
> +     ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
> +     ctx->sub_ved_id = atom_rom_header->usSubsystemID;
> +     if (atom_rom_header->usMasterDataTableOffset != 0) {
> +             master_table = (struct _ATOM_MASTER_DATA_TABLE *)
> +                             CSTR(atom_rom_header->usMasterDataTableOffset);
> +             if (master_table->ListOfDataTables.FirmwareInfo != 0) {
> +                     atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
> +                                     CSTR(master_table->ListOfDataTables.FirmwareInfo);
> +                     ctx->version = atom_fw_info->ulFirmwareRevision;
> +             }
> +     }
> +
> +     atom_get_vbios_name(ctx);
> +     atom_get_vbios_pn(ctx);
> +     atom_get_vbios_date(ctx);
> +     atom_get_vbios_version(ctx);
>
>        return ctx;
>   }
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h
> b/drivers/gpu/drm/amd/amdgpu/atom.h
> index d279759cab47..6463ce6e756d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.h
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
> @@ -112,6 +112,10 @@ struct drm_device;
>   #define ATOM_IO_SYSIO               2
>   #define ATOM_IO_IIO         0x80
>
> +#define STRLEN_NORMAL                32
> +#define STRLEN_LONG          64
> +#define STRLEN_VERYLONG              254
> +
>   struct card_info {
>        struct drm_device *dev;
>        void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
> @@ -140,6 +144,14 @@ struct atom_context {
>        uint32_t *scratch;
>        int scratch_size_bytes;
>        char vbios_version[20];
> +
> +     uint8_t name[STRLEN_LONG];
> +     uint8_t vbios_pn[STRLEN_LONG];
> +     uint32_t version;
> +     uint8_t vbios_ver_str[STRLEN_NORMAL];
> +     uint8_t date[STRLEN_NORMAL];
> +     uint32_t sub_dev_id;
> +     uint32_t sub_ved_id;
>   };
>
>   extern int amdgpu_atom_debug;
> diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h
> b/drivers/gpu/drm/amd/include/atomfirmware.h
> index 275468e4be60..28deecc2f990 100644
> --- a/drivers/gpu/drm/amd/include/atomfirmware.h
> +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
> @@ -197,6 +197,9 @@ enum atom_dp_vs_preemph_def{
>     DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
>   };
>
> +#define BIOS_ATOM_PREFIX   "ATOMBIOS"
> +#define BIOS_VERSION_PREFIX  "ATOMBIOSBK-AMD"
> +#define BIOS_STRING_LENGTH 43
>
>   /*
>   enum atom_string_def{
> @@ -215,6 +218,8 @@ enum atombios_image_offset{
>     MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
>     OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
>     OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
> +  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
> +  OFFSET_TO_VBIOS_DATE                       = 0x50,
>   };
>
>
> /*********************************************************************
> ******* diff --git a/include/uapi/drm/amdgpu_drm.h
> b/include/uapi/drm/amdgpu_drm.h index 9169df7fadee..e0f98ca9a755
> 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -756,6 +756,8 @@ struct drm_amdgpu_cs_chunk_data {
>        #define AMDGPU_INFO_VBIOS_SIZE          0x1
>        /* Subquery id: Query vbios image */
>        #define AMDGPU_INFO_VBIOS_IMAGE         0x2
> +     /* Subquery id: Query vbios info */
> +     #define AMDGPU_INFO_VBIOS_INFO          0x3
>   /* Query UVD handles */
>   #define AMDGPU_INFO_NUM_HANDLES                     0x1C
>   /* Query sensor related information */ @@ -949,6 +951,20 @@ struct
> drm_amdgpu_info_firmware {
>        __u32 feature;
>   };
>
> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf;
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial;
> +     __u32 dev_id;
> +     __u32 rev_id;
> +     __u32 sub_dev_id;
> +     __u32 sub_ved_id;
> +};
> +
>   #define AMDGPU_VRAM_TYPE_UNKNOWN 0
>   #define AMDGPU_VRAM_TYPE_GDDR1 1
>   #define AMDGPU_VRAM_TYPE_DDR2  2
> --
> 2.17.1

[-- Attachment #1.2: Type: text/html, Size: 41243 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-05-18  3:07         ` Gu, JiaWei (Will)
@ 2021-05-18  4:40           ` Nieto, David M
  2021-05-18  5:58             ` Gu, JiaWei (Will)
  0 siblings, 1 reply; 47+ messages in thread
From: Nieto, David M @ 2021-05-18  4:40 UTC (permalink / raw)
  To: Gu, JiaWei (Will),
	Koenig, Christian, amd-gfx, maraeo, Deucher, Alexander
  Cc: Deng, Emily


[-- Attachment #1.1: Type: text/plain, Size: 18181 bytes --]

[Public]

Yes, let's remove that too,

Thanks,

David
________________________________
From: Gu, JiaWei (Will) <JiaWei.Gu@amd.com>
Sent: Monday, May 17, 2021 8:07 PM
To: Nieto, David M <David.Nieto@amd.com>; Koenig, Christian <Christian.Koenig@amd.com>; amd-gfx@lists.freedesktop.org <amd-gfx@lists.freedesktop.org>; maraeo@gmail.com <maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com>
Cc: Deng, Emily <Emily.Deng@amd.com>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface


[AMD Official Use Only - Internal Distribution Only]



OK let’s remove serial.



dbdf comes from this:

vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);



I think we can remove dbdf as well.



Best regards,

Jiawei



From: Nieto, David M <David.Nieto@amd.com>
Sent: Tuesday, May 18, 2021 10:45 AM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com>; Koenig, Christian <Christian.Koenig@amd.com>; amd-gfx@lists.freedesktop.org; maraeo@gmail.com; Deucher, Alexander <Alexander.Deucher@amd.com>
Cc: Deng, Emily <Emily.Deng@amd.com>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface



[AMD Official Use Only - Internal Distribution Only]



The serial number is ASIC information, not VBIOS information, and it is still available as a sysfs node... I don't think we should put it there.



Not sure what dbdf stands for.

________________________________

From: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>
Sent: Monday, May 17, 2021 7:11 PM
To: Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>>; Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; maraeo@gmail.com<mailto:maraeo@gmail.com> <maraeo@gmail.com<mailto:maraeo@gmail.com>>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface



[AMD Official Use Only - Internal Distribution Only]

So I guess the dbdf is also needed to be removed?
And how about serial?

> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf; // do we need this?
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial; // do we need this?
> +};

Best regards,
Jiawei

-----Original Message-----
From: Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>
Sent: Monday, May 17, 2021 8:26 PM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>; Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; maraeo@gmail.com<mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

I'm not very familiar with the technical background why we have the fields here once more.

But of hand we should at least remove everything which is also available from the PCI information.

E.g. dev_id, rev_id, sub_dev_id, sub_ved_id.

Regards,
Christian.

Am 17.05.21 um 14:17 schrieb Gu, JiaWei (Will):
> [AMD Official Use Only - Internal Distribution Only]
>
> Hi all,
>
> Thanks Christian's suggestion.
> I reverted the previous patches and squash them into this single one.
>
> As this patch shows, the current uapi change looks like this:
>
> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf;
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial;
> +     __u32 dev_id;
> +     __u32 rev_id;
> +     __u32 sub_dev_id;
> +     __u32 sub_ved_id;
> +};
>
> As we know there's some redundant info in this struct.
> Please feel free to give any comments or suggestion about what it should & shouldn't include.
>
> Best regards,
> Jiawei
>
> -----Original Message-----
> From: Jiawei Gu <Jiawei.Gu@amd.com<mailto:Jiawei.Gu@amd.com>>
> Sent: Monday, May 17, 2021 8:08 PM
> To: amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>; Koenig, Christian
> <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>;
> maraeo@gmail.com<mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
> Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>; Gu, JiaWei (Will)
> <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>
> Subject: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.
>
> Provides a way for the user application to get the VBIOS information without having to parse the binary.
> It is useful for the user to be able to display in a simple way the VBIOS version in their system if they happen to encounter an issue.
>
> V2:
> Use numeric serial.
> Parse and expose vbios version string.
>
> Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com<mailto:Jiawei.Gu@amd.com>>
> Acked-by: Christian König <christian.koenig@amd.com<mailto:christian.koenig@amd.com>>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  21 +++
>   drivers/gpu/drm/amd/amdgpu/atom.c          | 174 +++++++++++++++++++++
>   drivers/gpu/drm/amd/amdgpu/atom.h          |  12 ++
>   drivers/gpu/drm/amd/include/atomfirmware.h |   5 +
>   include/uapi/drm/amdgpu_drm.h              |  16 ++
>   5 files changed, 228 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index 8d12e474745a..30e4fed3de22 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -861,6 +861,27 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
>                                            min((size_t)size, (size_t)(bios_size - bios_offset)))
>                                        ? -EFAULT : 0;
>                }
> +             case AMDGPU_INFO_VBIOS_INFO: {
> +                     struct drm_amdgpu_info_vbios vbios_info = {};
> +                     struct atom_context *atom_context;
> +
> +                     atom_context = adev->mode_info.atom_context;
> +                     memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
> +                     vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
> +                     memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
> +                     vbios_info.version = atom_context->version;
> +                     memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str,
> +                                             sizeof(atom_context->vbios_ver_str));
> +                     memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
> +                     vbios_info.serial = adev->unique_id;
> +                     vbios_info.dev_id = adev->pdev->device;
> +                     vbios_info.rev_id = adev->pdev->revision;
> +                     vbios_info.sub_dev_id = atom_context->sub_dev_id;
> +                     vbios_info.sub_ved_id = atom_context->sub_ved_id;
> +
> +                     return copy_to_user(out, &vbios_info,
> +                                             min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
> +             }
>                default:
>                        DRM_DEBUG_KMS("Invalid request %d\n",
>                                        info->vbios_info.type);
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c
> b/drivers/gpu/drm/amd/amdgpu/atom.c
> index 3dcb8b32f48b..542b2c2414e4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.c
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
> @@ -31,6 +31,7 @@
>
>   #define ATOM_DEBUG
>
> +#include "atomfirmware.h"
>   #include "atom.h"
>   #include "atom-names.h"
>   #include "atom-bits.h"
> @@ -1299,12 +1300,168 @@ static void atom_index_iio(struct atom_context *ctx, int base)
>        }
>   }
>
> +static void atom_get_vbios_name(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned char str_num;
> +     unsigned short off_to_vbios_str;
> +     unsigned char *c_ptr;
> +     int name_size;
> +     int i;
> +
> +     const char *na = "--N/A--";
> +     char *back;
> +
> +     p_rom = ctx->bios;
> +
> +     str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
> +     if (str_num != 0) {
> +             off_to_vbios_str =
> +                     *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +             c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
> +     } else {
> +             /* do not know where to find name */
> +             memcpy(ctx->name, na, 7);
> +             ctx->name[7] = 0;
> +             return;
> +     }
> +
> +     /*
> +      * skip the atombios strings, usually 4
> +      * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
> +      */
> +     for (i = 0; i < str_num; i++) {
> +             while (*c_ptr != 0)
> +                     c_ptr++;
> +             c_ptr++;
> +     }
> +
> +     /* skip the following 2 chars: 0x0D 0x0A */
> +     c_ptr += 2;
> +
> +     name_size = strnlen(c_ptr, STRLEN_LONG - 1);
> +     memcpy(ctx->name, c_ptr, name_size);
> +     back = ctx->name + name_size;
> +     while ((*--back) == ' ')
> +             ;
> +     *(back + 1) = '\0';
> +}
> +
> +static void atom_get_vbios_date(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned char *date_in_rom;
> +
> +     p_rom = ctx->bios;
> +
> +     date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
> +
> +     ctx->date[0] = '2';
> +     ctx->date[1] = '0';
> +     ctx->date[2] = date_in_rom[6];
> +     ctx->date[3] = date_in_rom[7];
> +     ctx->date[4] = '/';
> +     ctx->date[5] = date_in_rom[0];
> +     ctx->date[6] = date_in_rom[1];
> +     ctx->date[7] = '/';
> +     ctx->date[8] = date_in_rom[3];
> +     ctx->date[9] = date_in_rom[4];
> +     ctx->date[10] = ' ';
> +     ctx->date[11] = date_in_rom[9];
> +     ctx->date[12] = date_in_rom[10];
> +     ctx->date[13] = date_in_rom[11];
> +     ctx->date[14] = date_in_rom[12];
> +     ctx->date[15] = date_in_rom[13];
> +     ctx->date[16] = '\0';
> +}
> +
> +static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
> +                                        int end, int maxlen)
> +{
> +     unsigned long str_off;
> +     unsigned char *p_rom;
> +     unsigned short str_len;
> +
> +     str_off = 0;
> +     str_len = strnlen(str, maxlen);
> +     p_rom = ctx->bios;
> +
> +     for (; start <= end; ++start) {
> +             for (str_off = 0; str_off < str_len; ++str_off) {
> +                     if (str[str_off] != *(p_rom + start + str_off))
> +                             break;
> +             }
> +
> +             if (str_off == str_len || str[str_off] == 0)
> +                     return p_rom + start;
> +     }
> +     return NULL;
> +}
> +
> +static void atom_get_vbios_pn(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned short off_to_vbios_str;
> +     unsigned char *vbios_str;
> +     int count;
> +
> +     off_to_vbios_str = 0;
> +     p_rom = ctx->bios;
> +
> +     if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
> +             off_to_vbios_str =
> +                     *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +             vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
> +     } else {
> +             vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
> +     }
> +
> +     if (*vbios_str == 0) {
> +             vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
> +             if (vbios_str == NULL)
> +                     vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
> +     }
> +     if (vbios_str != NULL && *vbios_str == 0)
> +             vbios_str++;
> +
> +     if (vbios_str != NULL) {
> +             count = 0;
> +             while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
> +                    vbios_str[count] <= 'z') {
> +                     ctx->vbios_pn[count] = vbios_str[count];
> +                     count++;
> +             }
> +
> +             ctx->vbios_pn[count] = 0;
> +     }
> +}
> +
> +static void atom_get_vbios_version(struct atom_context *ctx) {
> +     unsigned char *vbios_ver;
> +
> +     /* find anchor ATOMBIOSBK-AMD */
> +     vbios_ver = atom_find_str_in_rom(ctx, BIOS_VERSION_PREFIX, 3, 1024, 64);
> +     if (vbios_ver != NULL) {
> +             /* skip ATOMBIOSBK-AMD VER */
> +             vbios_ver += 18;
> +             memcpy(ctx->vbios_ver_str, vbios_ver, STRLEN_NORMAL);
> +     } else {
> +             ctx->vbios_ver_str[0] = '\0';
> +     }
> +}
> +
>   struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)  {
>        int base;
>        struct atom_context *ctx =
>            kzalloc(sizeof(struct atom_context), GFP_KERNEL);
>        char *str;
> +     struct _ATOM_ROM_HEADER *atom_rom_header;
> +     struct _ATOM_MASTER_DATA_TABLE *master_table;
> +     struct _ATOM_FIRMWARE_INFO *atom_fw_info;
>        u16 idx;
>
>        if (!ctx)
> @@ -1353,6 +1510,23 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>                strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
>        }
>
> +     atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
> +     ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
> +     ctx->sub_ved_id = atom_rom_header->usSubsystemID;
> +     if (atom_rom_header->usMasterDataTableOffset != 0) {
> +             master_table = (struct _ATOM_MASTER_DATA_TABLE *)
> +                             CSTR(atom_rom_header->usMasterDataTableOffset);
> +             if (master_table->ListOfDataTables.FirmwareInfo != 0) {
> +                     atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
> +                                     CSTR(master_table->ListOfDataTables.FirmwareInfo);
> +                     ctx->version = atom_fw_info->ulFirmwareRevision;
> +             }
> +     }
> +
> +     atom_get_vbios_name(ctx);
> +     atom_get_vbios_pn(ctx);
> +     atom_get_vbios_date(ctx);
> +     atom_get_vbios_version(ctx);
>
>        return ctx;
>   }
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h
> b/drivers/gpu/drm/amd/amdgpu/atom.h
> index d279759cab47..6463ce6e756d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.h
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
> @@ -112,6 +112,10 @@ struct drm_device;
>   #define ATOM_IO_SYSIO               2
>   #define ATOM_IO_IIO         0x80
>
> +#define STRLEN_NORMAL                32
> +#define STRLEN_LONG          64
> +#define STRLEN_VERYLONG              254
> +
>   struct card_info {
>        struct drm_device *dev;
>        void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
> @@ -140,6 +144,14 @@ struct atom_context {
>        uint32_t *scratch;
>        int scratch_size_bytes;
>        char vbios_version[20];
> +
> +     uint8_t name[STRLEN_LONG];
> +     uint8_t vbios_pn[STRLEN_LONG];
> +     uint32_t version;
> +     uint8_t vbios_ver_str[STRLEN_NORMAL];
> +     uint8_t date[STRLEN_NORMAL];
> +     uint32_t sub_dev_id;
> +     uint32_t sub_ved_id;
>   };
>
>   extern int amdgpu_atom_debug;
> diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h
> b/drivers/gpu/drm/amd/include/atomfirmware.h
> index 275468e4be60..28deecc2f990 100644
> --- a/drivers/gpu/drm/amd/include/atomfirmware.h
> +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
> @@ -197,6 +197,9 @@ enum atom_dp_vs_preemph_def{
>     DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
>   };
>
> +#define BIOS_ATOM_PREFIX   "ATOMBIOS"
> +#define BIOS_VERSION_PREFIX  "ATOMBIOSBK-AMD"
> +#define BIOS_STRING_LENGTH 43
>
>   /*
>   enum atom_string_def{
> @@ -215,6 +218,8 @@ enum atombios_image_offset{
>     MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
>     OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
>     OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
> +  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
> +  OFFSET_TO_VBIOS_DATE                       = 0x50,
>   };
>
>
> /*********************************************************************
> ******* diff --git a/include/uapi/drm/amdgpu_drm.h
> b/include/uapi/drm/amdgpu_drm.h index 9169df7fadee..e0f98ca9a755
> 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -756,6 +756,8 @@ struct drm_amdgpu_cs_chunk_data {
>        #define AMDGPU_INFO_VBIOS_SIZE          0x1
>        /* Subquery id: Query vbios image */
>        #define AMDGPU_INFO_VBIOS_IMAGE         0x2
> +     /* Subquery id: Query vbios info */
> +     #define AMDGPU_INFO_VBIOS_INFO          0x3
>   /* Query UVD handles */
>   #define AMDGPU_INFO_NUM_HANDLES                     0x1C
>   /* Query sensor related information */ @@ -949,6 +951,20 @@ struct
> drm_amdgpu_info_firmware {
>        __u32 feature;
>   };
>
> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf;
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial;
> +     __u32 dev_id;
> +     __u32 rev_id;
> +     __u32 sub_dev_id;
> +     __u32 sub_ved_id;
> +};
> +
>   #define AMDGPU_VRAM_TYPE_UNKNOWN 0
>   #define AMDGPU_VRAM_TYPE_GDDR1 1
>   #define AMDGPU_VRAM_TYPE_DDR2  2
> --
> 2.17.1

[-- Attachment #1.2: Type: text/html, Size: 36893 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-05-18  2:44       ` Nieto, David M
@ 2021-05-18  3:07         ` Gu, JiaWei (Will)
  2021-05-18  4:40           ` Nieto, David M
  0 siblings, 1 reply; 47+ messages in thread
From: Gu, JiaWei (Will) @ 2021-05-18  3:07 UTC (permalink / raw)
  To: Nieto, David M, Koenig, Christian, amd-gfx, maraeo, Deucher, Alexander
  Cc: Deng, Emily


[-- Attachment #1.1: Type: text/plain, Size: 17620 bytes --]

[AMD Official Use Only - Internal Distribution Only]

OK let's remove serial.

dbdf comes from this:
vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);

I think we can remove dbdf as well.

Best regards,
Jiawei

From: Nieto, David M <David.Nieto@amd.com>
Sent: Tuesday, May 18, 2021 10:45 AM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com>; Koenig, Christian <Christian.Koenig@amd.com>; amd-gfx@lists.freedesktop.org; maraeo@gmail.com; Deucher, Alexander <Alexander.Deucher@amd.com>
Cc: Deng, Emily <Emily.Deng@amd.com>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface


[AMD Official Use Only - Internal Distribution Only]

The serial number is ASIC information, not VBIOS information, and it is still available as a sysfs node... I don't think we should put it there.

Not sure what dbdf stands for.
________________________________
From: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>
Sent: Monday, May 17, 2021 7:11 PM
To: Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>>; Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; maraeo@gmail.com<mailto:maraeo@gmail.com> <maraeo@gmail.com<mailto:maraeo@gmail.com>>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface

[AMD Official Use Only - Internal Distribution Only]

So I guess the dbdf is also needed to be removed?
And how about serial?

> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf; // do we need this?
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial; // do we need this?
> +};

Best regards,
Jiawei

-----Original Message-----
From: Koenig, Christian <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>
Sent: Monday, May 17, 2021 8:26 PM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>; Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; maraeo@gmail.com<mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

I'm not very familiar with the technical background why we have the fields here once more.

But of hand we should at least remove everything which is also available from the PCI information.

E.g. dev_id, rev_id, sub_dev_id, sub_ved_id.

Regards,
Christian.

Am 17.05.21 um 14:17 schrieb Gu, JiaWei (Will):
> [AMD Official Use Only - Internal Distribution Only]
>
> Hi all,
>
> Thanks Christian's suggestion.
> I reverted the previous patches and squash them into this single one.
>
> As this patch shows, the current uapi change looks like this:
>
> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf;
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial;
> +     __u32 dev_id;
> +     __u32 rev_id;
> +     __u32 sub_dev_id;
> +     __u32 sub_ved_id;
> +};
>
> As we know there's some redundant info in this struct.
> Please feel free to give any comments or suggestion about what it should & shouldn't include.
>
> Best regards,
> Jiawei
>
> -----Original Message-----
> From: Jiawei Gu <Jiawei.Gu@amd.com<mailto:Jiawei.Gu@amd.com>>
> Sent: Monday, May 17, 2021 8:08 PM
> To: amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>; Koenig, Christian
> <Christian.Koenig@amd.com<mailto:Christian.Koenig@amd.com>>; Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>;
> maraeo@gmail.com<mailto:maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>
> Cc: Deng, Emily <Emily.Deng@amd.com<mailto:Emily.Deng@amd.com>>; Gu, JiaWei (Will)
> <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>
> Subject: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.
>
> Provides a way for the user application to get the VBIOS information without having to parse the binary.
> It is useful for the user to be able to display in a simple way the VBIOS version in their system if they happen to encounter an issue.
>
> V2:
> Use numeric serial.
> Parse and expose vbios version string.
>
> Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com<mailto:Jiawei.Gu@amd.com>>
> Acked-by: Christian König <christian.koenig@amd.com<mailto:christian.koenig@amd.com>>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  21 +++
>   drivers/gpu/drm/amd/amdgpu/atom.c          | 174 +++++++++++++++++++++
>   drivers/gpu/drm/amd/amdgpu/atom.h          |  12 ++
>   drivers/gpu/drm/amd/include/atomfirmware.h |   5 +
>   include/uapi/drm/amdgpu_drm.h              |  16 ++
>   5 files changed, 228 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index 8d12e474745a..30e4fed3de22 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -861,6 +861,27 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
>                                            min((size_t)size, (size_t)(bios_size - bios_offset)))
>                                        ? -EFAULT : 0;
>                }
> +             case AMDGPU_INFO_VBIOS_INFO: {
> +                     struct drm_amdgpu_info_vbios vbios_info = {};
> +                     struct atom_context *atom_context;
> +
> +                     atom_context = adev->mode_info.atom_context;
> +                     memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
> +                     vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
> +                     memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
> +                     vbios_info.version = atom_context->version;
> +                     memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str,
> +                                             sizeof(atom_context->vbios_ver_str));
> +                     memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
> +                     vbios_info.serial = adev->unique_id;
> +                     vbios_info.dev_id = adev->pdev->device;
> +                     vbios_info.rev_id = adev->pdev->revision;
> +                     vbios_info.sub_dev_id = atom_context->sub_dev_id;
> +                     vbios_info.sub_ved_id = atom_context->sub_ved_id;
> +
> +                     return copy_to_user(out, &vbios_info,
> +                                             min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
> +             }
>                default:
>                        DRM_DEBUG_KMS("Invalid request %d\n",
>                                        info->vbios_info.type);
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c
> b/drivers/gpu/drm/amd/amdgpu/atom.c
> index 3dcb8b32f48b..542b2c2414e4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.c
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
> @@ -31,6 +31,7 @@
>
>   #define ATOM_DEBUG
>
> +#include "atomfirmware.h"
>   #include "atom.h"
>   #include "atom-names.h"
>   #include "atom-bits.h"
> @@ -1299,12 +1300,168 @@ static void atom_index_iio(struct atom_context *ctx, int base)
>        }
>   }
>
> +static void atom_get_vbios_name(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned char str_num;
> +     unsigned short off_to_vbios_str;
> +     unsigned char *c_ptr;
> +     int name_size;
> +     int i;
> +
> +     const char *na = "--N/A--";
> +     char *back;
> +
> +     p_rom = ctx->bios;
> +
> +     str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
> +     if (str_num != 0) {
> +             off_to_vbios_str =
> +                     *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +             c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
> +     } else {
> +             /* do not know where to find name */
> +             memcpy(ctx->name, na, 7);
> +             ctx->name[7] = 0;
> +             return;
> +     }
> +
> +     /*
> +      * skip the atombios strings, usually 4
> +      * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
> +      */
> +     for (i = 0; i < str_num; i++) {
> +             while (*c_ptr != 0)
> +                     c_ptr++;
> +             c_ptr++;
> +     }
> +
> +     /* skip the following 2 chars: 0x0D 0x0A */
> +     c_ptr += 2;
> +
> +     name_size = strnlen(c_ptr, STRLEN_LONG - 1);
> +     memcpy(ctx->name, c_ptr, name_size);
> +     back = ctx->name + name_size;
> +     while ((*--back) == ' ')
> +             ;
> +     *(back + 1) = '\0';
> +}
> +
> +static void atom_get_vbios_date(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned char *date_in_rom;
> +
> +     p_rom = ctx->bios;
> +
> +     date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
> +
> +     ctx->date[0] = '2';
> +     ctx->date[1] = '0';
> +     ctx->date[2] = date_in_rom[6];
> +     ctx->date[3] = date_in_rom[7];
> +     ctx->date[4] = '/';
> +     ctx->date[5] = date_in_rom[0];
> +     ctx->date[6] = date_in_rom[1];
> +     ctx->date[7] = '/';
> +     ctx->date[8] = date_in_rom[3];
> +     ctx->date[9] = date_in_rom[4];
> +     ctx->date[10] = ' ';
> +     ctx->date[11] = date_in_rom[9];
> +     ctx->date[12] = date_in_rom[10];
> +     ctx->date[13] = date_in_rom[11];
> +     ctx->date[14] = date_in_rom[12];
> +     ctx->date[15] = date_in_rom[13];
> +     ctx->date[16] = '\0';
> +}
> +
> +static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
> +                                        int end, int maxlen)
> +{
> +     unsigned long str_off;
> +     unsigned char *p_rom;
> +     unsigned short str_len;
> +
> +     str_off = 0;
> +     str_len = strnlen(str, maxlen);
> +     p_rom = ctx->bios;
> +
> +     for (; start <= end; ++start) {
> +             for (str_off = 0; str_off < str_len; ++str_off) {
> +                     if (str[str_off] != *(p_rom + start + str_off))
> +                             break;
> +             }
> +
> +             if (str_off == str_len || str[str_off] == 0)
> +                     return p_rom + start;
> +     }
> +     return NULL;
> +}
> +
> +static void atom_get_vbios_pn(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned short off_to_vbios_str;
> +     unsigned char *vbios_str;
> +     int count;
> +
> +     off_to_vbios_str = 0;
> +     p_rom = ctx->bios;
> +
> +     if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
> +             off_to_vbios_str =
> +                     *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +             vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
> +     } else {
> +             vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
> +     }
> +
> +     if (*vbios_str == 0) {
> +             vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
> +             if (vbios_str == NULL)
> +                     vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
> +     }
> +     if (vbios_str != NULL && *vbios_str == 0)
> +             vbios_str++;
> +
> +     if (vbios_str != NULL) {
> +             count = 0;
> +             while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
> +                    vbios_str[count] <= 'z') {
> +                     ctx->vbios_pn[count] = vbios_str[count];
> +                     count++;
> +             }
> +
> +             ctx->vbios_pn[count] = 0;
> +     }
> +}
> +
> +static void atom_get_vbios_version(struct atom_context *ctx) {
> +     unsigned char *vbios_ver;
> +
> +     /* find anchor ATOMBIOSBK-AMD */
> +     vbios_ver = atom_find_str_in_rom(ctx, BIOS_VERSION_PREFIX, 3, 1024, 64);
> +     if (vbios_ver != NULL) {
> +             /* skip ATOMBIOSBK-AMD VER */
> +             vbios_ver += 18;
> +             memcpy(ctx->vbios_ver_str, vbios_ver, STRLEN_NORMAL);
> +     } else {
> +             ctx->vbios_ver_str[0] = '\0';
> +     }
> +}
> +
>   struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)  {
>        int base;
>        struct atom_context *ctx =
>            kzalloc(sizeof(struct atom_context), GFP_KERNEL);
>        char *str;
> +     struct _ATOM_ROM_HEADER *atom_rom_header;
> +     struct _ATOM_MASTER_DATA_TABLE *master_table;
> +     struct _ATOM_FIRMWARE_INFO *atom_fw_info;
>        u16 idx;
>
>        if (!ctx)
> @@ -1353,6 +1510,23 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>                strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
>        }
>
> +     atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
> +     ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
> +     ctx->sub_ved_id = atom_rom_header->usSubsystemID;
> +     if (atom_rom_header->usMasterDataTableOffset != 0) {
> +             master_table = (struct _ATOM_MASTER_DATA_TABLE *)
> +                             CSTR(atom_rom_header->usMasterDataTableOffset);
> +             if (master_table->ListOfDataTables.FirmwareInfo != 0) {
> +                     atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
> +                                     CSTR(master_table->ListOfDataTables.FirmwareInfo);
> +                     ctx->version = atom_fw_info->ulFirmwareRevision;
> +             }
> +     }
> +
> +     atom_get_vbios_name(ctx);
> +     atom_get_vbios_pn(ctx);
> +     atom_get_vbios_date(ctx);
> +     atom_get_vbios_version(ctx);
>
>        return ctx;
>   }
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h
> b/drivers/gpu/drm/amd/amdgpu/atom.h
> index d279759cab47..6463ce6e756d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.h
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
> @@ -112,6 +112,10 @@ struct drm_device;
>   #define ATOM_IO_SYSIO               2
>   #define ATOM_IO_IIO         0x80
>
> +#define STRLEN_NORMAL                32
> +#define STRLEN_LONG          64
> +#define STRLEN_VERYLONG              254
> +
>   struct card_info {
>        struct drm_device *dev;
>        void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
> @@ -140,6 +144,14 @@ struct atom_context {
>        uint32_t *scratch;
>        int scratch_size_bytes;
>        char vbios_version[20];
> +
> +     uint8_t name[STRLEN_LONG];
> +     uint8_t vbios_pn[STRLEN_LONG];
> +     uint32_t version;
> +     uint8_t vbios_ver_str[STRLEN_NORMAL];
> +     uint8_t date[STRLEN_NORMAL];
> +     uint32_t sub_dev_id;
> +     uint32_t sub_ved_id;
>   };
>
>   extern int amdgpu_atom_debug;
> diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h
> b/drivers/gpu/drm/amd/include/atomfirmware.h
> index 275468e4be60..28deecc2f990 100644
> --- a/drivers/gpu/drm/amd/include/atomfirmware.h
> +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
> @@ -197,6 +197,9 @@ enum atom_dp_vs_preemph_def{
>     DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
>   };
>
> +#define BIOS_ATOM_PREFIX   "ATOMBIOS"
> +#define BIOS_VERSION_PREFIX  "ATOMBIOSBK-AMD"
> +#define BIOS_STRING_LENGTH 43
>
>   /*
>   enum atom_string_def{
> @@ -215,6 +218,8 @@ enum atombios_image_offset{
>     MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
>     OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
>     OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
> +  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
> +  OFFSET_TO_VBIOS_DATE                       = 0x50,
>   };
>
>
> /*********************************************************************
> ******* diff --git a/include/uapi/drm/amdgpu_drm.h
> b/include/uapi/drm/amdgpu_drm.h index 9169df7fadee..e0f98ca9a755
> 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -756,6 +756,8 @@ struct drm_amdgpu_cs_chunk_data {
>        #define AMDGPU_INFO_VBIOS_SIZE          0x1
>        /* Subquery id: Query vbios image */
>        #define AMDGPU_INFO_VBIOS_IMAGE         0x2
> +     /* Subquery id: Query vbios info */
> +     #define AMDGPU_INFO_VBIOS_INFO          0x3
>   /* Query UVD handles */
>   #define AMDGPU_INFO_NUM_HANDLES                     0x1C
>   /* Query sensor related information */ @@ -949,6 +951,20 @@ struct
> drm_amdgpu_info_firmware {
>        __u32 feature;
>   };
>
> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf;
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial;
> +     __u32 dev_id;
> +     __u32 rev_id;
> +     __u32 sub_dev_id;
> +     __u32 sub_ved_id;
> +};
> +
>   #define AMDGPU_VRAM_TYPE_UNKNOWN 0
>   #define AMDGPU_VRAM_TYPE_GDDR1 1
>   #define AMDGPU_VRAM_TYPE_DDR2  2
> --
> 2.17.1

[-- Attachment #1.2: Type: text/html, Size: 36417 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-05-18  2:11     ` Gu, JiaWei (Will)
@ 2021-05-18  2:44       ` Nieto, David M
  2021-05-18  3:07         ` Gu, JiaWei (Will)
  0 siblings, 1 reply; 47+ messages in thread
From: Nieto, David M @ 2021-05-18  2:44 UTC (permalink / raw)
  To: Gu, JiaWei (Will),
	Koenig, Christian, amd-gfx, maraeo, Deucher, Alexander
  Cc: Deng, Emily


[-- Attachment #1.1: Type: text/plain, Size: 16218 bytes --]

[AMD Official Use Only - Internal Distribution Only]

The serial number is ASIC information, not VBIOS information, and it is still available as a sysfs node... I don't think we should put it there.

Not sure what dbdf stands for.
________________________________
From: Gu, JiaWei (Will) <JiaWei.Gu@amd.com>
Sent: Monday, May 17, 2021 7:11 PM
To: Koenig, Christian <Christian.Koenig@amd.com>; amd-gfx@lists.freedesktop.org <amd-gfx@lists.freedesktop.org>; Nieto, David M <David.Nieto@amd.com>; maraeo@gmail.com <maraeo@gmail.com>; Deucher, Alexander <Alexander.Deucher@amd.com>
Cc: Deng, Emily <Emily.Deng@amd.com>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface

[AMD Official Use Only - Internal Distribution Only]

So I guess the dbdf is also needed to be removed?
And how about serial?

> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf; // do we need this?
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial; // do we need this?
> +};

Best regards,
Jiawei

-----Original Message-----
From: Koenig, Christian <Christian.Koenig@amd.com>
Sent: Monday, May 17, 2021 8:26 PM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com>; amd-gfx@lists.freedesktop.org; Nieto, David M <David.Nieto@amd.com>; maraeo@gmail.com; Deucher, Alexander <Alexander.Deucher@amd.com>
Cc: Deng, Emily <Emily.Deng@amd.com>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

I'm not very familiar with the technical background why we have the fields here once more.

But of hand we should at least remove everything which is also available from the PCI information.

E.g. dev_id, rev_id, sub_dev_id, sub_ved_id.

Regards,
Christian.

Am 17.05.21 um 14:17 schrieb Gu, JiaWei (Will):
> [AMD Official Use Only - Internal Distribution Only]
>
> Hi all,
>
> Thanks Christian's suggestion.
> I reverted the previous patches and squash them into this single one.
>
> As this patch shows, the current uapi change looks like this:
>
> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf;
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial;
> +     __u32 dev_id;
> +     __u32 rev_id;
> +     __u32 sub_dev_id;
> +     __u32 sub_ved_id;
> +};
>
> As we know there's some redundant info in this struct.
> Please feel free to give any comments or suggestion about what it should & shouldn't include.
>
> Best regards,
> Jiawei
>
> -----Original Message-----
> From: Jiawei Gu <Jiawei.Gu@amd.com>
> Sent: Monday, May 17, 2021 8:08 PM
> To: amd-gfx@lists.freedesktop.org; Koenig, Christian
> <Christian.Koenig@amd.com>; Nieto, David M <David.Nieto@amd.com>;
> maraeo@gmail.com; Deucher, Alexander <Alexander.Deucher@amd.com>
> Cc: Deng, Emily <Emily.Deng@amd.com>; Gu, JiaWei (Will)
> <JiaWei.Gu@amd.com>
> Subject: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.
>
> Provides a way for the user application to get the VBIOS information without having to parse the binary.
> It is useful for the user to be able to display in a simple way the VBIOS version in their system if they happen to encounter an issue.
>
> V2:
> Use numeric serial.
> Parse and expose vbios version string.
>
> Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com>
> Acked-by: Christian König <christian.koenig@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  21 +++
>   drivers/gpu/drm/amd/amdgpu/atom.c          | 174 +++++++++++++++++++++
>   drivers/gpu/drm/amd/amdgpu/atom.h          |  12 ++
>   drivers/gpu/drm/amd/include/atomfirmware.h |   5 +
>   include/uapi/drm/amdgpu_drm.h              |  16 ++
>   5 files changed, 228 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index 8d12e474745a..30e4fed3de22 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -861,6 +861,27 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
>                                            min((size_t)size, (size_t)(bios_size - bios_offset)))
>                                        ? -EFAULT : 0;
>                }
> +             case AMDGPU_INFO_VBIOS_INFO: {
> +                     struct drm_amdgpu_info_vbios vbios_info = {};
> +                     struct atom_context *atom_context;
> +
> +                     atom_context = adev->mode_info.atom_context;
> +                     memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
> +                     vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
> +                     memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
> +                     vbios_info.version = atom_context->version;
> +                     memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str,
> +                                             sizeof(atom_context->vbios_ver_str));
> +                     memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
> +                     vbios_info.serial = adev->unique_id;
> +                     vbios_info.dev_id = adev->pdev->device;
> +                     vbios_info.rev_id = adev->pdev->revision;
> +                     vbios_info.sub_dev_id = atom_context->sub_dev_id;
> +                     vbios_info.sub_ved_id = atom_context->sub_ved_id;
> +
> +                     return copy_to_user(out, &vbios_info,
> +                                             min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
> +             }
>                default:
>                        DRM_DEBUG_KMS("Invalid request %d\n",
>                                        info->vbios_info.type);
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c
> b/drivers/gpu/drm/amd/amdgpu/atom.c
> index 3dcb8b32f48b..542b2c2414e4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.c
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
> @@ -31,6 +31,7 @@
>
>   #define ATOM_DEBUG
>
> +#include "atomfirmware.h"
>   #include "atom.h"
>   #include "atom-names.h"
>   #include "atom-bits.h"
> @@ -1299,12 +1300,168 @@ static void atom_index_iio(struct atom_context *ctx, int base)
>        }
>   }
>
> +static void atom_get_vbios_name(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned char str_num;
> +     unsigned short off_to_vbios_str;
> +     unsigned char *c_ptr;
> +     int name_size;
> +     int i;
> +
> +     const char *na = "--N/A--";
> +     char *back;
> +
> +     p_rom = ctx->bios;
> +
> +     str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
> +     if (str_num != 0) {
> +             off_to_vbios_str =
> +                     *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +             c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
> +     } else {
> +             /* do not know where to find name */
> +             memcpy(ctx->name, na, 7);
> +             ctx->name[7] = 0;
> +             return;
> +     }
> +
> +     /*
> +      * skip the atombios strings, usually 4
> +      * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
> +      */
> +     for (i = 0; i < str_num; i++) {
> +             while (*c_ptr != 0)
> +                     c_ptr++;
> +             c_ptr++;
> +     }
> +
> +     /* skip the following 2 chars: 0x0D 0x0A */
> +     c_ptr += 2;
> +
> +     name_size = strnlen(c_ptr, STRLEN_LONG - 1);
> +     memcpy(ctx->name, c_ptr, name_size);
> +     back = ctx->name + name_size;
> +     while ((*--back) == ' ')
> +             ;
> +     *(back + 1) = '\0';
> +}
> +
> +static void atom_get_vbios_date(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned char *date_in_rom;
> +
> +     p_rom = ctx->bios;
> +
> +     date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
> +
> +     ctx->date[0] = '2';
> +     ctx->date[1] = '0';
> +     ctx->date[2] = date_in_rom[6];
> +     ctx->date[3] = date_in_rom[7];
> +     ctx->date[4] = '/';
> +     ctx->date[5] = date_in_rom[0];
> +     ctx->date[6] = date_in_rom[1];
> +     ctx->date[7] = '/';
> +     ctx->date[8] = date_in_rom[3];
> +     ctx->date[9] = date_in_rom[4];
> +     ctx->date[10] = ' ';
> +     ctx->date[11] = date_in_rom[9];
> +     ctx->date[12] = date_in_rom[10];
> +     ctx->date[13] = date_in_rom[11];
> +     ctx->date[14] = date_in_rom[12];
> +     ctx->date[15] = date_in_rom[13];
> +     ctx->date[16] = '\0';
> +}
> +
> +static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
> +                                        int end, int maxlen)
> +{
> +     unsigned long str_off;
> +     unsigned char *p_rom;
> +     unsigned short str_len;
> +
> +     str_off = 0;
> +     str_len = strnlen(str, maxlen);
> +     p_rom = ctx->bios;
> +
> +     for (; start <= end; ++start) {
> +             for (str_off = 0; str_off < str_len; ++str_off) {
> +                     if (str[str_off] != *(p_rom + start + str_off))
> +                             break;
> +             }
> +
> +             if (str_off == str_len || str[str_off] == 0)
> +                     return p_rom + start;
> +     }
> +     return NULL;
> +}
> +
> +static void atom_get_vbios_pn(struct atom_context *ctx) {
> +     unsigned char *p_rom;
> +     unsigned short off_to_vbios_str;
> +     unsigned char *vbios_str;
> +     int count;
> +
> +     off_to_vbios_str = 0;
> +     p_rom = ctx->bios;
> +
> +     if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
> +             off_to_vbios_str =
> +                     *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +             vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
> +     } else {
> +             vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
> +     }
> +
> +     if (*vbios_str == 0) {
> +             vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
> +             if (vbios_str == NULL)
> +                     vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
> +     }
> +     if (vbios_str != NULL && *vbios_str == 0)
> +             vbios_str++;
> +
> +     if (vbios_str != NULL) {
> +             count = 0;
> +             while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
> +                    vbios_str[count] <= 'z') {
> +                     ctx->vbios_pn[count] = vbios_str[count];
> +                     count++;
> +             }
> +
> +             ctx->vbios_pn[count] = 0;
> +     }
> +}
> +
> +static void atom_get_vbios_version(struct atom_context *ctx) {
> +     unsigned char *vbios_ver;
> +
> +     /* find anchor ATOMBIOSBK-AMD */
> +     vbios_ver = atom_find_str_in_rom(ctx, BIOS_VERSION_PREFIX, 3, 1024, 64);
> +     if (vbios_ver != NULL) {
> +             /* skip ATOMBIOSBK-AMD VER */
> +             vbios_ver += 18;
> +             memcpy(ctx->vbios_ver_str, vbios_ver, STRLEN_NORMAL);
> +     } else {
> +             ctx->vbios_ver_str[0] = '\0';
> +     }
> +}
> +
>   struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)  {
>        int base;
>        struct atom_context *ctx =
>            kzalloc(sizeof(struct atom_context), GFP_KERNEL);
>        char *str;
> +     struct _ATOM_ROM_HEADER *atom_rom_header;
> +     struct _ATOM_MASTER_DATA_TABLE *master_table;
> +     struct _ATOM_FIRMWARE_INFO *atom_fw_info;
>        u16 idx;
>
>        if (!ctx)
> @@ -1353,6 +1510,23 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>                strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
>        }
>
> +     atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
> +     ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
> +     ctx->sub_ved_id = atom_rom_header->usSubsystemID;
> +     if (atom_rom_header->usMasterDataTableOffset != 0) {
> +             master_table = (struct _ATOM_MASTER_DATA_TABLE *)
> +                             CSTR(atom_rom_header->usMasterDataTableOffset);
> +             if (master_table->ListOfDataTables.FirmwareInfo != 0) {
> +                     atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
> +                                     CSTR(master_table->ListOfDataTables.FirmwareInfo);
> +                     ctx->version = atom_fw_info->ulFirmwareRevision;
> +             }
> +     }
> +
> +     atom_get_vbios_name(ctx);
> +     atom_get_vbios_pn(ctx);
> +     atom_get_vbios_date(ctx);
> +     atom_get_vbios_version(ctx);
>
>        return ctx;
>   }
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h
> b/drivers/gpu/drm/amd/amdgpu/atom.h
> index d279759cab47..6463ce6e756d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.h
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
> @@ -112,6 +112,10 @@ struct drm_device;
>   #define ATOM_IO_SYSIO               2
>   #define ATOM_IO_IIO         0x80
>
> +#define STRLEN_NORMAL                32
> +#define STRLEN_LONG          64
> +#define STRLEN_VERYLONG              254
> +
>   struct card_info {
>        struct drm_device *dev;
>        void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
> @@ -140,6 +144,14 @@ struct atom_context {
>        uint32_t *scratch;
>        int scratch_size_bytes;
>        char vbios_version[20];
> +
> +     uint8_t name[STRLEN_LONG];
> +     uint8_t vbios_pn[STRLEN_LONG];
> +     uint32_t version;
> +     uint8_t vbios_ver_str[STRLEN_NORMAL];
> +     uint8_t date[STRLEN_NORMAL];
> +     uint32_t sub_dev_id;
> +     uint32_t sub_ved_id;
>   };
>
>   extern int amdgpu_atom_debug;
> diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h
> b/drivers/gpu/drm/amd/include/atomfirmware.h
> index 275468e4be60..28deecc2f990 100644
> --- a/drivers/gpu/drm/amd/include/atomfirmware.h
> +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
> @@ -197,6 +197,9 @@ enum atom_dp_vs_preemph_def{
>     DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
>   };
>
> +#define BIOS_ATOM_PREFIX   "ATOMBIOS"
> +#define BIOS_VERSION_PREFIX  "ATOMBIOSBK-AMD"
> +#define BIOS_STRING_LENGTH 43
>
>   /*
>   enum atom_string_def{
> @@ -215,6 +218,8 @@ enum atombios_image_offset{
>     MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
>     OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
>     OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
> +  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
> +  OFFSET_TO_VBIOS_DATE                       = 0x50,
>   };
>
>
> /*********************************************************************
> ******* diff --git a/include/uapi/drm/amdgpu_drm.h
> b/include/uapi/drm/amdgpu_drm.h index 9169df7fadee..e0f98ca9a755
> 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -756,6 +756,8 @@ struct drm_amdgpu_cs_chunk_data {
>        #define AMDGPU_INFO_VBIOS_SIZE          0x1
>        /* Subquery id: Query vbios image */
>        #define AMDGPU_INFO_VBIOS_IMAGE         0x2
> +     /* Subquery id: Query vbios info */
> +     #define AMDGPU_INFO_VBIOS_INFO          0x3
>   /* Query UVD handles */
>   #define AMDGPU_INFO_NUM_HANDLES                     0x1C
>   /* Query sensor related information */ @@ -949,6 +951,20 @@ struct
> drm_amdgpu_info_firmware {
>        __u32 feature;
>   };
>
> +struct drm_amdgpu_info_vbios {
> +     __u8 name[64];
> +     __u32 dbdf;
> +     __u8 vbios_pn[64];
> +     __u32 version;
> +     __u8 vbios_ver_str[32];
> +     __u8 date[32];
> +     __u64 serial;
> +     __u32 dev_id;
> +     __u32 rev_id;
> +     __u32 sub_dev_id;
> +     __u32 sub_ved_id;
> +};
> +
>   #define AMDGPU_VRAM_TYPE_UNKNOWN 0
>   #define AMDGPU_VRAM_TYPE_GDDR1 1
>   #define AMDGPU_VRAM_TYPE_DDR2  2
> --
> 2.17.1

[-- Attachment #1.2: Type: text/html, Size: 31950 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-05-17 12:25   ` Christian König
@ 2021-05-18  2:11     ` Gu, JiaWei (Will)
  2021-05-18  2:44       ` Nieto, David M
  0 siblings, 1 reply; 47+ messages in thread
From: Gu, JiaWei (Will) @ 2021-05-18  2:11 UTC (permalink / raw)
  To: Koenig, Christian, amd-gfx, Nieto, David M, maraeo, Deucher, Alexander
  Cc: Deng, Emily

[AMD Official Use Only - Internal Distribution Only]

So I guess the dbdf is also needed to be removed?
And how about serial?

> +struct drm_amdgpu_info_vbios {
> +	__u8 name[64];
> +	__u32 dbdf; // do we need this?
> +	__u8 vbios_pn[64];
> +	__u32 version;
> +	__u8 vbios_ver_str[32];
> +	__u8 date[32];
> +	__u64 serial; // do we need this?
> +};

Best regards,
Jiawei

-----Original Message-----
From: Koenig, Christian <Christian.Koenig@amd.com> 
Sent: Monday, May 17, 2021 8:26 PM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com>; amd-gfx@lists.freedesktop.org; Nieto, David M <David.Nieto@amd.com>; maraeo@gmail.com; Deucher, Alexander <Alexander.Deucher@amd.com>
Cc: Deng, Emily <Emily.Deng@amd.com>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

I'm not very familiar with the technical background why we have the fields here once more.

But of hand we should at least remove everything which is also available from the PCI information.

E.g. dev_id, rev_id, sub_dev_id, sub_ved_id.

Regards,
Christian.

Am 17.05.21 um 14:17 schrieb Gu, JiaWei (Will):
> [AMD Official Use Only - Internal Distribution Only]
>
> Hi all,
>
> Thanks Christian's suggestion.
> I reverted the previous patches and squash them into this single one.
>
> As this patch shows, the current uapi change looks like this:
>
> +struct drm_amdgpu_info_vbios {
> +	__u8 name[64];
> +	__u32 dbdf;
> +	__u8 vbios_pn[64];
> +	__u32 version;
> +	__u8 vbios_ver_str[32];
> +	__u8 date[32];
> +	__u64 serial;
> +	__u32 dev_id;
> +	__u32 rev_id;
> +	__u32 sub_dev_id;
> +	__u32 sub_ved_id;
> +};
>
> As we know there's some redundant info in this struct.
> Please feel free to give any comments or suggestion about what it should & shouldn't include.
>
> Best regards,
> Jiawei
>
> -----Original Message-----
> From: Jiawei Gu <Jiawei.Gu@amd.com>
> Sent: Monday, May 17, 2021 8:08 PM
> To: amd-gfx@lists.freedesktop.org; Koenig, Christian 
> <Christian.Koenig@amd.com>; Nieto, David M <David.Nieto@amd.com>; 
> maraeo@gmail.com; Deucher, Alexander <Alexander.Deucher@amd.com>
> Cc: Deng, Emily <Emily.Deng@amd.com>; Gu, JiaWei (Will) 
> <JiaWei.Gu@amd.com>
> Subject: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.
>
> Provides a way for the user application to get the VBIOS information without having to parse the binary.
> It is useful for the user to be able to display in a simple way the VBIOS version in their system if they happen to encounter an issue.
>
> V2:
> Use numeric serial.
> Parse and expose vbios version string.
>
> Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com>
> Acked-by: Christian König <christian.koenig@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  21 +++
>   drivers/gpu/drm/amd/amdgpu/atom.c          | 174 +++++++++++++++++++++
>   drivers/gpu/drm/amd/amdgpu/atom.h          |  12 ++
>   drivers/gpu/drm/amd/include/atomfirmware.h |   5 +
>   include/uapi/drm/amdgpu_drm.h              |  16 ++
>   5 files changed, 228 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index 8d12e474745a..30e4fed3de22 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -861,6 +861,27 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
>   					    min((size_t)size, (size_t)(bios_size - bios_offset)))
>   					? -EFAULT : 0;
>   		}
> +		case AMDGPU_INFO_VBIOS_INFO: {
> +			struct drm_amdgpu_info_vbios vbios_info = {};
> +			struct atom_context *atom_context;
> +
> +			atom_context = adev->mode_info.atom_context;
> +			memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
> +			vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
> +			memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
> +			vbios_info.version = atom_context->version;
> +			memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str,
> +						sizeof(atom_context->vbios_ver_str));
> +			memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
> +			vbios_info.serial = adev->unique_id;
> +			vbios_info.dev_id = adev->pdev->device;
> +			vbios_info.rev_id = adev->pdev->revision;
> +			vbios_info.sub_dev_id = atom_context->sub_dev_id;
> +			vbios_info.sub_ved_id = atom_context->sub_ved_id;
> +
> +			return copy_to_user(out, &vbios_info,
> +						min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
> +		}
>   		default:
>   			DRM_DEBUG_KMS("Invalid request %d\n",
>   					info->vbios_info.type);
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c 
> b/drivers/gpu/drm/amd/amdgpu/atom.c
> index 3dcb8b32f48b..542b2c2414e4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.c
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
> @@ -31,6 +31,7 @@
>   
>   #define ATOM_DEBUG
>   
> +#include "atomfirmware.h"
>   #include "atom.h"
>   #include "atom-names.h"
>   #include "atom-bits.h"
> @@ -1299,12 +1300,168 @@ static void atom_index_iio(struct atom_context *ctx, int base)
>   	}
>   }
>   
> +static void atom_get_vbios_name(struct atom_context *ctx) {
> +	unsigned char *p_rom;
> +	unsigned char str_num;
> +	unsigned short off_to_vbios_str;
> +	unsigned char *c_ptr;
> +	int name_size;
> +	int i;
> +
> +	const char *na = "--N/A--";
> +	char *back;
> +
> +	p_rom = ctx->bios;
> +
> +	str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
> +	if (str_num != 0) {
> +		off_to_vbios_str =
> +			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +		c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
> +	} else {
> +		/* do not know where to find name */
> +		memcpy(ctx->name, na, 7);
> +		ctx->name[7] = 0;
> +		return;
> +	}
> +
> +	/*
> +	 * skip the atombios strings, usually 4
> +	 * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
> +	 */
> +	for (i = 0; i < str_num; i++) {
> +		while (*c_ptr != 0)
> +			c_ptr++;
> +		c_ptr++;
> +	}
> +
> +	/* skip the following 2 chars: 0x0D 0x0A */
> +	c_ptr += 2;
> +
> +	name_size = strnlen(c_ptr, STRLEN_LONG - 1);
> +	memcpy(ctx->name, c_ptr, name_size);
> +	back = ctx->name + name_size;
> +	while ((*--back) == ' ')
> +		;
> +	*(back + 1) = '\0';
> +}
> +
> +static void atom_get_vbios_date(struct atom_context *ctx) {
> +	unsigned char *p_rom;
> +	unsigned char *date_in_rom;
> +
> +	p_rom = ctx->bios;
> +
> +	date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
> +
> +	ctx->date[0] = '2';
> +	ctx->date[1] = '0';
> +	ctx->date[2] = date_in_rom[6];
> +	ctx->date[3] = date_in_rom[7];
> +	ctx->date[4] = '/';
> +	ctx->date[5] = date_in_rom[0];
> +	ctx->date[6] = date_in_rom[1];
> +	ctx->date[7] = '/';
> +	ctx->date[8] = date_in_rom[3];
> +	ctx->date[9] = date_in_rom[4];
> +	ctx->date[10] = ' ';
> +	ctx->date[11] = date_in_rom[9];
> +	ctx->date[12] = date_in_rom[10];
> +	ctx->date[13] = date_in_rom[11];
> +	ctx->date[14] = date_in_rom[12];
> +	ctx->date[15] = date_in_rom[13];
> +	ctx->date[16] = '\0';
> +}
> +
> +static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
> +					   int end, int maxlen)
> +{
> +	unsigned long str_off;
> +	unsigned char *p_rom;
> +	unsigned short str_len;
> +
> +	str_off = 0;
> +	str_len = strnlen(str, maxlen);
> +	p_rom = ctx->bios;
> +
> +	for (; start <= end; ++start) {
> +		for (str_off = 0; str_off < str_len; ++str_off) {
> +			if (str[str_off] != *(p_rom + start + str_off))
> +				break;
> +		}
> +
> +		if (str_off == str_len || str[str_off] == 0)
> +			return p_rom + start;
> +	}
> +	return NULL;
> +}
> +
> +static void atom_get_vbios_pn(struct atom_context *ctx) {
> +	unsigned char *p_rom;
> +	unsigned short off_to_vbios_str;
> +	unsigned char *vbios_str;
> +	int count;
> +
> +	off_to_vbios_str = 0;
> +	p_rom = ctx->bios;
> +
> +	if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
> +		off_to_vbios_str =
> +			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +		vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
> +	} else {
> +		vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
> +	}
> +
> +	if (*vbios_str == 0) {
> +		vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
> +		if (vbios_str == NULL)
> +			vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
> +	}
> +	if (vbios_str != NULL && *vbios_str == 0)
> +		vbios_str++;
> +
> +	if (vbios_str != NULL) {
> +		count = 0;
> +		while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
> +		       vbios_str[count] <= 'z') {
> +			ctx->vbios_pn[count] = vbios_str[count];
> +			count++;
> +		}
> +
> +		ctx->vbios_pn[count] = 0;
> +	}
> +}
> +
> +static void atom_get_vbios_version(struct atom_context *ctx) {
> +	unsigned char *vbios_ver;
> +
> +	/* find anchor ATOMBIOSBK-AMD */
> +	vbios_ver = atom_find_str_in_rom(ctx, BIOS_VERSION_PREFIX, 3, 1024, 64);
> +	if (vbios_ver != NULL) {
> +		/* skip ATOMBIOSBK-AMD VER */
> +		vbios_ver += 18;
> +		memcpy(ctx->vbios_ver_str, vbios_ver, STRLEN_NORMAL);
> +	} else {
> +		ctx->vbios_ver_str[0] = '\0';
> +	}
> +}
> +
>   struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)  {
>   	int base;
>   	struct atom_context *ctx =
>   	    kzalloc(sizeof(struct atom_context), GFP_KERNEL);
>   	char *str;
> +	struct _ATOM_ROM_HEADER *atom_rom_header;
> +	struct _ATOM_MASTER_DATA_TABLE *master_table;
> +	struct _ATOM_FIRMWARE_INFO *atom_fw_info;
>   	u16 idx;
>   
>   	if (!ctx)
> @@ -1353,6 +1510,23 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>   		strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
>   	}
>   
> +	atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
> +	ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
> +	ctx->sub_ved_id = atom_rom_header->usSubsystemID;
> +	if (atom_rom_header->usMasterDataTableOffset != 0) {
> +		master_table = (struct _ATOM_MASTER_DATA_TABLE *)
> +				CSTR(atom_rom_header->usMasterDataTableOffset);
> +		if (master_table->ListOfDataTables.FirmwareInfo != 0) {
> +			atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
> +					CSTR(master_table->ListOfDataTables.FirmwareInfo);
> +			ctx->version = atom_fw_info->ulFirmwareRevision;
> +		}
> +	}
> +
> +	atom_get_vbios_name(ctx);
> +	atom_get_vbios_pn(ctx);
> +	atom_get_vbios_date(ctx);
> +	atom_get_vbios_version(ctx);
>   
>   	return ctx;
>   }
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h 
> b/drivers/gpu/drm/amd/amdgpu/atom.h
> index d279759cab47..6463ce6e756d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.h
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
> @@ -112,6 +112,10 @@ struct drm_device;
>   #define ATOM_IO_SYSIO		2
>   #define ATOM_IO_IIO		0x80
>   
> +#define STRLEN_NORMAL		32
> +#define STRLEN_LONG		64
> +#define STRLEN_VERYLONG		254
> +
>   struct card_info {
>   	struct drm_device *dev;
>   	void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
> @@ -140,6 +144,14 @@ struct atom_context {
>   	uint32_t *scratch;
>   	int scratch_size_bytes;
>   	char vbios_version[20];
> +
> +	uint8_t name[STRLEN_LONG];
> +	uint8_t vbios_pn[STRLEN_LONG];
> +	uint32_t version;
> +	uint8_t vbios_ver_str[STRLEN_NORMAL];
> +	uint8_t date[STRLEN_NORMAL];
> +	uint32_t sub_dev_id;
> +	uint32_t sub_ved_id;
>   };
>   
>   extern int amdgpu_atom_debug;
> diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h 
> b/drivers/gpu/drm/amd/include/atomfirmware.h
> index 275468e4be60..28deecc2f990 100644
> --- a/drivers/gpu/drm/amd/include/atomfirmware.h
> +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
> @@ -197,6 +197,9 @@ enum atom_dp_vs_preemph_def{
>     DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
>   };
>   
> +#define BIOS_ATOM_PREFIX   "ATOMBIOS"
> +#define BIOS_VERSION_PREFIX  "ATOMBIOSBK-AMD"
> +#define BIOS_STRING_LENGTH 43
>   
>   /*
>   enum atom_string_def{
> @@ -215,6 +218,8 @@ enum atombios_image_offset{
>     MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
>     OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
>     OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
> +  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
> +  OFFSET_TO_VBIOS_DATE                       = 0x50,
>   };
>   
>   
> /*********************************************************************
> ******* diff --git a/include/uapi/drm/amdgpu_drm.h 
> b/include/uapi/drm/amdgpu_drm.h index 9169df7fadee..e0f98ca9a755 
> 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -756,6 +756,8 @@ struct drm_amdgpu_cs_chunk_data {
>   	#define AMDGPU_INFO_VBIOS_SIZE		0x1
>   	/* Subquery id: Query vbios image */
>   	#define AMDGPU_INFO_VBIOS_IMAGE		0x2
> +	/* Subquery id: Query vbios info */
> +	#define AMDGPU_INFO_VBIOS_INFO		0x3
>   /* Query UVD handles */
>   #define AMDGPU_INFO_NUM_HANDLES			0x1C
>   /* Query sensor related information */ @@ -949,6 +951,20 @@ struct 
> drm_amdgpu_info_firmware {
>   	__u32 feature;
>   };
>   
> +struct drm_amdgpu_info_vbios {
> +	__u8 name[64];
> +	__u32 dbdf;
> +	__u8 vbios_pn[64];
> +	__u32 version;
> +	__u8 vbios_ver_str[32];
> +	__u8 date[32];
> +	__u64 serial;
> +	__u32 dev_id;
> +	__u32 rev_id;
> +	__u32 sub_dev_id;
> +	__u32 sub_ved_id;
> +};
> +
>   #define AMDGPU_VRAM_TYPE_UNKNOWN 0
>   #define AMDGPU_VRAM_TYPE_GDDR1 1
>   #define AMDGPU_VRAM_TYPE_DDR2  2
> --
> 2.17.1
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-05-17 12:17 ` Gu, JiaWei (Will)
@ 2021-05-17 12:25   ` Christian König
  2021-05-18  2:11     ` Gu, JiaWei (Will)
  0 siblings, 1 reply; 47+ messages in thread
From: Christian König @ 2021-05-17 12:25 UTC (permalink / raw)
  To: Gu, JiaWei (Will), amd-gfx, Nieto, David M, maraeo, Deucher, Alexander
  Cc: Deng, Emily

I'm not very familiar with the technical background why we have the 
fields here once more.

But of hand we should at least remove everything which is also available 
from the PCI information.

E.g. dev_id, rev_id, sub_dev_id, sub_ved_id.

Regards,
Christian.

Am 17.05.21 um 14:17 schrieb Gu, JiaWei (Will):
> [AMD Official Use Only - Internal Distribution Only]
>
> Hi all,
>
> Thanks Christian's suggestion.
> I reverted the previous patches and squash them into this single one.
>
> As this patch shows, the current uapi change looks like this:
>
> +struct drm_amdgpu_info_vbios {
> +	__u8 name[64];
> +	__u32 dbdf;
> +	__u8 vbios_pn[64];
> +	__u32 version;
> +	__u8 vbios_ver_str[32];
> +	__u8 date[32];
> +	__u64 serial;
> +	__u32 dev_id;
> +	__u32 rev_id;
> +	__u32 sub_dev_id;
> +	__u32 sub_ved_id;
> +};
>
> As we know there's some redundant info in this struct.
> Please feel free to give any comments or suggestion about what it should & shouldn't include.
>
> Best regards,
> Jiawei
>
> -----Original Message-----
> From: Jiawei Gu <Jiawei.Gu@amd.com>
> Sent: Monday, May 17, 2021 8:08 PM
> To: amd-gfx@lists.freedesktop.org; Koenig, Christian <Christian.Koenig@amd.com>; Nieto, David M <David.Nieto@amd.com>; maraeo@gmail.com; Deucher, Alexander <Alexander.Deucher@amd.com>
> Cc: Deng, Emily <Emily.Deng@amd.com>; Gu, JiaWei (Will) <JiaWei.Gu@amd.com>
> Subject: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.
>
> Provides a way for the user application to get the VBIOS information without having to parse the binary.
> It is useful for the user to be able to display in a simple way the VBIOS version in their system if they happen to encounter an issue.
>
> V2:
> Use numeric serial.
> Parse and expose vbios version string.
>
> Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com>
> Acked-by: Christian König <christian.koenig@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  21 +++
>   drivers/gpu/drm/amd/amdgpu/atom.c          | 174 +++++++++++++++++++++
>   drivers/gpu/drm/amd/amdgpu/atom.h          |  12 ++
>   drivers/gpu/drm/amd/include/atomfirmware.h |   5 +
>   include/uapi/drm/amdgpu_drm.h              |  16 ++
>   5 files changed, 228 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index 8d12e474745a..30e4fed3de22 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -861,6 +861,27 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
>   					    min((size_t)size, (size_t)(bios_size - bios_offset)))
>   					? -EFAULT : 0;
>   		}
> +		case AMDGPU_INFO_VBIOS_INFO: {
> +			struct drm_amdgpu_info_vbios vbios_info = {};
> +			struct atom_context *atom_context;
> +
> +			atom_context = adev->mode_info.atom_context;
> +			memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
> +			vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
> +			memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
> +			vbios_info.version = atom_context->version;
> +			memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str,
> +						sizeof(atom_context->vbios_ver_str));
> +			memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
> +			vbios_info.serial = adev->unique_id;
> +			vbios_info.dev_id = adev->pdev->device;
> +			vbios_info.rev_id = adev->pdev->revision;
> +			vbios_info.sub_dev_id = atom_context->sub_dev_id;
> +			vbios_info.sub_ved_id = atom_context->sub_ved_id;
> +
> +			return copy_to_user(out, &vbios_info,
> +						min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
> +		}
>   		default:
>   			DRM_DEBUG_KMS("Invalid request %d\n",
>   					info->vbios_info.type);
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c
> index 3dcb8b32f48b..542b2c2414e4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.c
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
> @@ -31,6 +31,7 @@
>   
>   #define ATOM_DEBUG
>   
> +#include "atomfirmware.h"
>   #include "atom.h"
>   #include "atom-names.h"
>   #include "atom-bits.h"
> @@ -1299,12 +1300,168 @@ static void atom_index_iio(struct atom_context *ctx, int base)
>   	}
>   }
>   
> +static void atom_get_vbios_name(struct atom_context *ctx) {
> +	unsigned char *p_rom;
> +	unsigned char str_num;
> +	unsigned short off_to_vbios_str;
> +	unsigned char *c_ptr;
> +	int name_size;
> +	int i;
> +
> +	const char *na = "--N/A--";
> +	char *back;
> +
> +	p_rom = ctx->bios;
> +
> +	str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
> +	if (str_num != 0) {
> +		off_to_vbios_str =
> +			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +		c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
> +	} else {
> +		/* do not know where to find name */
> +		memcpy(ctx->name, na, 7);
> +		ctx->name[7] = 0;
> +		return;
> +	}
> +
> +	/*
> +	 * skip the atombios strings, usually 4
> +	 * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
> +	 */
> +	for (i = 0; i < str_num; i++) {
> +		while (*c_ptr != 0)
> +			c_ptr++;
> +		c_ptr++;
> +	}
> +
> +	/* skip the following 2 chars: 0x0D 0x0A */
> +	c_ptr += 2;
> +
> +	name_size = strnlen(c_ptr, STRLEN_LONG - 1);
> +	memcpy(ctx->name, c_ptr, name_size);
> +	back = ctx->name + name_size;
> +	while ((*--back) == ' ')
> +		;
> +	*(back + 1) = '\0';
> +}
> +
> +static void atom_get_vbios_date(struct atom_context *ctx) {
> +	unsigned char *p_rom;
> +	unsigned char *date_in_rom;
> +
> +	p_rom = ctx->bios;
> +
> +	date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
> +
> +	ctx->date[0] = '2';
> +	ctx->date[1] = '0';
> +	ctx->date[2] = date_in_rom[6];
> +	ctx->date[3] = date_in_rom[7];
> +	ctx->date[4] = '/';
> +	ctx->date[5] = date_in_rom[0];
> +	ctx->date[6] = date_in_rom[1];
> +	ctx->date[7] = '/';
> +	ctx->date[8] = date_in_rom[3];
> +	ctx->date[9] = date_in_rom[4];
> +	ctx->date[10] = ' ';
> +	ctx->date[11] = date_in_rom[9];
> +	ctx->date[12] = date_in_rom[10];
> +	ctx->date[13] = date_in_rom[11];
> +	ctx->date[14] = date_in_rom[12];
> +	ctx->date[15] = date_in_rom[13];
> +	ctx->date[16] = '\0';
> +}
> +
> +static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
> +					   int end, int maxlen)
> +{
> +	unsigned long str_off;
> +	unsigned char *p_rom;
> +	unsigned short str_len;
> +
> +	str_off = 0;
> +	str_len = strnlen(str, maxlen);
> +	p_rom = ctx->bios;
> +
> +	for (; start <= end; ++start) {
> +		for (str_off = 0; str_off < str_len; ++str_off) {
> +			if (str[str_off] != *(p_rom + start + str_off))
> +				break;
> +		}
> +
> +		if (str_off == str_len || str[str_off] == 0)
> +			return p_rom + start;
> +	}
> +	return NULL;
> +}
> +
> +static void atom_get_vbios_pn(struct atom_context *ctx) {
> +	unsigned char *p_rom;
> +	unsigned short off_to_vbios_str;
> +	unsigned char *vbios_str;
> +	int count;
> +
> +	off_to_vbios_str = 0;
> +	p_rom = ctx->bios;
> +
> +	if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
> +		off_to_vbios_str =
> +			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +		vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
> +	} else {
> +		vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
> +	}
> +
> +	if (*vbios_str == 0) {
> +		vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
> +		if (vbios_str == NULL)
> +			vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
> +	}
> +	if (vbios_str != NULL && *vbios_str == 0)
> +		vbios_str++;
> +
> +	if (vbios_str != NULL) {
> +		count = 0;
> +		while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
> +		       vbios_str[count] <= 'z') {
> +			ctx->vbios_pn[count] = vbios_str[count];
> +			count++;
> +		}
> +
> +		ctx->vbios_pn[count] = 0;
> +	}
> +}
> +
> +static void atom_get_vbios_version(struct atom_context *ctx) {
> +	unsigned char *vbios_ver;
> +
> +	/* find anchor ATOMBIOSBK-AMD */
> +	vbios_ver = atom_find_str_in_rom(ctx, BIOS_VERSION_PREFIX, 3, 1024, 64);
> +	if (vbios_ver != NULL) {
> +		/* skip ATOMBIOSBK-AMD VER */
> +		vbios_ver += 18;
> +		memcpy(ctx->vbios_ver_str, vbios_ver, STRLEN_NORMAL);
> +	} else {
> +		ctx->vbios_ver_str[0] = '\0';
> +	}
> +}
> +
>   struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)  {
>   	int base;
>   	struct atom_context *ctx =
>   	    kzalloc(sizeof(struct atom_context), GFP_KERNEL);
>   	char *str;
> +	struct _ATOM_ROM_HEADER *atom_rom_header;
> +	struct _ATOM_MASTER_DATA_TABLE *master_table;
> +	struct _ATOM_FIRMWARE_INFO *atom_fw_info;
>   	u16 idx;
>   
>   	if (!ctx)
> @@ -1353,6 +1510,23 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>   		strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
>   	}
>   
> +	atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
> +	ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
> +	ctx->sub_ved_id = atom_rom_header->usSubsystemID;
> +	if (atom_rom_header->usMasterDataTableOffset != 0) {
> +		master_table = (struct _ATOM_MASTER_DATA_TABLE *)
> +				CSTR(atom_rom_header->usMasterDataTableOffset);
> +		if (master_table->ListOfDataTables.FirmwareInfo != 0) {
> +			atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
> +					CSTR(master_table->ListOfDataTables.FirmwareInfo);
> +			ctx->version = atom_fw_info->ulFirmwareRevision;
> +		}
> +	}
> +
> +	atom_get_vbios_name(ctx);
> +	atom_get_vbios_pn(ctx);
> +	atom_get_vbios_date(ctx);
> +	atom_get_vbios_version(ctx);
>   
>   	return ctx;
>   }
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h
> index d279759cab47..6463ce6e756d 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.h
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
> @@ -112,6 +112,10 @@ struct drm_device;
>   #define ATOM_IO_SYSIO		2
>   #define ATOM_IO_IIO		0x80
>   
> +#define STRLEN_NORMAL		32
> +#define STRLEN_LONG		64
> +#define STRLEN_VERYLONG		254
> +
>   struct card_info {
>   	struct drm_device *dev;
>   	void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
> @@ -140,6 +144,14 @@ struct atom_context {
>   	uint32_t *scratch;
>   	int scratch_size_bytes;
>   	char vbios_version[20];
> +
> +	uint8_t name[STRLEN_LONG];
> +	uint8_t vbios_pn[STRLEN_LONG];
> +	uint32_t version;
> +	uint8_t vbios_ver_str[STRLEN_NORMAL];
> +	uint8_t date[STRLEN_NORMAL];
> +	uint32_t sub_dev_id;
> +	uint32_t sub_ved_id;
>   };
>   
>   extern int amdgpu_atom_debug;
> diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
> index 275468e4be60..28deecc2f990 100644
> --- a/drivers/gpu/drm/amd/include/atomfirmware.h
> +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
> @@ -197,6 +197,9 @@ enum atom_dp_vs_preemph_def{
>     DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
>   };
>   
> +#define BIOS_ATOM_PREFIX   "ATOMBIOS"
> +#define BIOS_VERSION_PREFIX  "ATOMBIOSBK-AMD"
> +#define BIOS_STRING_LENGTH 43
>   
>   /*
>   enum atom_string_def{
> @@ -215,6 +218,8 @@ enum atombios_image_offset{
>     MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
>     OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
>     OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
> +  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
> +  OFFSET_TO_VBIOS_DATE                       = 0x50,
>   };
>   
>   /****************************************************************************
> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 9169df7fadee..e0f98ca9a755 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -756,6 +756,8 @@ struct drm_amdgpu_cs_chunk_data {
>   	#define AMDGPU_INFO_VBIOS_SIZE		0x1
>   	/* Subquery id: Query vbios image */
>   	#define AMDGPU_INFO_VBIOS_IMAGE		0x2
> +	/* Subquery id: Query vbios info */
> +	#define AMDGPU_INFO_VBIOS_INFO		0x3
>   /* Query UVD handles */
>   #define AMDGPU_INFO_NUM_HANDLES			0x1C
>   /* Query sensor related information */
> @@ -949,6 +951,20 @@ struct drm_amdgpu_info_firmware {
>   	__u32 feature;
>   };
>   
> +struct drm_amdgpu_info_vbios {
> +	__u8 name[64];
> +	__u32 dbdf;
> +	__u8 vbios_pn[64];
> +	__u32 version;
> +	__u8 vbios_ver_str[32];
> +	__u8 date[32];
> +	__u64 serial;
> +	__u32 dev_id;
> +	__u32 rev_id;
> +	__u32 sub_dev_id;
> +	__u32 sub_ved_id;
> +};
> +
>   #define AMDGPU_VRAM_TYPE_UNKNOWN 0
>   #define AMDGPU_VRAM_TYPE_GDDR1 1
>   #define AMDGPU_VRAM_TYPE_DDR2  2
> --
> 2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-05-17 12:08 Jiawei Gu
@ 2021-05-17 12:17 ` Gu, JiaWei (Will)
  2021-05-17 12:25   ` Christian König
  0 siblings, 1 reply; 47+ messages in thread
From: Gu, JiaWei (Will) @ 2021-05-17 12:17 UTC (permalink / raw)
  To: Gu, JiaWei (Will),
	amd-gfx, Koenig, Christian, Nieto, David M, maraeo, Deucher,
	Alexander
  Cc: Deng, Emily

[AMD Official Use Only - Internal Distribution Only]

Hi all,

Thanks Christian's suggestion.
I reverted the previous patches and squash them into this single one.

As this patch shows, the current uapi change looks like this:

+struct drm_amdgpu_info_vbios {
+	__u8 name[64];
+	__u32 dbdf;
+	__u8 vbios_pn[64];
+	__u32 version;
+	__u8 vbios_ver_str[32];
+	__u8 date[32];
+	__u64 serial;
+	__u32 dev_id;
+	__u32 rev_id;
+	__u32 sub_dev_id;
+	__u32 sub_ved_id;
+};

As we know there's some redundant info in this struct.
Please feel free to give any comments or suggestion about what it should & shouldn't include.

Best regards,
Jiawei

-----Original Message-----
From: Jiawei Gu <Jiawei.Gu@amd.com> 
Sent: Monday, May 17, 2021 8:08 PM
To: amd-gfx@lists.freedesktop.org; Koenig, Christian <Christian.Koenig@amd.com>; Nieto, David M <David.Nieto@amd.com>; maraeo@gmail.com; Deucher, Alexander <Alexander.Deucher@amd.com>
Cc: Deng, Emily <Emily.Deng@amd.com>; Gu, JiaWei (Will) <JiaWei.Gu@amd.com>
Subject: [PATCH] drm/amdgpu: Add vbios info ioctl interface

Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.

Provides a way for the user application to get the VBIOS information without having to parse the binary.
It is useful for the user to be able to display in a simple way the VBIOS version in their system if they happen to encounter an issue.

V2:
Use numeric serial.
Parse and expose vbios version string.

Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com>
Acked-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  21 +++
 drivers/gpu/drm/amd/amdgpu/atom.c          | 174 +++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/atom.h          |  12 ++
 drivers/gpu/drm/amd/include/atomfirmware.h |   5 +
 include/uapi/drm/amdgpu_drm.h              |  16 ++
 5 files changed, 228 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 8d12e474745a..30e4fed3de22 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -861,6 +861,27 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
 					    min((size_t)size, (size_t)(bios_size - bios_offset)))
 					? -EFAULT : 0;
 		}
+		case AMDGPU_INFO_VBIOS_INFO: {
+			struct drm_amdgpu_info_vbios vbios_info = {};
+			struct atom_context *atom_context;
+
+			atom_context = adev->mode_info.atom_context;
+			memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
+			vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
+			memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
+			vbios_info.version = atom_context->version;
+			memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str,
+						sizeof(atom_context->vbios_ver_str));
+			memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
+			vbios_info.serial = adev->unique_id;
+			vbios_info.dev_id = adev->pdev->device;
+			vbios_info.rev_id = adev->pdev->revision;
+			vbios_info.sub_dev_id = atom_context->sub_dev_id;
+			vbios_info.sub_ved_id = atom_context->sub_ved_id;
+
+			return copy_to_user(out, &vbios_info,
+						min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
+		}
 		default:
 			DRM_DEBUG_KMS("Invalid request %d\n",
 					info->vbios_info.type);
diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c
index 3dcb8b32f48b..542b2c2414e4 100644
--- a/drivers/gpu/drm/amd/amdgpu/atom.c
+++ b/drivers/gpu/drm/amd/amdgpu/atom.c
@@ -31,6 +31,7 @@
 
 #define ATOM_DEBUG
 
+#include "atomfirmware.h"
 #include "atom.h"
 #include "atom-names.h"
 #include "atom-bits.h"
@@ -1299,12 +1300,168 @@ static void atom_index_iio(struct atom_context *ctx, int base)
 	}
 }
 
+static void atom_get_vbios_name(struct atom_context *ctx) {
+	unsigned char *p_rom;
+	unsigned char str_num;
+	unsigned short off_to_vbios_str;
+	unsigned char *c_ptr;
+	int name_size;
+	int i;
+
+	const char *na = "--N/A--";
+	char *back;
+
+	p_rom = ctx->bios;
+
+	str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
+	if (str_num != 0) {
+		off_to_vbios_str =
+			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
+
+		c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
+	} else {
+		/* do not know where to find name */
+		memcpy(ctx->name, na, 7);
+		ctx->name[7] = 0;
+		return;
+	}
+
+	/*
+	 * skip the atombios strings, usually 4
+	 * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
+	 */
+	for (i = 0; i < str_num; i++) {
+		while (*c_ptr != 0)
+			c_ptr++;
+		c_ptr++;
+	}
+
+	/* skip the following 2 chars: 0x0D 0x0A */
+	c_ptr += 2;
+
+	name_size = strnlen(c_ptr, STRLEN_LONG - 1);
+	memcpy(ctx->name, c_ptr, name_size);
+	back = ctx->name + name_size;
+	while ((*--back) == ' ')
+		;
+	*(back + 1) = '\0';
+}
+
+static void atom_get_vbios_date(struct atom_context *ctx) {
+	unsigned char *p_rom;
+	unsigned char *date_in_rom;
+
+	p_rom = ctx->bios;
+
+	date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
+
+	ctx->date[0] = '2';
+	ctx->date[1] = '0';
+	ctx->date[2] = date_in_rom[6];
+	ctx->date[3] = date_in_rom[7];
+	ctx->date[4] = '/';
+	ctx->date[5] = date_in_rom[0];
+	ctx->date[6] = date_in_rom[1];
+	ctx->date[7] = '/';
+	ctx->date[8] = date_in_rom[3];
+	ctx->date[9] = date_in_rom[4];
+	ctx->date[10] = ' ';
+	ctx->date[11] = date_in_rom[9];
+	ctx->date[12] = date_in_rom[10];
+	ctx->date[13] = date_in_rom[11];
+	ctx->date[14] = date_in_rom[12];
+	ctx->date[15] = date_in_rom[13];
+	ctx->date[16] = '\0';
+}
+
+static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
+					   int end, int maxlen)
+{
+	unsigned long str_off;
+	unsigned char *p_rom;
+	unsigned short str_len;
+
+	str_off = 0;
+	str_len = strnlen(str, maxlen);
+	p_rom = ctx->bios;
+
+	for (; start <= end; ++start) {
+		for (str_off = 0; str_off < str_len; ++str_off) {
+			if (str[str_off] != *(p_rom + start + str_off))
+				break;
+		}
+
+		if (str_off == str_len || str[str_off] == 0)
+			return p_rom + start;
+	}
+	return NULL;
+}
+
+static void atom_get_vbios_pn(struct atom_context *ctx) {
+	unsigned char *p_rom;
+	unsigned short off_to_vbios_str;
+	unsigned char *vbios_str;
+	int count;
+
+	off_to_vbios_str = 0;
+	p_rom = ctx->bios;
+
+	if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
+		off_to_vbios_str =
+			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
+
+		vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
+	} else {
+		vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
+	}
+
+	if (*vbios_str == 0) {
+		vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
+		if (vbios_str == NULL)
+			vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
+	}
+	if (vbios_str != NULL && *vbios_str == 0)
+		vbios_str++;
+
+	if (vbios_str != NULL) {
+		count = 0;
+		while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
+		       vbios_str[count] <= 'z') {
+			ctx->vbios_pn[count] = vbios_str[count];
+			count++;
+		}
+
+		ctx->vbios_pn[count] = 0;
+	}
+}
+
+static void atom_get_vbios_version(struct atom_context *ctx) {
+	unsigned char *vbios_ver;
+
+	/* find anchor ATOMBIOSBK-AMD */
+	vbios_ver = atom_find_str_in_rom(ctx, BIOS_VERSION_PREFIX, 3, 1024, 64);
+	if (vbios_ver != NULL) {
+		/* skip ATOMBIOSBK-AMD VER */
+		vbios_ver += 18;
+		memcpy(ctx->vbios_ver_str, vbios_ver, STRLEN_NORMAL);
+	} else {
+		ctx->vbios_ver_str[0] = '\0';
+	}
+}
+
 struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)  {
 	int base;
 	struct atom_context *ctx =
 	    kzalloc(sizeof(struct atom_context), GFP_KERNEL);
 	char *str;
+	struct _ATOM_ROM_HEADER *atom_rom_header;
+	struct _ATOM_MASTER_DATA_TABLE *master_table;
+	struct _ATOM_FIRMWARE_INFO *atom_fw_info;
 	u16 idx;
 
 	if (!ctx)
@@ -1353,6 +1510,23 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
 		strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
 	}
 
+	atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
+	ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
+	ctx->sub_ved_id = atom_rom_header->usSubsystemID;
+	if (atom_rom_header->usMasterDataTableOffset != 0) {
+		master_table = (struct _ATOM_MASTER_DATA_TABLE *)
+				CSTR(atom_rom_header->usMasterDataTableOffset);
+		if (master_table->ListOfDataTables.FirmwareInfo != 0) {
+			atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
+					CSTR(master_table->ListOfDataTables.FirmwareInfo);
+			ctx->version = atom_fw_info->ulFirmwareRevision;
+		}
+	}
+
+	atom_get_vbios_name(ctx);
+	atom_get_vbios_pn(ctx);
+	atom_get_vbios_date(ctx);
+	atom_get_vbios_version(ctx);
 
 	return ctx;
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h
index d279759cab47..6463ce6e756d 100644
--- a/drivers/gpu/drm/amd/amdgpu/atom.h
+++ b/drivers/gpu/drm/amd/amdgpu/atom.h
@@ -112,6 +112,10 @@ struct drm_device;
 #define ATOM_IO_SYSIO		2
 #define ATOM_IO_IIO		0x80
 
+#define STRLEN_NORMAL		32
+#define STRLEN_LONG		64
+#define STRLEN_VERYLONG		254
+
 struct card_info {
 	struct drm_device *dev;
 	void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
@@ -140,6 +144,14 @@ struct atom_context {
 	uint32_t *scratch;
 	int scratch_size_bytes;
 	char vbios_version[20];
+
+	uint8_t name[STRLEN_LONG];
+	uint8_t vbios_pn[STRLEN_LONG];
+	uint32_t version;
+	uint8_t vbios_ver_str[STRLEN_NORMAL];
+	uint8_t date[STRLEN_NORMAL];
+	uint32_t sub_dev_id;
+	uint32_t sub_ved_id;
 };
 
 extern int amdgpu_atom_debug;
diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
index 275468e4be60..28deecc2f990 100644
--- a/drivers/gpu/drm/amd/include/atomfirmware.h
+++ b/drivers/gpu/drm/amd/include/atomfirmware.h
@@ -197,6 +197,9 @@ enum atom_dp_vs_preemph_def{
   DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
 };
 
+#define BIOS_ATOM_PREFIX   "ATOMBIOS"
+#define BIOS_VERSION_PREFIX  "ATOMBIOSBK-AMD"
+#define BIOS_STRING_LENGTH 43
 
 /*
 enum atom_string_def{
@@ -215,6 +218,8 @@ enum atombios_image_offset{
   MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
   OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
   OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
+  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
+  OFFSET_TO_VBIOS_DATE                       = 0x50,
 };
 
 /****************************************************************************   
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 9169df7fadee..e0f98ca9a755 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -756,6 +756,8 @@ struct drm_amdgpu_cs_chunk_data {
 	#define AMDGPU_INFO_VBIOS_SIZE		0x1
 	/* Subquery id: Query vbios image */
 	#define AMDGPU_INFO_VBIOS_IMAGE		0x2
+	/* Subquery id: Query vbios info */
+	#define AMDGPU_INFO_VBIOS_INFO		0x3
 /* Query UVD handles */
 #define AMDGPU_INFO_NUM_HANDLES			0x1C
 /* Query sensor related information */
@@ -949,6 +951,20 @@ struct drm_amdgpu_info_firmware {
 	__u32 feature;
 };
 
+struct drm_amdgpu_info_vbios {
+	__u8 name[64];
+	__u32 dbdf;
+	__u8 vbios_pn[64];
+	__u32 version;
+	__u8 vbios_ver_str[32];
+	__u8 date[32];
+	__u64 serial;
+	__u32 dev_id;
+	__u32 rev_id;
+	__u32 sub_dev_id;
+	__u32 sub_ved_id;
+};
+
 #define AMDGPU_VRAM_TYPE_UNKNOWN 0
 #define AMDGPU_VRAM_TYPE_GDDR1 1
 #define AMDGPU_VRAM_TYPE_DDR2  2
--
2.17.1
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH] drm/amdgpu: Add vbios info ioctl interface
@ 2021-05-17 12:08 Jiawei Gu
  2021-05-17 12:17 ` Gu, JiaWei (Will)
  0 siblings, 1 reply; 47+ messages in thread
From: Jiawei Gu @ 2021-05-17 12:08 UTC (permalink / raw)
  To: amd-gfx, christian.koenig, david.nieto, maraeo, alexander.deucher
  Cc: emily.deng, Jiawei Gu

Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.

Provides a way for the user application to get the VBIOS
information without having to parse the binary.
It is useful for the user to be able to display in a simple way the VBIOS
version in their system if they happen to encounter an issue.

V2:
Use numeric serial.
Parse and expose vbios version string.

Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com>
Acked-by: Christian König <christian.koenig@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  21 +++
 drivers/gpu/drm/amd/amdgpu/atom.c          | 174 +++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/atom.h          |  12 ++
 drivers/gpu/drm/amd/include/atomfirmware.h |   5 +
 include/uapi/drm/amdgpu_drm.h              |  16 ++
 5 files changed, 228 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 8d12e474745a..30e4fed3de22 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -861,6 +861,27 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
 					    min((size_t)size, (size_t)(bios_size - bios_offset)))
 					? -EFAULT : 0;
 		}
+		case AMDGPU_INFO_VBIOS_INFO: {
+			struct drm_amdgpu_info_vbios vbios_info = {};
+			struct atom_context *atom_context;
+
+			atom_context = adev->mode_info.atom_context;
+			memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
+			vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
+			memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
+			vbios_info.version = atom_context->version;
+			memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str,
+						sizeof(atom_context->vbios_ver_str));
+			memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
+			vbios_info.serial = adev->unique_id;
+			vbios_info.dev_id = adev->pdev->device;
+			vbios_info.rev_id = adev->pdev->revision;
+			vbios_info.sub_dev_id = atom_context->sub_dev_id;
+			vbios_info.sub_ved_id = atom_context->sub_ved_id;
+
+			return copy_to_user(out, &vbios_info,
+						min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
+		}
 		default:
 			DRM_DEBUG_KMS("Invalid request %d\n",
 					info->vbios_info.type);
diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c
index 3dcb8b32f48b..542b2c2414e4 100644
--- a/drivers/gpu/drm/amd/amdgpu/atom.c
+++ b/drivers/gpu/drm/amd/amdgpu/atom.c
@@ -31,6 +31,7 @@
 
 #define ATOM_DEBUG
 
+#include "atomfirmware.h"
 #include "atom.h"
 #include "atom-names.h"
 #include "atom-bits.h"
@@ -1299,12 +1300,168 @@ static void atom_index_iio(struct atom_context *ctx, int base)
 	}
 }
 
+static void atom_get_vbios_name(struct atom_context *ctx)
+{
+	unsigned char *p_rom;
+	unsigned char str_num;
+	unsigned short off_to_vbios_str;
+	unsigned char *c_ptr;
+	int name_size;
+	int i;
+
+	const char *na = "--N/A--";
+	char *back;
+
+	p_rom = ctx->bios;
+
+	str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
+	if (str_num != 0) {
+		off_to_vbios_str =
+			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
+
+		c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
+	} else {
+		/* do not know where to find name */
+		memcpy(ctx->name, na, 7);
+		ctx->name[7] = 0;
+		return;
+	}
+
+	/*
+	 * skip the atombios strings, usually 4
+	 * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
+	 */
+	for (i = 0; i < str_num; i++) {
+		while (*c_ptr != 0)
+			c_ptr++;
+		c_ptr++;
+	}
+
+	/* skip the following 2 chars: 0x0D 0x0A */
+	c_ptr += 2;
+
+	name_size = strnlen(c_ptr, STRLEN_LONG - 1);
+	memcpy(ctx->name, c_ptr, name_size);
+	back = ctx->name + name_size;
+	while ((*--back) == ' ')
+		;
+	*(back + 1) = '\0';
+}
+
+static void atom_get_vbios_date(struct atom_context *ctx)
+{
+	unsigned char *p_rom;
+	unsigned char *date_in_rom;
+
+	p_rom = ctx->bios;
+
+	date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
+
+	ctx->date[0] = '2';
+	ctx->date[1] = '0';
+	ctx->date[2] = date_in_rom[6];
+	ctx->date[3] = date_in_rom[7];
+	ctx->date[4] = '/';
+	ctx->date[5] = date_in_rom[0];
+	ctx->date[6] = date_in_rom[1];
+	ctx->date[7] = '/';
+	ctx->date[8] = date_in_rom[3];
+	ctx->date[9] = date_in_rom[4];
+	ctx->date[10] = ' ';
+	ctx->date[11] = date_in_rom[9];
+	ctx->date[12] = date_in_rom[10];
+	ctx->date[13] = date_in_rom[11];
+	ctx->date[14] = date_in_rom[12];
+	ctx->date[15] = date_in_rom[13];
+	ctx->date[16] = '\0';
+}
+
+static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
+					   int end, int maxlen)
+{
+	unsigned long str_off;
+	unsigned char *p_rom;
+	unsigned short str_len;
+
+	str_off = 0;
+	str_len = strnlen(str, maxlen);
+	p_rom = ctx->bios;
+
+	for (; start <= end; ++start) {
+		for (str_off = 0; str_off < str_len; ++str_off) {
+			if (str[str_off] != *(p_rom + start + str_off))
+				break;
+		}
+
+		if (str_off == str_len || str[str_off] == 0)
+			return p_rom + start;
+	}
+	return NULL;
+}
+
+static void atom_get_vbios_pn(struct atom_context *ctx)
+{
+	unsigned char *p_rom;
+	unsigned short off_to_vbios_str;
+	unsigned char *vbios_str;
+	int count;
+
+	off_to_vbios_str = 0;
+	p_rom = ctx->bios;
+
+	if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
+		off_to_vbios_str =
+			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
+
+		vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
+	} else {
+		vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
+	}
+
+	if (*vbios_str == 0) {
+		vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
+		if (vbios_str == NULL)
+			vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
+	}
+	if (vbios_str != NULL && *vbios_str == 0)
+		vbios_str++;
+
+	if (vbios_str != NULL) {
+		count = 0;
+		while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
+		       vbios_str[count] <= 'z') {
+			ctx->vbios_pn[count] = vbios_str[count];
+			count++;
+		}
+
+		ctx->vbios_pn[count] = 0;
+	}
+}
+
+static void atom_get_vbios_version(struct atom_context *ctx)
+{
+	unsigned char *vbios_ver;
+
+	/* find anchor ATOMBIOSBK-AMD */
+	vbios_ver = atom_find_str_in_rom(ctx, BIOS_VERSION_PREFIX, 3, 1024, 64);
+	if (vbios_ver != NULL) {
+		/* skip ATOMBIOSBK-AMD VER */
+		vbios_ver += 18;
+		memcpy(ctx->vbios_ver_str, vbios_ver, STRLEN_NORMAL);
+	} else {
+		ctx->vbios_ver_str[0] = '\0';
+	}
+}
+
 struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
 {
 	int base;
 	struct atom_context *ctx =
 	    kzalloc(sizeof(struct atom_context), GFP_KERNEL);
 	char *str;
+	struct _ATOM_ROM_HEADER *atom_rom_header;
+	struct _ATOM_MASTER_DATA_TABLE *master_table;
+	struct _ATOM_FIRMWARE_INFO *atom_fw_info;
 	u16 idx;
 
 	if (!ctx)
@@ -1353,6 +1510,23 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
 		strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
 	}
 
+	atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
+	ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
+	ctx->sub_ved_id = atom_rom_header->usSubsystemID;
+	if (atom_rom_header->usMasterDataTableOffset != 0) {
+		master_table = (struct _ATOM_MASTER_DATA_TABLE *)
+				CSTR(atom_rom_header->usMasterDataTableOffset);
+		if (master_table->ListOfDataTables.FirmwareInfo != 0) {
+			atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
+					CSTR(master_table->ListOfDataTables.FirmwareInfo);
+			ctx->version = atom_fw_info->ulFirmwareRevision;
+		}
+	}
+
+	atom_get_vbios_name(ctx);
+	atom_get_vbios_pn(ctx);
+	atom_get_vbios_date(ctx);
+	atom_get_vbios_version(ctx);
 
 	return ctx;
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h
index d279759cab47..6463ce6e756d 100644
--- a/drivers/gpu/drm/amd/amdgpu/atom.h
+++ b/drivers/gpu/drm/amd/amdgpu/atom.h
@@ -112,6 +112,10 @@ struct drm_device;
 #define ATOM_IO_SYSIO		2
 #define ATOM_IO_IIO		0x80
 
+#define STRLEN_NORMAL		32
+#define STRLEN_LONG		64
+#define STRLEN_VERYLONG		254
+
 struct card_info {
 	struct drm_device *dev;
 	void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
@@ -140,6 +144,14 @@ struct atom_context {
 	uint32_t *scratch;
 	int scratch_size_bytes;
 	char vbios_version[20];
+
+	uint8_t name[STRLEN_LONG];
+	uint8_t vbios_pn[STRLEN_LONG];
+	uint32_t version;
+	uint8_t vbios_ver_str[STRLEN_NORMAL];
+	uint8_t date[STRLEN_NORMAL];
+	uint32_t sub_dev_id;
+	uint32_t sub_ved_id;
 };
 
 extern int amdgpu_atom_debug;
diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
index 275468e4be60..28deecc2f990 100644
--- a/drivers/gpu/drm/amd/include/atomfirmware.h
+++ b/drivers/gpu/drm/amd/include/atomfirmware.h
@@ -197,6 +197,9 @@ enum atom_dp_vs_preemph_def{
   DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
 };
 
+#define BIOS_ATOM_PREFIX   "ATOMBIOS"
+#define BIOS_VERSION_PREFIX  "ATOMBIOSBK-AMD"
+#define BIOS_STRING_LENGTH 43
 
 /*
 enum atom_string_def{
@@ -215,6 +218,8 @@ enum atombios_image_offset{
   MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
   OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
   OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
+  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
+  OFFSET_TO_VBIOS_DATE                       = 0x50,
 };
 
 /****************************************************************************   
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index 9169df7fadee..e0f98ca9a755 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -756,6 +756,8 @@ struct drm_amdgpu_cs_chunk_data {
 	#define AMDGPU_INFO_VBIOS_SIZE		0x1
 	/* Subquery id: Query vbios image */
 	#define AMDGPU_INFO_VBIOS_IMAGE		0x2
+	/* Subquery id: Query vbios info */
+	#define AMDGPU_INFO_VBIOS_INFO		0x3
 /* Query UVD handles */
 #define AMDGPU_INFO_NUM_HANDLES			0x1C
 /* Query sensor related information */
@@ -949,6 +951,20 @@ struct drm_amdgpu_info_firmware {
 	__u32 feature;
 };
 
+struct drm_amdgpu_info_vbios {
+	__u8 name[64];
+	__u32 dbdf;
+	__u8 vbios_pn[64];
+	__u32 version;
+	__u8 vbios_ver_str[32];
+	__u8 date[32];
+	__u64 serial;
+	__u32 dev_id;
+	__u32 rev_id;
+	__u32 sub_dev_id;
+	__u32 sub_ved_id;
+};
+
 #define AMDGPU_VRAM_TYPE_UNKNOWN 0
 #define AMDGPU_VRAM_TYPE_GDDR1 1
 #define AMDGPU_VRAM_TYPE_DDR2  2
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-05-08  9:51       ` Kees Cook
  (?)
@ 2021-05-09  5:35       ` Nieto, David M
  -1 siblings, 0 replies; 47+ messages in thread
From: Nieto, David M @ 2021-05-09  5:35 UTC (permalink / raw)
  To: Kees Cook, Gu, JiaWei (Will)
  Cc: Deucher, Alexander, StDenis, Tom, linux-next, amd-gfx,
	Christian König


[-- Attachment #1.1: Type: text/plain, Size: 3828 bytes --]

[AMD Public Use]

The full vbios versioning information consists of the version (numeric), build date and the name... I this this interface exposes only the name.

Should we expose those on different sysfs files or just combine all of them in a single file?

David
________________________________
From: Kees Cook <keescook@chromium.org>
Sent: Saturday, May 8, 2021 2:51 AM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com>
Cc: Deucher, Alexander <Alexander.Deucher@amd.com>; StDenis, Tom <Tom.StDenis@amd.com>; Christian König <ckoenig.leichtzumerken@gmail.com>; amd-gfx@lists.freedesktop.org <amd-gfx@lists.freedesktop.org>; Nieto, David M <David.Nieto@amd.com>; linux-next@vger.kernel.org <linux-next@vger.kernel.org>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

On Sat, May 08, 2021 at 06:01:23AM +0000, Gu, JiaWei (Will) wrote:
> [AMD Official Use Only - Internal Distribution Only]
>
> Thanks for this catching Kees.
>
> Yes it should be 20, not 16. I was not aware that serial size had been changed from 16 to 20 in struct amdgpu_device.
> Will submit a fix soon.

You might want to add a BUILD_BUG_ON() to keep those in sync, especially
since it's about to be UAPI.

-Kees

>
> Best regards,
> Jiawei
>
>
> -----Original Message-----
> From: Kees Cook <keescook@chromium.org>
> Sent: Saturday, May 8, 2021 12:28 PM
> To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com>; Deucher, Alexander <Alexander.Deucher@amd.com>
> Cc: StDenis, Tom <Tom.StDenis@amd.com>; Deucher, Alexander <Alexander.Deucher@amd.com>; Christian König <ckoenig.leichtzumerken@gmail.com>; Gu, JiaWei (Will) <JiaWei.Gu@amd.com>; amd-gfx@lists.freedesktop.org; Nieto, David M <David.Nieto@amd.com>; linux-next@vger.kernel.org
> Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> Hi!
>
> This patch needs some fixing.
>
> On Thu, Apr 22, 2021 at 10:34:48AM +0800, Jiawei Gu wrote:
> > +           case AMDGPU_INFO_VBIOS_INFO: {
> > +                   struct drm_amdgpu_info_vbios vbios_info = {};
> > +                   struct atom_context *atom_context;
> > +
> > +                   atom_context = adev->mode_info.atom_context;
> > +                   memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
> > +                   vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
> > +                   memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
> > +                   vbios_info.version = atom_context->version;
> > +                   memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
> > +                   memcpy(vbios_info.serial, adev->serial, sizeof(adev->serial));
>
> This writes beyond the end of vbios_info.serial.
>
> > +                   vbios_info.dev_id = adev->pdev->device;
> > +                   vbios_info.rev_id = adev->pdev->revision;
> > +                   vbios_info.sub_dev_id = atom_context->sub_dev_id;
> > +                   vbios_info.sub_ved_id = atom_context->sub_ved_id;
>
> Though it gets "repaired" by these writes.
>
> > +
> > +                   return copy_to_user(out, &vbios_info,
> > +                                           min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
> > +           }
>
> sizeof(adev->serial) != sizeof(vbios_info.serial)
>
> adev is struct amdgpu_device:
>
> struct amdgpu_device {
> ...
>         char                            serial[20];
>
>
> > +struct drm_amdgpu_info_vbios {
> > [...]
> > +   __u8 serial[16];
> > +   __u32 dev_id;
> > +   __u32 rev_id;
> > +   __u32 sub_dev_id;
> > +   __u32 sub_ved_id;
> > +};
>
> Is there a truncation issue (20 vs 16) and is this intended to be a NUL-terminated string?
>
> --
> Kees Cook

--
Kees Cook

[-- Attachment #1.2: Type: text/html, Size: 7908 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-05-08  6:01     ` Gu, JiaWei (Will)
@ 2021-05-08  9:51       ` Kees Cook
  -1 siblings, 0 replies; 47+ messages in thread
From: Kees Cook @ 2021-05-08  9:51 UTC (permalink / raw)
  To: Gu, JiaWei (Will)
  Cc: Deucher, Alexander, StDenis, Tom, Christian König, amd-gfx,
	Nieto, David M, linux-next

On Sat, May 08, 2021 at 06:01:23AM +0000, Gu, JiaWei (Will) wrote:
> [AMD Official Use Only - Internal Distribution Only]
> 
> Thanks for this catching Kees.
> 
> Yes it should be 20, not 16. I was not aware that serial size had been changed from 16 to 20 in struct amdgpu_device.
> Will submit a fix soon.

You might want to add a BUILD_BUG_ON() to keep those in sync, especially
since it's about to be UAPI.

-Kees

> 
> Best regards,
> Jiawei
> 
> 
> -----Original Message-----
> From: Kees Cook <keescook@chromium.org> 
> Sent: Saturday, May 8, 2021 12:28 PM
> To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com>; Deucher, Alexander <Alexander.Deucher@amd.com>
> Cc: StDenis, Tom <Tom.StDenis@amd.com>; Deucher, Alexander <Alexander.Deucher@amd.com>; Christian König <ckoenig.leichtzumerken@gmail.com>; Gu, JiaWei (Will) <JiaWei.Gu@amd.com>; amd-gfx@lists.freedesktop.org; Nieto, David M <David.Nieto@amd.com>; linux-next@vger.kernel.org
> Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
> 
> Hi!
> 
> This patch needs some fixing.
> 
> On Thu, Apr 22, 2021 at 10:34:48AM +0800, Jiawei Gu wrote:
> > +		case AMDGPU_INFO_VBIOS_INFO: {
> > +			struct drm_amdgpu_info_vbios vbios_info = {};
> > +			struct atom_context *atom_context;
> > +
> > +			atom_context = adev->mode_info.atom_context;
> > +			memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
> > +			vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
> > +			memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
> > +			vbios_info.version = atom_context->version;
> > +			memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
> > +			memcpy(vbios_info.serial, adev->serial, sizeof(adev->serial));
> 
> This writes beyond the end of vbios_info.serial.
> 
> > +			vbios_info.dev_id = adev->pdev->device;
> > +			vbios_info.rev_id = adev->pdev->revision;
> > +			vbios_info.sub_dev_id = atom_context->sub_dev_id;
> > +			vbios_info.sub_ved_id = atom_context->sub_ved_id;
> 
> Though it gets "repaired" by these writes.
> 
> > +
> > +			return copy_to_user(out, &vbios_info,
> > +						min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
> > +		}
> 
> sizeof(adev->serial) != sizeof(vbios_info.serial)
> 
> adev is struct amdgpu_device:
> 
> struct amdgpu_device {
> ...
>         char                            serial[20];
> 
> 
> > +struct drm_amdgpu_info_vbios {
> > [...]
> > +	__u8 serial[16];
> > +	__u32 dev_id;
> > +	__u32 rev_id;
> > +	__u32 sub_dev_id;
> > +	__u32 sub_ved_id;
> > +};
> 
> Is there a truncation issue (20 vs 16) and is this intended to be a NUL-terminated string?
> 
> --
> Kees Cook

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
@ 2021-05-08  9:51       ` Kees Cook
  0 siblings, 0 replies; 47+ messages in thread
From: Kees Cook @ 2021-05-08  9:51 UTC (permalink / raw)
  To: Gu, JiaWei (Will)
  Cc: StDenis, Tom, Christian König, amd-gfx, linux-next, Deucher,
	Alexander, Nieto, David M

On Sat, May 08, 2021 at 06:01:23AM +0000, Gu, JiaWei (Will) wrote:
> [AMD Official Use Only - Internal Distribution Only]
> 
> Thanks for this catching Kees.
> 
> Yes it should be 20, not 16. I was not aware that serial size had been changed from 16 to 20 in struct amdgpu_device.
> Will submit a fix soon.

You might want to add a BUILD_BUG_ON() to keep those in sync, especially
since it's about to be UAPI.

-Kees

> 
> Best regards,
> Jiawei
> 
> 
> -----Original Message-----
> From: Kees Cook <keescook@chromium.org> 
> Sent: Saturday, May 8, 2021 12:28 PM
> To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com>; Deucher, Alexander <Alexander.Deucher@amd.com>
> Cc: StDenis, Tom <Tom.StDenis@amd.com>; Deucher, Alexander <Alexander.Deucher@amd.com>; Christian König <ckoenig.leichtzumerken@gmail.com>; Gu, JiaWei (Will) <JiaWei.Gu@amd.com>; amd-gfx@lists.freedesktop.org; Nieto, David M <David.Nieto@amd.com>; linux-next@vger.kernel.org
> Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
> 
> Hi!
> 
> This patch needs some fixing.
> 
> On Thu, Apr 22, 2021 at 10:34:48AM +0800, Jiawei Gu wrote:
> > +		case AMDGPU_INFO_VBIOS_INFO: {
> > +			struct drm_amdgpu_info_vbios vbios_info = {};
> > +			struct atom_context *atom_context;
> > +
> > +			atom_context = adev->mode_info.atom_context;
> > +			memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
> > +			vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
> > +			memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
> > +			vbios_info.version = atom_context->version;
> > +			memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
> > +			memcpy(vbios_info.serial, adev->serial, sizeof(adev->serial));
> 
> This writes beyond the end of vbios_info.serial.
> 
> > +			vbios_info.dev_id = adev->pdev->device;
> > +			vbios_info.rev_id = adev->pdev->revision;
> > +			vbios_info.sub_dev_id = atom_context->sub_dev_id;
> > +			vbios_info.sub_ved_id = atom_context->sub_ved_id;
> 
> Though it gets "repaired" by these writes.
> 
> > +
> > +			return copy_to_user(out, &vbios_info,
> > +						min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
> > +		}
> 
> sizeof(adev->serial) != sizeof(vbios_info.serial)
> 
> adev is struct amdgpu_device:
> 
> struct amdgpu_device {
> ...
>         char                            serial[20];
> 
> 
> > +struct drm_amdgpu_info_vbios {
> > [...]
> > +	__u8 serial[16];
> > +	__u32 dev_id;
> > +	__u32 rev_id;
> > +	__u32 sub_dev_id;
> > +	__u32 sub_ved_id;
> > +};
> 
> Is there a truncation issue (20 vs 16) and is this intended to be a NUL-terminated string?
> 
> --
> Kees Cook

-- 
Kees Cook
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-05-08  4:28   ` Kees Cook
@ 2021-05-08  6:01     ` Gu, JiaWei (Will)
  -1 siblings, 0 replies; 47+ messages in thread
From: Gu, JiaWei (Will) @ 2021-05-08  6:01 UTC (permalink / raw)
  To: Kees Cook, Deucher, Alexander
  Cc: StDenis, Tom, Deucher, Alexander, Christian König, amd-gfx,
	Nieto, David M, linux-next

[AMD Official Use Only - Internal Distribution Only]

Thanks for this catching Kees.

Yes it should be 20, not 16. I was not aware that serial size had been changed from 16 to 20 in struct amdgpu_device.
Will submit a fix soon.

Best regards,
Jiawei


-----Original Message-----
From: Kees Cook <keescook@chromium.org> 
Sent: Saturday, May 8, 2021 12:28 PM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com>; Deucher, Alexander <Alexander.Deucher@amd.com>
Cc: StDenis, Tom <Tom.StDenis@amd.com>; Deucher, Alexander <Alexander.Deucher@amd.com>; Christian König <ckoenig.leichtzumerken@gmail.com>; Gu, JiaWei (Will) <JiaWei.Gu@amd.com>; amd-gfx@lists.freedesktop.org; Nieto, David M <David.Nieto@amd.com>; linux-next@vger.kernel.org
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

Hi!

This patch needs some fixing.

On Thu, Apr 22, 2021 at 10:34:48AM +0800, Jiawei Gu wrote:
> +		case AMDGPU_INFO_VBIOS_INFO: {
> +			struct drm_amdgpu_info_vbios vbios_info = {};
> +			struct atom_context *atom_context;
> +
> +			atom_context = adev->mode_info.atom_context;
> +			memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
> +			vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
> +			memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
> +			vbios_info.version = atom_context->version;
> +			memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
> +			memcpy(vbios_info.serial, adev->serial, sizeof(adev->serial));

This writes beyond the end of vbios_info.serial.

> +			vbios_info.dev_id = adev->pdev->device;
> +			vbios_info.rev_id = adev->pdev->revision;
> +			vbios_info.sub_dev_id = atom_context->sub_dev_id;
> +			vbios_info.sub_ved_id = atom_context->sub_ved_id;

Though it gets "repaired" by these writes.

> +
> +			return copy_to_user(out, &vbios_info,
> +						min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
> +		}

sizeof(adev->serial) != sizeof(vbios_info.serial)

adev is struct amdgpu_device:

struct amdgpu_device {
...
        char                            serial[20];


> +struct drm_amdgpu_info_vbios {
> [...]
> +	__u8 serial[16];
> +	__u32 dev_id;
> +	__u32 rev_id;
> +	__u32 sub_dev_id;
> +	__u32 sub_ved_id;
> +};

Is there a truncation issue (20 vs 16) and is this intended to be a NUL-terminated string?

--
Kees Cook

^ permalink raw reply	[flat|nested] 47+ messages in thread

* RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
@ 2021-05-08  6:01     ` Gu, JiaWei (Will)
  0 siblings, 0 replies; 47+ messages in thread
From: Gu, JiaWei (Will) @ 2021-05-08  6:01 UTC (permalink / raw)
  To: Kees Cook, Deucher, Alexander
  Cc: StDenis, Tom, Christian König, amd-gfx, linux-next, Deucher,
	Alexander, Nieto, David M

[AMD Official Use Only - Internal Distribution Only]

Thanks for this catching Kees.

Yes it should be 20, not 16. I was not aware that serial size had been changed from 16 to 20 in struct amdgpu_device.
Will submit a fix soon.

Best regards,
Jiawei


-----Original Message-----
From: Kees Cook <keescook@chromium.org> 
Sent: Saturday, May 8, 2021 12:28 PM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com>; Deucher, Alexander <Alexander.Deucher@amd.com>
Cc: StDenis, Tom <Tom.StDenis@amd.com>; Deucher, Alexander <Alexander.Deucher@amd.com>; Christian König <ckoenig.leichtzumerken@gmail.com>; Gu, JiaWei (Will) <JiaWei.Gu@amd.com>; amd-gfx@lists.freedesktop.org; Nieto, David M <David.Nieto@amd.com>; linux-next@vger.kernel.org
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

Hi!

This patch needs some fixing.

On Thu, Apr 22, 2021 at 10:34:48AM +0800, Jiawei Gu wrote:
> +		case AMDGPU_INFO_VBIOS_INFO: {
> +			struct drm_amdgpu_info_vbios vbios_info = {};
> +			struct atom_context *atom_context;
> +
> +			atom_context = adev->mode_info.atom_context;
> +			memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
> +			vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
> +			memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
> +			vbios_info.version = atom_context->version;
> +			memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
> +			memcpy(vbios_info.serial, adev->serial, sizeof(adev->serial));

This writes beyond the end of vbios_info.serial.

> +			vbios_info.dev_id = adev->pdev->device;
> +			vbios_info.rev_id = adev->pdev->revision;
> +			vbios_info.sub_dev_id = atom_context->sub_dev_id;
> +			vbios_info.sub_ved_id = atom_context->sub_ved_id;

Though it gets "repaired" by these writes.

> +
> +			return copy_to_user(out, &vbios_info,
> +						min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
> +		}

sizeof(adev->serial) != sizeof(vbios_info.serial)

adev is struct amdgpu_device:

struct amdgpu_device {
...
        char                            serial[20];


> +struct drm_amdgpu_info_vbios {
> [...]
> +	__u8 serial[16];
> +	__u32 dev_id;
> +	__u32 rev_id;
> +	__u32 sub_dev_id;
> +	__u32 sub_ved_id;
> +};

Is there a truncation issue (20 vs 16) and is this intended to be a NUL-terminated string?

--
Kees Cook
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-04-22  2:34 Jiawei Gu
@ 2021-05-08  4:28   ` Kees Cook
  2021-05-08  4:28   ` Kees Cook
  1 sibling, 0 replies; 47+ messages in thread
From: Kees Cook @ 2021-05-08  4:28 UTC (permalink / raw)
  To: Jiawei Gu, Deucher, Alexander
  Cc: StDenis, Tom, Deucher, Alexander, Christian König, Gu,
	JiaWei (Will),
	amd-gfx, Nieto, David M, linux-next

Hi!

This patch needs some fixing.

On Thu, Apr 22, 2021 at 10:34:48AM +0800, Jiawei Gu wrote:
> +		case AMDGPU_INFO_VBIOS_INFO: {
> +			struct drm_amdgpu_info_vbios vbios_info = {};
> +			struct atom_context *atom_context;
> +
> +			atom_context = adev->mode_info.atom_context;
> +			memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
> +			vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
> +			memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
> +			vbios_info.version = atom_context->version;
> +			memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
> +			memcpy(vbios_info.serial, adev->serial, sizeof(adev->serial));

This writes beyond the end of vbios_info.serial.

> +			vbios_info.dev_id = adev->pdev->device;
> +			vbios_info.rev_id = adev->pdev->revision;
> +			vbios_info.sub_dev_id = atom_context->sub_dev_id;
> +			vbios_info.sub_ved_id = atom_context->sub_ved_id;

Though it gets "repaired" by these writes.

> +
> +			return copy_to_user(out, &vbios_info,
> +						min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
> +		}

sizeof(adev->serial) != sizeof(vbios_info.serial)

adev is struct amdgpu_device:

struct amdgpu_device {
...
        char                            serial[20];


> +struct drm_amdgpu_info_vbios {
> [...]
> +	__u8 serial[16];
> +	__u32 dev_id;
> +	__u32 rev_id;
> +	__u32 sub_dev_id;
> +	__u32 sub_ved_id;
> +};

Is there a truncation issue (20 vs 16) and is this intended to be a
NUL-terminated string?

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
@ 2021-05-08  4:28   ` Kees Cook
  0 siblings, 0 replies; 47+ messages in thread
From: Kees Cook @ 2021-05-08  4:28 UTC (permalink / raw)
  To: Jiawei Gu, Deucher, Alexander
  Cc: StDenis, Tom, Christian König, Gu, JiaWei (Will),
	amd-gfx, linux-next, Deucher, Alexander, Nieto, David M

Hi!

This patch needs some fixing.

On Thu, Apr 22, 2021 at 10:34:48AM +0800, Jiawei Gu wrote:
> +		case AMDGPU_INFO_VBIOS_INFO: {
> +			struct drm_amdgpu_info_vbios vbios_info = {};
> +			struct atom_context *atom_context;
> +
> +			atom_context = adev->mode_info.atom_context;
> +			memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
> +			vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
> +			memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
> +			vbios_info.version = atom_context->version;
> +			memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
> +			memcpy(vbios_info.serial, adev->serial, sizeof(adev->serial));

This writes beyond the end of vbios_info.serial.

> +			vbios_info.dev_id = adev->pdev->device;
> +			vbios_info.rev_id = adev->pdev->revision;
> +			vbios_info.sub_dev_id = atom_context->sub_dev_id;
> +			vbios_info.sub_ved_id = atom_context->sub_ved_id;

Though it gets "repaired" by these writes.

> +
> +			return copy_to_user(out, &vbios_info,
> +						min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
> +		}

sizeof(adev->serial) != sizeof(vbios_info.serial)

adev is struct amdgpu_device:

struct amdgpu_device {
...
        char                            serial[20];


> +struct drm_amdgpu_info_vbios {
> [...]
> +	__u8 serial[16];
> +	__u32 dev_id;
> +	__u32 rev_id;
> +	__u32 sub_dev_id;
> +	__u32 sub_ved_id;
> +};

Is there a truncation issue (20 vs 16) and is this intended to be a
NUL-terminated string?

-- 
Kees Cook
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-04-28 20:53                       ` Alex Deucher
@ 2021-04-28 21:18                         ` StDenis, Tom
  0 siblings, 0 replies; 47+ messages in thread
From: StDenis, Tom @ 2021-04-28 21:18 UTC (permalink / raw)
  To: Alex Deucher
  Cc: Deucher, Alexander, Christian König, Gu, JiaWei (Will),
	amd-gfx, Nieto, David M

[AMD Official Use Only - Internal Distribution Only]

Done.

________________________________________
From: Alex Deucher <alexdeucher@gmail.com>
Sent: Wednesday, April 28, 2021 16:53
To: StDenis, Tom
Cc: Gu, JiaWei (Will); Christian König; Nieto, David M; amd-gfx@lists.freedesktop.org; Deucher, Alexander
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

Please revert the patch in umr until the kernel side lands in upstream drm-next.

Alex

On Wed, Apr 28, 2021 at 7:30 AM StDenis, Tom <Tom.StDenis@amd.com> wrote:
>
> [AMD Official Use Only - Internal Distribution Only]
>
> Hi Will,
>
> I've merged in your v2 patch last week.  If that's still the latest you should be good to go.
>
> Tom
>
> ________________________________________
> From: Gu, JiaWei (Will) <JiaWei.Gu@amd.com>
> Sent: Wednesday, April 28, 2021 06:38
> To: Christian König; Nieto, David M; amd-gfx@lists.freedesktop.org; StDenis, Tom
> Cc: Deucher, Alexander
> Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> [AMD Official Use Only - Internal Distribution Only]
>
> Hi @StDenis, Tom<mailto:Tom.StDenis@amd.com>,
>
> We have merged vbios info ioctl patch.
> Could you help re-merge the UMR side one again if it was reverted before?
>
> Thanks in advance!
> Jiawei
>
> From: Gu, JiaWei (Will)
> Sent: Wednesday, April 28, 2021 4:21 PM
> To: Christian König <ckoenig.leichtzumerken@gmail.com>; Nieto, David M <David.Nieto@amd.com>; amd-gfx@lists.freedesktop.org
> Cc: Deucher, Alexander <Alexander.Deucher@amd.com>; StDenis, Tom <Tom.StDenis@amd.com>
> Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
>
> [AMD Official Use Only - Internal Distribution Only]
>
> Thanks Christian,
>
> I amended the commit message and resend the patch out.
> Please feel free to let me know if message is not clear enough.
>
> Best regards,
> Jiawei
>
> From: Christian König <ckoenig.leichtzumerken@gmail.com<mailto:ckoenig.leichtzumerken@gmail.com>>
> Sent: Wednesday, April 28, 2021 3:43 PM
> To: Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>
> Cc: Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>; StDenis, Tom <Tom.StDenis@amd.com<mailto:Tom.StDenis@amd.com>>
> Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> Yeah, makes sense. Please note that in the commit message.
>
> With that feel free to put an Acked-by: Christian König <christian.koenig@amd.com><mailto:christian.koenig@amd.com> on it.
>
> Regards,
> Christian.
> Am 28.04.21 um 09:25 schrieb Nieto, David M:
> I think this change may be orthogonal to that. Here we want to provide a way for the user application to get the VBIOS information without having to parse the binary…
>
> And I agree that we should not have strong dependencies unless the encounter buggy VBIOS on the field, but I still think it is useful for the user to be able to display in a simple way the VBIOS version in their system if they happen to encounter an issue.
>
> Regards,
> David
>
> From: Christian König <ckoenig.leichtzumerken@gmail.com><mailto:ckoenig.leichtzumerken@gmail.com>
> Date: Wednesday, April 28, 2021 at 12:15 AM
> To: "Nieto, David M" <David.Nieto@amd.com><mailto:David.Nieto@amd.com>, "Gu, JiaWei (Will)" <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com>, "amd-gfx@lists.freedesktop.org"<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org><mailto:amd-gfx@lists.freedesktop.org>
> Cc: "Deucher, Alexander" <Alexander.Deucher@amd.com><mailto:Alexander.Deucher@amd.com>, "StDenis, Tom" <Tom.StDenis@amd.com><mailto:Tom.StDenis@amd.com>
> Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> Well displaying the VBIOS information along with the other firmware in userspace is certainly useful.
>
> We should just avoid making strong dependencies on that.
>
> Firmware and VBIOS must always be backward compatible and the driver must always work with any released firmware and VBIOS combination.
>
> What we can do is to display a warning when we detect and/or old/buggy firmware.
>
> Regards,
> Christian.
> Am 28.04.21 um 08:47 schrieb Nieto, David M:
> Besides system management, it provides parseable details on the VBIOS version and information. This is useful renderer information as the GPU behavior depends not only on the driver version but also on the firmwares running on the GPU.
>
> The AMDGPU_INFO ioctl contains a method to get the versions of the ucode for all the IPs, but for VBIOS, only a way to dump the entire image is provided. While it Is possible to implement the whole logic of VBIOS parsing on userspace, it requires the application to have details on the header and table formats to parse the data. Moreover there is no guarantee that the format and header locations will remain constant across ASIC generations, so the maintainance cost and complexity seems unreasonable.
>
> Providing a simple, and stable interface to the application seems to us like a sensible choice.
>
> Thanks,
> David
>
> From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org><mailto:amd-gfx-bounces@lists.freedesktop.org> on behalf of "Gu, JiaWei (Will)" <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com>
> Date: Thursday, April 22, 2021 at 8:25 PM
> To: Christian König <ckoenig.leichtzumerken@gmail.com><mailto:ckoenig.leichtzumerken@gmail.com>, "amd-gfx@lists.freedesktop.org"<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org><mailto:amd-gfx@lists.freedesktop.org>
> Cc: "Deucher, Alexander" <Alexander.Deucher@amd.com><mailto:Alexander.Deucher@amd.com>, "StDenis, Tom" <Tom.StDenis@amd.com><mailto:Tom.StDenis@amd.com>, "Nieto, David M" <David.Nieto@amd.com><mailto:David.Nieto@amd.com>
> Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
>
> [AMD Official Use Only - Internal Distribution Only]
>
> Hi Christian,
> It will be used by a user space SMI-lib for GPU status query.
>
> Hi David, please feel free to correct my statement since I’m not sure I have a view of whole picture.
>
> Thanks,
> Jiawei
>
> From: Christian König <ckoenig.leichtzumerken@gmail.com><mailto:ckoenig.leichtzumerken@gmail.com>
> Sent: Thursday, April 22, 2021 9:27 PM
> To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>
> Cc: Deucher, Alexander <Alexander.Deucher@amd.com><mailto:Alexander.Deucher@amd.com>; StDenis, Tom <Tom.StDenis@amd.com><mailto:Tom.StDenis@amd.com>
> Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> Is that useful to Vulkan/OpenGL/other clients in any way?
>
> Christian.
> Am 22.04.21 um 15:18 schrieb Gu, JiaWei (Will):
>
>
>
> CC Tom.
>
>
>
> On Apr 22, 2021, at 21:09, Gu, JiaWei (Will) <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com> wrote:
>
>
>
> <[v2][umr]add-vbios-info-query.patch>
>
> UMR patch which calls this new IOCTL attached.
>
>
>
> Best regards,
>
> Jiawei
>
>
>
> On Apr 22, 2021, at 10:34, Jiawei Gu <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com> wrote:
>
>
>
> Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.
>
>
>
> Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com><mailto:Jiawei.Gu@amd.com>
>
> ---
>
> drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  19 +++
>
> drivers/gpu/drm/amd/amdgpu/atom.c          | 158 +++++++++++++++++++++
>
> drivers/gpu/drm/amd/amdgpu/atom.h          |  11 ++
>
> drivers/gpu/drm/amd/include/atomfirmware.h |  16 ++-
>
> include/uapi/drm/amdgpu_drm.h              |  15 ++
>
> 5 files changed, 213 insertions(+), 6 deletions(-)
>
>
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>
> index 39ee88d29cca..a20b016b05ab 100644
>
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>
> @@ -861,6 +861,25 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
>
>                                        min((size_t)size, (size_t)(bios_size - bios_offset)))
>
>                                    ? -EFAULT : 0;
>
>              }
>
> +            case AMDGPU_INFO_VBIOS_INFO: {
>
> +                   struct drm_amdgpu_info_vbios vbios_info = {};
>
> +                   struct atom_context *atom_context;
>
> +
>
> +                   atom_context = adev->mode_info.atom_context;
>
> +                 memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
>
> +                 vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
>
> +                 memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
>
> +                 vbios_info.version = atom_context->version;
>
> +                 memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
>
> +                 memcpy(vbios_info.serial, adev->serial, sizeof(adev->serial));
>
> +                 vbios_info.dev_id = adev->pdev->device;
>
> +                 vbios_info.rev_id = adev->pdev->revision;
>
> +                 vbios_info.sub_dev_id = atom_context->sub_dev_id;
>
> +                 vbios_info.sub_ved_id = atom_context->sub_ved_id;
>
> +
>
> +                   return copy_to_user(out, &vbios_info,
>
> +                                  min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
>
> +            }
>
>              default:
>
>                   DRM_DEBUG_KMS("Invalid request %d\n",
>
>                             info->vbios_info.type);
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c
>
> index 3dcb8b32f48b..0e2f0ea13b40 100644
>
> --- a/drivers/gpu/drm/amd/amdgpu/atom.c
>
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
>
> @@ -31,6 +31,7 @@
>
>
>
> #define ATOM_DEBUG
>
>
>
> +#include "atomfirmware.h"
>
> #include "atom.h"
>
> #include "atom-names.h"
>
> #include "atom-bits.h"
>
> @@ -1299,12 +1300,153 @@ static void atom_index_iio(struct atom_context *ctx, int base)
>
>      }
>
> }
>
>
>
> +static void atom_get_vbios_name(struct atom_context *ctx)
>
> +{
>
> +    unsigned char *p_rom;
>
> +    unsigned char str_num;
>
> +    unsigned short off_to_vbios_str;
>
> +    unsigned char *c_ptr;
>
> +    int name_size;
>
> +    int i;
>
> +
>
> +    const char *na = "--N/A--";
>
> +    char *back;
>
> +
>
> +    p_rom = ctx->bios;
>
> +
>
> +    str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
>
> +    if (str_num != 0) {
>
> +            off_to_vbios_str =
>
> +                   *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
>
> +
>
> +            c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
>
> +    } else {
>
> +            /* do not know where to find name */
>
> +            memcpy(ctx->name, na, 7);
>
> +            ctx->name[7] = 0;
>
> +            return;
>
> +    }
>
> +
>
> +    /*
>
> +     * skip the atombios strings, usually 4
>
> +     * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
>
> +     */
>
> +    for (i = 0; i < str_num; i++) {
>
> +            while (*c_ptr != 0)
>
> +                   c_ptr++;
>
> +            c_ptr++;
>
> +    }
>
> +
>
> +    /* skip the following 2 chars: 0x0D 0x0A */
>
> +    c_ptr += 2;
>
> +
>
> +    name_size = strnlen(c_ptr, STRLEN_LONG - 1);
>
> +    memcpy(ctx->name, c_ptr, name_size);
>
> +    back = ctx->name + name_size;
>
> +    while ((*--back) == ' ')
>
> +            ;
>
> +    *(back + 1) = '\0';
>
> +}
>
> +
>
> +static void atom_get_vbios_date(struct atom_context *ctx)
>
> +{
>
> +    unsigned char *p_rom;
>
> +    unsigned char *date_in_rom;
>
> +
>
> +    p_rom = ctx->bios;
>
> +
>
> +    date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
>
> +
>
> +    ctx->date[0] = '2';
>
> +    ctx->date[1] = '0';
>
> +    ctx->date[2] = date_in_rom[6];
>
> +    ctx->date[3] = date_in_rom[7];
>
> +    ctx->date[4] = '/';
>
> +    ctx->date[5] = date_in_rom[0];
>
> +    ctx->date[6] = date_in_rom[1];
>
> +    ctx->date[7] = '/';
>
> +    ctx->date[8] = date_in_rom[3];
>
> +    ctx->date[9] = date_in_rom[4];
>
> +    ctx->date[10] = ' ';
>
> +    ctx->date[11] = date_in_rom[9];
>
> +    ctx->date[12] = date_in_rom[10];
>
> +    ctx->date[13] = date_in_rom[11];
>
> +    ctx->date[14] = date_in_rom[12];
>
> +    ctx->date[15] = date_in_rom[13];
>
> +    ctx->date[16] = '\0';
>
> +}
>
> +
>
> +static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
>
> +                                     int end, int maxlen)
>
> +{
>
> +    unsigned long str_off;
>
> +    unsigned char *p_rom;
>
> +    unsigned short str_len;
>
> +
>
> +    str_off = 0;
>
> +    str_len = strnlen(str, maxlen);
>
> +    p_rom = ctx->bios;
>
> +
>
> +    for (; start <= end; ++start) {
>
> +            for (str_off = 0; str_off < str_len; ++str_off) {
>
> +                   if (str[str_off] != *(p_rom + start + str_off))
>
> +                        break;
>
> +            }
>
> +
>
> +            if (str_off == str_len || str[str_off] == 0)
>
> +                   return p_rom + start;
>
> +    }
>
> +    return NULL;
>
> +}
>
> +
>
> +static void atom_get_vbios_pn(struct atom_context *ctx)
>
> +{
>
> +    unsigned char *p_rom;
>
> +    unsigned short off_to_vbios_str;
>
> +    unsigned char *vbios_str;
>
> +    int count;
>
> +
>
> +    off_to_vbios_str = 0;
>
> +    p_rom = ctx->bios;
>
> +
>
> +    if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
>
> +            off_to_vbios_str =
>
> +                   *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
>
> +
>
> +            vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
>
> +    } else {
>
> +            vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
>
> +    }
>
> +
>
> +    if (*vbios_str == 0) {
>
> +            vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
>
> +            if (vbios_str == NULL)
>
> +                   vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
>
> +    }
>
> +    if (vbios_str != NULL && *vbios_str == 0)
>
> +            vbios_str++;
>
> +
>
> +    if (vbios_str != NULL) {
>
> +            count = 0;
>
> +            while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
>
> +                   vbios_str[count] <= 'z') {
>
> +                 ctx->vbios_pn[count] = vbios_str[count];
>
> +                   count++;
>
> +            }
>
> +
>
> +            ctx->vbios_pn[count] = 0;
>
> +    }
>
> +}
>
> +
>
> struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>
> {
>
>      int base;
>
>      struct atom_context *ctx =
>
>          kzalloc(sizeof(struct atom_context), GFP_KERNEL);
>
>      char *str;
>
> +    struct _ATOM_ROM_HEADER *atom_rom_header;
>
> +    struct _ATOM_MASTER_DATA_TABLE *master_table;
>
> +    struct _ATOM_FIRMWARE_INFO *atom_fw_info;
>
>      u16 idx;
>
>
>
>      if (!ctx)
>
> @@ -1353,6 +1495,22 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>
>           strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
>
>      }
>
>
>
> +    atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
>
> +    ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
>
> +    ctx->sub_ved_id = atom_rom_header->usSubsystemID;
>
> +    if (atom_rom_header->usMasterDataTableOffset != 0) {
>
> +            master_table = (struct _ATOM_MASTER_DATA_TABLE *)
>
> +                    CSTR(atom_rom_header->usMasterDataTableOffset);
>
> +            if (master_table->ListOfDataTables.FirmwareInfo != 0) {
>
> +                   atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
>
> +                           CSTR(master_table->ListOfDataTables.FirmwareInfo);
>
> +                   ctx->version = atom_fw_info->ulFirmwareRevision;
>
> +            }
>
> +    }
>
> +
>
> +    atom_get_vbios_name(ctx);
>
> +    atom_get_vbios_pn(ctx);
>
> +    atom_get_vbios_date(ctx);
>
>
>
>      return ctx;
>
> }
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h
>
> index d279759cab47..c729f7ceba4f 100644
>
> --- a/drivers/gpu/drm/amd/amdgpu/atom.h
>
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
>
> @@ -112,6 +112,10 @@ struct drm_device;
>
> #define ATOM_IO_SYSIO              2
>
> #define ATOM_IO_IIO         0x80
>
>
>
> +#define STRLEN_NORMAL             32
>
> +#define STRLEN_LONG        64
>
> +#define STRLEN_VERYLONG           254
>
> +
>
> struct card_info {
>
>      struct drm_device *dev;
>
>      void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
>
> @@ -140,6 +144,13 @@ struct atom_context {
>
>      uint32_t *scratch;
>
>      int scratch_size_bytes;
>
>      char vbios_version[20];
>
> +
>
> +    uint8_t name[STRLEN_LONG];
>
> +    uint8_t vbios_pn[STRLEN_LONG];
>
> +    uint32_t version;
>
> +    uint8_t date[STRLEN_NORMAL];
>
> +    uint32_t sub_dev_id;
>
> +    uint32_t sub_ved_id;
>
> };
>
>
>
> extern int amdgpu_atom_debug;
>
> diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
>
> index c77ed38c20fb..3a8e404099b0 100644
>
> --- a/drivers/gpu/drm/amd/include/atomfirmware.h
>
> +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
>
> @@ -197,6 +197,8 @@ enum atom_dp_vs_preemph_def{
>
>  DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
>
> };
>
>
>
> +#define BIOS_ATOM_PREFIX   "ATOMBIOS"
>
> +#define BIOS_STRING_LENGTH 43
>
>
>
> /*
>
> enum atom_string_def{
>
> @@ -209,12 +211,14 @@ atom_bios_string          = "ATOM"
>
> #pragma pack(1)                          /* BIOS data must use byte aligment*/
>
>
>
> enum atombios_image_offset{
>
> -OFFSET_TO_ATOM_ROM_HEADER_POINTER          =0x00000048,
>
> -OFFSET_TO_ATOM_ROM_IMAGE_SIZE              =0x00000002,
>
> -OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       =0x94,
>
> -MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      =20,  /*including the terminator 0x0!*/
>
> -OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   =0x2f,
>
> -OFFSET_TO_GET_ATOMBIOS_STRING_START        =0x6e,
>
> +  OFFSET_TO_ATOM_ROM_HEADER_POINTER          = 0x00000048,
>
> +  OFFSET_TO_ATOM_ROM_IMAGE_SIZE              = 0x00000002,
>
> +  OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       = 0x94,
>
> +  MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
>
> +  OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
>
> +  OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
>
> +  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
>
> +  OFFSET_TO_VBIOS_DATE                       = 0x50,
>
> };
>
>
>
> /****************************************************************************
>
> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
>
> index 8b832f7458f2..77980445d486 100644
>
> --- a/include/uapi/drm/amdgpu_drm.h
>
> +++ b/include/uapi/drm/amdgpu_drm.h
>
> @@ -758,6 +758,8 @@ struct drm_amdgpu_cs_chunk_data {
>
>      #define AMDGPU_INFO_VBIOS_SIZE             0x1
>
>      /* Subquery id: Query vbios image */
>
>      #define AMDGPU_INFO_VBIOS_IMAGE            0x2
>
> +    /* Subquery id: Query vbios info */
>
> +    #define AMDGPU_INFO_VBIOS_INFO             0x3
>
> /* Query UVD handles */
>
> #define AMDGPU_INFO_NUM_HANDLES                    0x1C
>
> /* Query sensor related information */
>
> @@ -951,6 +953,19 @@ struct drm_amdgpu_info_firmware {
>
>      __u32 feature;
>
> };
>
>
>
> +struct drm_amdgpu_info_vbios {
>
> +    __u8 name[64];
>
> +    __u32 dbdf;
>
> +    __u8 vbios_pn[64];
>
> +    __u32 version;
>
> +    __u8 date[32];
>
> +    __u8 serial[16];
>
> +    __u32 dev_id;
>
> +    __u32 rev_id;
>
> +    __u32 sub_dev_id;
>
> +    __u32 sub_ved_id;
>
> +};
>
> +
>
> #define AMDGPU_VRAM_TYPE_UNKNOWN 0
>
> #define AMDGPU_VRAM_TYPE_GDDR1 1
>
> #define AMDGPU_VRAM_TYPE_DDR2  2
>
> --
>
> 2.17.1
>
>
>
>
>
>
>
>
> _______________________________________________
>
> amd-gfx mailing list
>
> amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>
>
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&amp;data=04%7C01%7CTom.StDenis%40amd.com%7C2e21345be22a4d33287208d90a87bfba%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637552400421234036%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=tpz4dELQMPbVYCGy66Jko8wonptkM%2BWL2zNXxxDxrXQ%3D&amp;reserved=0<https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&amp;data=04%7C01%7CTom.StDenis%40amd.com%7C2e21345be22a4d33287208d90a87bfba%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637552400421234036%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=tpz4dELQMPbVYCGy66Jko8wonptkM%2BWL2zNXxxDxrXQ%3D&amp;reserved=0>
>
>
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&amp;data=04%7C01%7CTom.StDenis%40amd.com%7C2e21345be22a4d33287208d90a87bfba%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637552400421234036%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=tpz4dELQMPbVYCGy66Jko8wonptkM%2BWL2zNXxxDxrXQ%3D&amp;reserved=0
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-04-28 11:30                     ` StDenis, Tom
@ 2021-04-28 20:53                       ` Alex Deucher
  2021-04-28 21:18                         ` StDenis, Tom
  0 siblings, 1 reply; 47+ messages in thread
From: Alex Deucher @ 2021-04-28 20:53 UTC (permalink / raw)
  To: StDenis, Tom
  Cc: Deucher, Alexander, Christian König, Gu, JiaWei (Will),
	amd-gfx, Nieto, David M

Please revert the patch in umr until the kernel side lands in upstream drm-next.

Alex

On Wed, Apr 28, 2021 at 7:30 AM StDenis, Tom <Tom.StDenis@amd.com> wrote:
>
> [AMD Official Use Only - Internal Distribution Only]
>
> Hi Will,
>
> I've merged in your v2 patch last week.  If that's still the latest you should be good to go.
>
> Tom
>
> ________________________________________
> From: Gu, JiaWei (Will) <JiaWei.Gu@amd.com>
> Sent: Wednesday, April 28, 2021 06:38
> To: Christian König; Nieto, David M; amd-gfx@lists.freedesktop.org; StDenis, Tom
> Cc: Deucher, Alexander
> Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> [AMD Official Use Only - Internal Distribution Only]
>
> Hi @StDenis, Tom<mailto:Tom.StDenis@amd.com>,
>
> We have merged vbios info ioctl patch.
> Could you help re-merge the UMR side one again if it was reverted before?
>
> Thanks in advance!
> Jiawei
>
> From: Gu, JiaWei (Will)
> Sent: Wednesday, April 28, 2021 4:21 PM
> To: Christian König <ckoenig.leichtzumerken@gmail.com>; Nieto, David M <David.Nieto@amd.com>; amd-gfx@lists.freedesktop.org
> Cc: Deucher, Alexander <Alexander.Deucher@amd.com>; StDenis, Tom <Tom.StDenis@amd.com>
> Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
>
> [AMD Official Use Only - Internal Distribution Only]
>
> Thanks Christian,
>
> I amended the commit message and resend the patch out.
> Please feel free to let me know if message is not clear enough.
>
> Best regards,
> Jiawei
>
> From: Christian König <ckoenig.leichtzumerken@gmail.com<mailto:ckoenig.leichtzumerken@gmail.com>>
> Sent: Wednesday, April 28, 2021 3:43 PM
> To: Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>
> Cc: Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>; StDenis, Tom <Tom.StDenis@amd.com<mailto:Tom.StDenis@amd.com>>
> Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> Yeah, makes sense. Please note that in the commit message.
>
> With that feel free to put an Acked-by: Christian König <christian.koenig@amd.com><mailto:christian.koenig@amd.com> on it.
>
> Regards,
> Christian.
> Am 28.04.21 um 09:25 schrieb Nieto, David M:
> I think this change may be orthogonal to that. Here we want to provide a way for the user application to get the VBIOS information without having to parse the binary…
>
> And I agree that we should not have strong dependencies unless the encounter buggy VBIOS on the field, but I still think it is useful for the user to be able to display in a simple way the VBIOS version in their system if they happen to encounter an issue.
>
> Regards,
> David
>
> From: Christian König <ckoenig.leichtzumerken@gmail.com><mailto:ckoenig.leichtzumerken@gmail.com>
> Date: Wednesday, April 28, 2021 at 12:15 AM
> To: "Nieto, David M" <David.Nieto@amd.com><mailto:David.Nieto@amd.com>, "Gu, JiaWei (Will)" <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com>, "amd-gfx@lists.freedesktop.org"<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org><mailto:amd-gfx@lists.freedesktop.org>
> Cc: "Deucher, Alexander" <Alexander.Deucher@amd.com><mailto:Alexander.Deucher@amd.com>, "StDenis, Tom" <Tom.StDenis@amd.com><mailto:Tom.StDenis@amd.com>
> Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> Well displaying the VBIOS information along with the other firmware in userspace is certainly useful.
>
> We should just avoid making strong dependencies on that.
>
> Firmware and VBIOS must always be backward compatible and the driver must always work with any released firmware and VBIOS combination.
>
> What we can do is to display a warning when we detect and/or old/buggy firmware.
>
> Regards,
> Christian.
> Am 28.04.21 um 08:47 schrieb Nieto, David M:
> Besides system management, it provides parseable details on the VBIOS version and information. This is useful renderer information as the GPU behavior depends not only on the driver version but also on the firmwares running on the GPU.
>
> The AMDGPU_INFO ioctl contains a method to get the versions of the ucode for all the IPs, but for VBIOS, only a way to dump the entire image is provided. While it Is possible to implement the whole logic of VBIOS parsing on userspace, it requires the application to have details on the header and table formats to parse the data. Moreover there is no guarantee that the format and header locations will remain constant across ASIC generations, so the maintainance cost and complexity seems unreasonable.
>
> Providing a simple, and stable interface to the application seems to us like a sensible choice.
>
> Thanks,
> David
>
> From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org><mailto:amd-gfx-bounces@lists.freedesktop.org> on behalf of "Gu, JiaWei (Will)" <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com>
> Date: Thursday, April 22, 2021 at 8:25 PM
> To: Christian König <ckoenig.leichtzumerken@gmail.com><mailto:ckoenig.leichtzumerken@gmail.com>, "amd-gfx@lists.freedesktop.org"<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org><mailto:amd-gfx@lists.freedesktop.org>
> Cc: "Deucher, Alexander" <Alexander.Deucher@amd.com><mailto:Alexander.Deucher@amd.com>, "StDenis, Tom" <Tom.StDenis@amd.com><mailto:Tom.StDenis@amd.com>, "Nieto, David M" <David.Nieto@amd.com><mailto:David.Nieto@amd.com>
> Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
>
> [AMD Official Use Only - Internal Distribution Only]
>
> Hi Christian,
> It will be used by a user space SMI-lib for GPU status query.
>
> Hi David, please feel free to correct my statement since I’m not sure I have a view of whole picture.
>
> Thanks,
> Jiawei
>
> From: Christian König <ckoenig.leichtzumerken@gmail.com><mailto:ckoenig.leichtzumerken@gmail.com>
> Sent: Thursday, April 22, 2021 9:27 PM
> To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>
> Cc: Deucher, Alexander <Alexander.Deucher@amd.com><mailto:Alexander.Deucher@amd.com>; StDenis, Tom <Tom.StDenis@amd.com><mailto:Tom.StDenis@amd.com>
> Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> Is that useful to Vulkan/OpenGL/other clients in any way?
>
> Christian.
> Am 22.04.21 um 15:18 schrieb Gu, JiaWei (Will):
>
>
>
> CC Tom.
>
>
>
> On Apr 22, 2021, at 21:09, Gu, JiaWei (Will) <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com> wrote:
>
>
>
> <[v2][umr]add-vbios-info-query.patch>
>
> UMR patch which calls this new IOCTL attached.
>
>
>
> Best regards,
>
> Jiawei
>
>
>
> On Apr 22, 2021, at 10:34, Jiawei Gu <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com> wrote:
>
>
>
> Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.
>
>
>
> Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com><mailto:Jiawei.Gu@amd.com>
>
> ---
>
> drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  19 +++
>
> drivers/gpu/drm/amd/amdgpu/atom.c          | 158 +++++++++++++++++++++
>
> drivers/gpu/drm/amd/amdgpu/atom.h          |  11 ++
>
> drivers/gpu/drm/amd/include/atomfirmware.h |  16 ++-
>
> include/uapi/drm/amdgpu_drm.h              |  15 ++
>
> 5 files changed, 213 insertions(+), 6 deletions(-)
>
>
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>
> index 39ee88d29cca..a20b016b05ab 100644
>
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>
> @@ -861,6 +861,25 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
>
>                                        min((size_t)size, (size_t)(bios_size - bios_offset)))
>
>                                    ? -EFAULT : 0;
>
>              }
>
> +            case AMDGPU_INFO_VBIOS_INFO: {
>
> +                   struct drm_amdgpu_info_vbios vbios_info = {};
>
> +                   struct atom_context *atom_context;
>
> +
>
> +                   atom_context = adev->mode_info.atom_context;
>
> +                 memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
>
> +                 vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
>
> +                 memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
>
> +                 vbios_info.version = atom_context->version;
>
> +                 memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
>
> +                 memcpy(vbios_info.serial, adev->serial, sizeof(adev->serial));
>
> +                 vbios_info.dev_id = adev->pdev->device;
>
> +                 vbios_info.rev_id = adev->pdev->revision;
>
> +                 vbios_info.sub_dev_id = atom_context->sub_dev_id;
>
> +                 vbios_info.sub_ved_id = atom_context->sub_ved_id;
>
> +
>
> +                   return copy_to_user(out, &vbios_info,
>
> +                                  min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
>
> +            }
>
>              default:
>
>                   DRM_DEBUG_KMS("Invalid request %d\n",
>
>                             info->vbios_info.type);
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c
>
> index 3dcb8b32f48b..0e2f0ea13b40 100644
>
> --- a/drivers/gpu/drm/amd/amdgpu/atom.c
>
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
>
> @@ -31,6 +31,7 @@
>
>
>
> #define ATOM_DEBUG
>
>
>
> +#include "atomfirmware.h"
>
> #include "atom.h"
>
> #include "atom-names.h"
>
> #include "atom-bits.h"
>
> @@ -1299,12 +1300,153 @@ static void atom_index_iio(struct atom_context *ctx, int base)
>
>      }
>
> }
>
>
>
> +static void atom_get_vbios_name(struct atom_context *ctx)
>
> +{
>
> +    unsigned char *p_rom;
>
> +    unsigned char str_num;
>
> +    unsigned short off_to_vbios_str;
>
> +    unsigned char *c_ptr;
>
> +    int name_size;
>
> +    int i;
>
> +
>
> +    const char *na = "--N/A--";
>
> +    char *back;
>
> +
>
> +    p_rom = ctx->bios;
>
> +
>
> +    str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
>
> +    if (str_num != 0) {
>
> +            off_to_vbios_str =
>
> +                   *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
>
> +
>
> +            c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
>
> +    } else {
>
> +            /* do not know where to find name */
>
> +            memcpy(ctx->name, na, 7);
>
> +            ctx->name[7] = 0;
>
> +            return;
>
> +    }
>
> +
>
> +    /*
>
> +     * skip the atombios strings, usually 4
>
> +     * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
>
> +     */
>
> +    for (i = 0; i < str_num; i++) {
>
> +            while (*c_ptr != 0)
>
> +                   c_ptr++;
>
> +            c_ptr++;
>
> +    }
>
> +
>
> +    /* skip the following 2 chars: 0x0D 0x0A */
>
> +    c_ptr += 2;
>
> +
>
> +    name_size = strnlen(c_ptr, STRLEN_LONG - 1);
>
> +    memcpy(ctx->name, c_ptr, name_size);
>
> +    back = ctx->name + name_size;
>
> +    while ((*--back) == ' ')
>
> +            ;
>
> +    *(back + 1) = '\0';
>
> +}
>
> +
>
> +static void atom_get_vbios_date(struct atom_context *ctx)
>
> +{
>
> +    unsigned char *p_rom;
>
> +    unsigned char *date_in_rom;
>
> +
>
> +    p_rom = ctx->bios;
>
> +
>
> +    date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
>
> +
>
> +    ctx->date[0] = '2';
>
> +    ctx->date[1] = '0';
>
> +    ctx->date[2] = date_in_rom[6];
>
> +    ctx->date[3] = date_in_rom[7];
>
> +    ctx->date[4] = '/';
>
> +    ctx->date[5] = date_in_rom[0];
>
> +    ctx->date[6] = date_in_rom[1];
>
> +    ctx->date[7] = '/';
>
> +    ctx->date[8] = date_in_rom[3];
>
> +    ctx->date[9] = date_in_rom[4];
>
> +    ctx->date[10] = ' ';
>
> +    ctx->date[11] = date_in_rom[9];
>
> +    ctx->date[12] = date_in_rom[10];
>
> +    ctx->date[13] = date_in_rom[11];
>
> +    ctx->date[14] = date_in_rom[12];
>
> +    ctx->date[15] = date_in_rom[13];
>
> +    ctx->date[16] = '\0';
>
> +}
>
> +
>
> +static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
>
> +                                     int end, int maxlen)
>
> +{
>
> +    unsigned long str_off;
>
> +    unsigned char *p_rom;
>
> +    unsigned short str_len;
>
> +
>
> +    str_off = 0;
>
> +    str_len = strnlen(str, maxlen);
>
> +    p_rom = ctx->bios;
>
> +
>
> +    for (; start <= end; ++start) {
>
> +            for (str_off = 0; str_off < str_len; ++str_off) {
>
> +                   if (str[str_off] != *(p_rom + start + str_off))
>
> +                        break;
>
> +            }
>
> +
>
> +            if (str_off == str_len || str[str_off] == 0)
>
> +                   return p_rom + start;
>
> +    }
>
> +    return NULL;
>
> +}
>
> +
>
> +static void atom_get_vbios_pn(struct atom_context *ctx)
>
> +{
>
> +    unsigned char *p_rom;
>
> +    unsigned short off_to_vbios_str;
>
> +    unsigned char *vbios_str;
>
> +    int count;
>
> +
>
> +    off_to_vbios_str = 0;
>
> +    p_rom = ctx->bios;
>
> +
>
> +    if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
>
> +            off_to_vbios_str =
>
> +                   *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
>
> +
>
> +            vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
>
> +    } else {
>
> +            vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
>
> +    }
>
> +
>
> +    if (*vbios_str == 0) {
>
> +            vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
>
> +            if (vbios_str == NULL)
>
> +                   vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
>
> +    }
>
> +    if (vbios_str != NULL && *vbios_str == 0)
>
> +            vbios_str++;
>
> +
>
> +    if (vbios_str != NULL) {
>
> +            count = 0;
>
> +            while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
>
> +                   vbios_str[count] <= 'z') {
>
> +                 ctx->vbios_pn[count] = vbios_str[count];
>
> +                   count++;
>
> +            }
>
> +
>
> +            ctx->vbios_pn[count] = 0;
>
> +    }
>
> +}
>
> +
>
> struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>
> {
>
>      int base;
>
>      struct atom_context *ctx =
>
>          kzalloc(sizeof(struct atom_context), GFP_KERNEL);
>
>      char *str;
>
> +    struct _ATOM_ROM_HEADER *atom_rom_header;
>
> +    struct _ATOM_MASTER_DATA_TABLE *master_table;
>
> +    struct _ATOM_FIRMWARE_INFO *atom_fw_info;
>
>      u16 idx;
>
>
>
>      if (!ctx)
>
> @@ -1353,6 +1495,22 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>
>           strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
>
>      }
>
>
>
> +    atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
>
> +    ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
>
> +    ctx->sub_ved_id = atom_rom_header->usSubsystemID;
>
> +    if (atom_rom_header->usMasterDataTableOffset != 0) {
>
> +            master_table = (struct _ATOM_MASTER_DATA_TABLE *)
>
> +                    CSTR(atom_rom_header->usMasterDataTableOffset);
>
> +            if (master_table->ListOfDataTables.FirmwareInfo != 0) {
>
> +                   atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
>
> +                           CSTR(master_table->ListOfDataTables.FirmwareInfo);
>
> +                   ctx->version = atom_fw_info->ulFirmwareRevision;
>
> +            }
>
> +    }
>
> +
>
> +    atom_get_vbios_name(ctx);
>
> +    atom_get_vbios_pn(ctx);
>
> +    atom_get_vbios_date(ctx);
>
>
>
>      return ctx;
>
> }
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h
>
> index d279759cab47..c729f7ceba4f 100644
>
> --- a/drivers/gpu/drm/amd/amdgpu/atom.h
>
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
>
> @@ -112,6 +112,10 @@ struct drm_device;
>
> #define ATOM_IO_SYSIO              2
>
> #define ATOM_IO_IIO         0x80
>
>
>
> +#define STRLEN_NORMAL             32
>
> +#define STRLEN_LONG        64
>
> +#define STRLEN_VERYLONG           254
>
> +
>
> struct card_info {
>
>      struct drm_device *dev;
>
>      void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
>
> @@ -140,6 +144,13 @@ struct atom_context {
>
>      uint32_t *scratch;
>
>      int scratch_size_bytes;
>
>      char vbios_version[20];
>
> +
>
> +    uint8_t name[STRLEN_LONG];
>
> +    uint8_t vbios_pn[STRLEN_LONG];
>
> +    uint32_t version;
>
> +    uint8_t date[STRLEN_NORMAL];
>
> +    uint32_t sub_dev_id;
>
> +    uint32_t sub_ved_id;
>
> };
>
>
>
> extern int amdgpu_atom_debug;
>
> diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
>
> index c77ed38c20fb..3a8e404099b0 100644
>
> --- a/drivers/gpu/drm/amd/include/atomfirmware.h
>
> +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
>
> @@ -197,6 +197,8 @@ enum atom_dp_vs_preemph_def{
>
>  DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
>
> };
>
>
>
> +#define BIOS_ATOM_PREFIX   "ATOMBIOS"
>
> +#define BIOS_STRING_LENGTH 43
>
>
>
> /*
>
> enum atom_string_def{
>
> @@ -209,12 +211,14 @@ atom_bios_string          = "ATOM"
>
> #pragma pack(1)                          /* BIOS data must use byte aligment*/
>
>
>
> enum atombios_image_offset{
>
> -OFFSET_TO_ATOM_ROM_HEADER_POINTER          =0x00000048,
>
> -OFFSET_TO_ATOM_ROM_IMAGE_SIZE              =0x00000002,
>
> -OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       =0x94,
>
> -MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      =20,  /*including the terminator 0x0!*/
>
> -OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   =0x2f,
>
> -OFFSET_TO_GET_ATOMBIOS_STRING_START        =0x6e,
>
> +  OFFSET_TO_ATOM_ROM_HEADER_POINTER          = 0x00000048,
>
> +  OFFSET_TO_ATOM_ROM_IMAGE_SIZE              = 0x00000002,
>
> +  OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       = 0x94,
>
> +  MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
>
> +  OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
>
> +  OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
>
> +  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
>
> +  OFFSET_TO_VBIOS_DATE                       = 0x50,
>
> };
>
>
>
> /****************************************************************************
>
> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
>
> index 8b832f7458f2..77980445d486 100644
>
> --- a/include/uapi/drm/amdgpu_drm.h
>
> +++ b/include/uapi/drm/amdgpu_drm.h
>
> @@ -758,6 +758,8 @@ struct drm_amdgpu_cs_chunk_data {
>
>      #define AMDGPU_INFO_VBIOS_SIZE             0x1
>
>      /* Subquery id: Query vbios image */
>
>      #define AMDGPU_INFO_VBIOS_IMAGE            0x2
>
> +    /* Subquery id: Query vbios info */
>
> +    #define AMDGPU_INFO_VBIOS_INFO             0x3
>
> /* Query UVD handles */
>
> #define AMDGPU_INFO_NUM_HANDLES                    0x1C
>
> /* Query sensor related information */
>
> @@ -951,6 +953,19 @@ struct drm_amdgpu_info_firmware {
>
>      __u32 feature;
>
> };
>
>
>
> +struct drm_amdgpu_info_vbios {
>
> +    __u8 name[64];
>
> +    __u32 dbdf;
>
> +    __u8 vbios_pn[64];
>
> +    __u32 version;
>
> +    __u8 date[32];
>
> +    __u8 serial[16];
>
> +    __u32 dev_id;
>
> +    __u32 rev_id;
>
> +    __u32 sub_dev_id;
>
> +    __u32 sub_ved_id;
>
> +};
>
> +
>
> #define AMDGPU_VRAM_TYPE_UNKNOWN 0
>
> #define AMDGPU_VRAM_TYPE_GDDR1 1
>
> #define AMDGPU_VRAM_TYPE_DDR2  2
>
> --
>
> 2.17.1
>
>
>
>
>
>
>
>
> _______________________________________________
>
> amd-gfx mailing list
>
> amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>
>
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx<https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=04%7C01%7CJiaWei.Gu%40amd.com%7Cfc8d3420d88745c257bf08d90a1934d6%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637551925654186287%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=Y9%2B4WCgVSr0pS%2Bdf5PzTCddGhjitFaCsNhp%2Fu%2F%2FnmII%3D&reserved=0>
>
>
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-04-28 10:38                   ` Gu, JiaWei (Will)
@ 2021-04-28 11:30                     ` StDenis, Tom
  2021-04-28 20:53                       ` Alex Deucher
  0 siblings, 1 reply; 47+ messages in thread
From: StDenis, Tom @ 2021-04-28 11:30 UTC (permalink / raw)
  To: Gu, JiaWei (Will), Christian König, Nieto, David M, amd-gfx
  Cc: Deucher, Alexander

[AMD Official Use Only - Internal Distribution Only]

Hi Will,

I've merged in your v2 patch last week.  If that's still the latest you should be good to go.

Tom

________________________________________
From: Gu, JiaWei (Will) <JiaWei.Gu@amd.com>
Sent: Wednesday, April 28, 2021 06:38
To: Christian König; Nieto, David M; amd-gfx@lists.freedesktop.org; StDenis, Tom
Cc: Deucher, Alexander
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface

[AMD Official Use Only - Internal Distribution Only]

Hi @StDenis, Tom<mailto:Tom.StDenis@amd.com>,

We have merged vbios info ioctl patch.
Could you help re-merge the UMR side one again if it was reverted before?

Thanks in advance!
Jiawei

From: Gu, JiaWei (Will)
Sent: Wednesday, April 28, 2021 4:21 PM
To: Christian König <ckoenig.leichtzumerken@gmail.com>; Nieto, David M <David.Nieto@amd.com>; amd-gfx@lists.freedesktop.org
Cc: Deucher, Alexander <Alexander.Deucher@amd.com>; StDenis, Tom <Tom.StDenis@amd.com>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface


[AMD Official Use Only - Internal Distribution Only]

Thanks Christian,

I amended the commit message and resend the patch out.
Please feel free to let me know if message is not clear enough.

Best regards,
Jiawei

From: Christian König <ckoenig.leichtzumerken@gmail.com<mailto:ckoenig.leichtzumerken@gmail.com>>
Sent: Wednesday, April 28, 2021 3:43 PM
To: Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>
Cc: Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>; StDenis, Tom <Tom.StDenis@amd.com<mailto:Tom.StDenis@amd.com>>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

Yeah, makes sense. Please note that in the commit message.

With that feel free to put an Acked-by: Christian König <christian.koenig@amd.com><mailto:christian.koenig@amd.com> on it.

Regards,
Christian.
Am 28.04.21 um 09:25 schrieb Nieto, David M:
I think this change may be orthogonal to that. Here we want to provide a way for the user application to get the VBIOS information without having to parse the binary…

And I agree that we should not have strong dependencies unless the encounter buggy VBIOS on the field, but I still think it is useful for the user to be able to display in a simple way the VBIOS version in their system if they happen to encounter an issue.

Regards,
David

From: Christian König <ckoenig.leichtzumerken@gmail.com><mailto:ckoenig.leichtzumerken@gmail.com>
Date: Wednesday, April 28, 2021 at 12:15 AM
To: "Nieto, David M" <David.Nieto@amd.com><mailto:David.Nieto@amd.com>, "Gu, JiaWei (Will)" <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com>, "amd-gfx@lists.freedesktop.org"<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org><mailto:amd-gfx@lists.freedesktop.org>
Cc: "Deucher, Alexander" <Alexander.Deucher@amd.com><mailto:Alexander.Deucher@amd.com>, "StDenis, Tom" <Tom.StDenis@amd.com><mailto:Tom.StDenis@amd.com>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

Well displaying the VBIOS information along with the other firmware in userspace is certainly useful.

We should just avoid making strong dependencies on that.

Firmware and VBIOS must always be backward compatible and the driver must always work with any released firmware and VBIOS combination.

What we can do is to display a warning when we detect and/or old/buggy firmware.

Regards,
Christian.
Am 28.04.21 um 08:47 schrieb Nieto, David M:
Besides system management, it provides parseable details on the VBIOS version and information. This is useful renderer information as the GPU behavior depends not only on the driver version but also on the firmwares running on the GPU.

The AMDGPU_INFO ioctl contains a method to get the versions of the ucode for all the IPs, but for VBIOS, only a way to dump the entire image is provided. While it Is possible to implement the whole logic of VBIOS parsing on userspace, it requires the application to have details on the header and table formats to parse the data. Moreover there is no guarantee that the format and header locations will remain constant across ASIC generations, so the maintainance cost and complexity seems unreasonable.

Providing a simple, and stable interface to the application seems to us like a sensible choice.

Thanks,
David

From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org><mailto:amd-gfx-bounces@lists.freedesktop.org> on behalf of "Gu, JiaWei (Will)" <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com>
Date: Thursday, April 22, 2021 at 8:25 PM
To: Christian König <ckoenig.leichtzumerken@gmail.com><mailto:ckoenig.leichtzumerken@gmail.com>, "amd-gfx@lists.freedesktop.org"<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org><mailto:amd-gfx@lists.freedesktop.org>
Cc: "Deucher, Alexander" <Alexander.Deucher@amd.com><mailto:Alexander.Deucher@amd.com>, "StDenis, Tom" <Tom.StDenis@amd.com><mailto:Tom.StDenis@amd.com>, "Nieto, David M" <David.Nieto@amd.com><mailto:David.Nieto@amd.com>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface


[AMD Official Use Only - Internal Distribution Only]

Hi Christian,
It will be used by a user space SMI-lib for GPU status query.

Hi David, please feel free to correct my statement since I’m not sure I have a view of whole picture.

Thanks,
Jiawei

From: Christian König <ckoenig.leichtzumerken@gmail.com><mailto:ckoenig.leichtzumerken@gmail.com>
Sent: Thursday, April 22, 2021 9:27 PM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>
Cc: Deucher, Alexander <Alexander.Deucher@amd.com><mailto:Alexander.Deucher@amd.com>; StDenis, Tom <Tom.StDenis@amd.com><mailto:Tom.StDenis@amd.com>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

Is that useful to Vulkan/OpenGL/other clients in any way?

Christian.
Am 22.04.21 um 15:18 schrieb Gu, JiaWei (Will):



CC Tom.



On Apr 22, 2021, at 21:09, Gu, JiaWei (Will) <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com> wrote:



<[v2][umr]add-vbios-info-query.patch>

UMR patch which calls this new IOCTL attached.



Best regards,

Jiawei



On Apr 22, 2021, at 10:34, Jiawei Gu <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com> wrote:



Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.



Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com><mailto:Jiawei.Gu@amd.com>

---

drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  19 +++

drivers/gpu/drm/amd/amdgpu/atom.c          | 158 +++++++++++++++++++++

drivers/gpu/drm/amd/amdgpu/atom.h          |  11 ++

drivers/gpu/drm/amd/include/atomfirmware.h |  16 ++-

include/uapi/drm/amdgpu_drm.h              |  15 ++

5 files changed, 213 insertions(+), 6 deletions(-)



diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

index 39ee88d29cca..a20b016b05ab 100644

--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

@@ -861,6 +861,25 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)

                                       min((size_t)size, (size_t)(bios_size - bios_offset)))

                                   ? -EFAULT : 0;

             }

+            case AMDGPU_INFO_VBIOS_INFO: {

+                   struct drm_amdgpu_info_vbios vbios_info = {};

+                   struct atom_context *atom_context;

+

+                   atom_context = adev->mode_info.atom_context;

+                 memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));

+                 vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);

+                 memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));

+                 vbios_info.version = atom_context->version;

+                 memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));

+                 memcpy(vbios_info.serial, adev->serial, sizeof(adev->serial));

+                 vbios_info.dev_id = adev->pdev->device;

+                 vbios_info.rev_id = adev->pdev->revision;

+                 vbios_info.sub_dev_id = atom_context->sub_dev_id;

+                 vbios_info.sub_ved_id = atom_context->sub_ved_id;

+

+                   return copy_to_user(out, &vbios_info,

+                                  min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;

+            }

             default:

                  DRM_DEBUG_KMS("Invalid request %d\n",

                            info->vbios_info.type);

diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c

index 3dcb8b32f48b..0e2f0ea13b40 100644

--- a/drivers/gpu/drm/amd/amdgpu/atom.c

+++ b/drivers/gpu/drm/amd/amdgpu/atom.c

@@ -31,6 +31,7 @@



#define ATOM_DEBUG



+#include "atomfirmware.h"

#include "atom.h"

#include "atom-names.h"

#include "atom-bits.h"

@@ -1299,12 +1300,153 @@ static void atom_index_iio(struct atom_context *ctx, int base)

     }

}



+static void atom_get_vbios_name(struct atom_context *ctx)

+{

+    unsigned char *p_rom;

+    unsigned char str_num;

+    unsigned short off_to_vbios_str;

+    unsigned char *c_ptr;

+    int name_size;

+    int i;

+

+    const char *na = "--N/A--";

+    char *back;

+

+    p_rom = ctx->bios;

+

+    str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);

+    if (str_num != 0) {

+            off_to_vbios_str =

+                   *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);

+

+            c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);

+    } else {

+            /* do not know where to find name */

+            memcpy(ctx->name, na, 7);

+            ctx->name[7] = 0;

+            return;

+    }

+

+    /*

+     * skip the atombios strings, usually 4

+     * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type

+     */

+    for (i = 0; i < str_num; i++) {

+            while (*c_ptr != 0)

+                   c_ptr++;

+            c_ptr++;

+    }

+

+    /* skip the following 2 chars: 0x0D 0x0A */

+    c_ptr += 2;

+

+    name_size = strnlen(c_ptr, STRLEN_LONG - 1);

+    memcpy(ctx->name, c_ptr, name_size);

+    back = ctx->name + name_size;

+    while ((*--back) == ' ')

+            ;

+    *(back + 1) = '\0';

+}

+

+static void atom_get_vbios_date(struct atom_context *ctx)

+{

+    unsigned char *p_rom;

+    unsigned char *date_in_rom;

+

+    p_rom = ctx->bios;

+

+    date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;

+

+    ctx->date[0] = '2';

+    ctx->date[1] = '0';

+    ctx->date[2] = date_in_rom[6];

+    ctx->date[3] = date_in_rom[7];

+    ctx->date[4] = '/';

+    ctx->date[5] = date_in_rom[0];

+    ctx->date[6] = date_in_rom[1];

+    ctx->date[7] = '/';

+    ctx->date[8] = date_in_rom[3];

+    ctx->date[9] = date_in_rom[4];

+    ctx->date[10] = ' ';

+    ctx->date[11] = date_in_rom[9];

+    ctx->date[12] = date_in_rom[10];

+    ctx->date[13] = date_in_rom[11];

+    ctx->date[14] = date_in_rom[12];

+    ctx->date[15] = date_in_rom[13];

+    ctx->date[16] = '\0';

+}

+

+static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,

+                                     int end, int maxlen)

+{

+    unsigned long str_off;

+    unsigned char *p_rom;

+    unsigned short str_len;

+

+    str_off = 0;

+    str_len = strnlen(str, maxlen);

+    p_rom = ctx->bios;

+

+    for (; start <= end; ++start) {

+            for (str_off = 0; str_off < str_len; ++str_off) {

+                   if (str[str_off] != *(p_rom + start + str_off))

+                        break;

+            }

+

+            if (str_off == str_len || str[str_off] == 0)

+                   return p_rom + start;

+    }

+    return NULL;

+}

+

+static void atom_get_vbios_pn(struct atom_context *ctx)

+{

+    unsigned char *p_rom;

+    unsigned short off_to_vbios_str;

+    unsigned char *vbios_str;

+    int count;

+

+    off_to_vbios_str = 0;

+    p_rom = ctx->bios;

+

+    if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {

+            off_to_vbios_str =

+                   *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);

+

+            vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);

+    } else {

+            vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;

+    }

+

+    if (*vbios_str == 0) {

+            vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);

+            if (vbios_str == NULL)

+                   vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;

+    }

+    if (vbios_str != NULL && *vbios_str == 0)

+            vbios_str++;

+

+    if (vbios_str != NULL) {

+            count = 0;

+            while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&

+                   vbios_str[count] <= 'z') {

+                 ctx->vbios_pn[count] = vbios_str[count];

+                   count++;

+            }

+

+            ctx->vbios_pn[count] = 0;

+    }

+}

+

struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)

{

     int base;

     struct atom_context *ctx =

         kzalloc(sizeof(struct atom_context), GFP_KERNEL);

     char *str;

+    struct _ATOM_ROM_HEADER *atom_rom_header;

+    struct _ATOM_MASTER_DATA_TABLE *master_table;

+    struct _ATOM_FIRMWARE_INFO *atom_fw_info;

     u16 idx;



     if (!ctx)

@@ -1353,6 +1495,22 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)

          strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));

     }



+    atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);

+    ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;

+    ctx->sub_ved_id = atom_rom_header->usSubsystemID;

+    if (atom_rom_header->usMasterDataTableOffset != 0) {

+            master_table = (struct _ATOM_MASTER_DATA_TABLE *)

+                    CSTR(atom_rom_header->usMasterDataTableOffset);

+            if (master_table->ListOfDataTables.FirmwareInfo != 0) {

+                   atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)

+                           CSTR(master_table->ListOfDataTables.FirmwareInfo);

+                   ctx->version = atom_fw_info->ulFirmwareRevision;

+            }

+    }

+

+    atom_get_vbios_name(ctx);

+    atom_get_vbios_pn(ctx);

+    atom_get_vbios_date(ctx);



     return ctx;

}

diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h

index d279759cab47..c729f7ceba4f 100644

--- a/drivers/gpu/drm/amd/amdgpu/atom.h

+++ b/drivers/gpu/drm/amd/amdgpu/atom.h

@@ -112,6 +112,10 @@ struct drm_device;

#define ATOM_IO_SYSIO              2

#define ATOM_IO_IIO         0x80



+#define STRLEN_NORMAL             32

+#define STRLEN_LONG        64

+#define STRLEN_VERYLONG           254

+

struct card_info {

     struct drm_device *dev;

     void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */

@@ -140,6 +144,13 @@ struct atom_context {

     uint32_t *scratch;

     int scratch_size_bytes;

     char vbios_version[20];

+

+    uint8_t name[STRLEN_LONG];

+    uint8_t vbios_pn[STRLEN_LONG];

+    uint32_t version;

+    uint8_t date[STRLEN_NORMAL];

+    uint32_t sub_dev_id;

+    uint32_t sub_ved_id;

};



extern int amdgpu_atom_debug;

diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h

index c77ed38c20fb..3a8e404099b0 100644

--- a/drivers/gpu/drm/amd/include/atomfirmware.h

+++ b/drivers/gpu/drm/amd/include/atomfirmware.h

@@ -197,6 +197,8 @@ enum atom_dp_vs_preemph_def{

 DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,

};



+#define BIOS_ATOM_PREFIX   "ATOMBIOS"

+#define BIOS_STRING_LENGTH 43



/*

enum atom_string_def{

@@ -209,12 +211,14 @@ atom_bios_string          = "ATOM"

#pragma pack(1)                          /* BIOS data must use byte aligment*/



enum atombios_image_offset{

-OFFSET_TO_ATOM_ROM_HEADER_POINTER          =0x00000048,

-OFFSET_TO_ATOM_ROM_IMAGE_SIZE              =0x00000002,

-OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       =0x94,

-MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      =20,  /*including the terminator 0x0!*/

-OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   =0x2f,

-OFFSET_TO_GET_ATOMBIOS_STRING_START        =0x6e,

+  OFFSET_TO_ATOM_ROM_HEADER_POINTER          = 0x00000048,

+  OFFSET_TO_ATOM_ROM_IMAGE_SIZE              = 0x00000002,

+  OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       = 0x94,

+  MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/

+  OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,

+  OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,

+  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,

+  OFFSET_TO_VBIOS_DATE                       = 0x50,

};



/****************************************************************************

diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h

index 8b832f7458f2..77980445d486 100644

--- a/include/uapi/drm/amdgpu_drm.h

+++ b/include/uapi/drm/amdgpu_drm.h

@@ -758,6 +758,8 @@ struct drm_amdgpu_cs_chunk_data {

     #define AMDGPU_INFO_VBIOS_SIZE             0x1

     /* Subquery id: Query vbios image */

     #define AMDGPU_INFO_VBIOS_IMAGE            0x2

+    /* Subquery id: Query vbios info */

+    #define AMDGPU_INFO_VBIOS_INFO             0x3

/* Query UVD handles */

#define AMDGPU_INFO_NUM_HANDLES                    0x1C

/* Query sensor related information */

@@ -951,6 +953,19 @@ struct drm_amdgpu_info_firmware {

     __u32 feature;

};



+struct drm_amdgpu_info_vbios {

+    __u8 name[64];

+    __u32 dbdf;

+    __u8 vbios_pn[64];

+    __u32 version;

+    __u8 date[32];

+    __u8 serial[16];

+    __u32 dev_id;

+    __u32 rev_id;

+    __u32 sub_dev_id;

+    __u32 sub_ved_id;

+};

+

#define AMDGPU_VRAM_TYPE_UNKNOWN 0

#define AMDGPU_VRAM_TYPE_GDDR1 1

#define AMDGPU_VRAM_TYPE_DDR2  2

--

2.17.1








_______________________________________________

amd-gfx mailing list

amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>

https://lists.freedesktop.org/mailman/listinfo/amd-gfx<https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=04%7C01%7CJiaWei.Gu%40amd.com%7Cfc8d3420d88745c257bf08d90a1934d6%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637551925654186287%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=Y9%2B4WCgVSr0pS%2Bdf5PzTCddGhjitFaCsNhp%2Fu%2F%2FnmII%3D&reserved=0>



_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-04-28  8:21                 ` Gu, JiaWei (Will)
@ 2021-04-28 10:38                   ` Gu, JiaWei (Will)
  2021-04-28 11:30                     ` StDenis, Tom
  0 siblings, 1 reply; 47+ messages in thread
From: Gu, JiaWei (Will) @ 2021-04-28 10:38 UTC (permalink / raw)
  To: Christian König, Nieto, David M, amd-gfx, StDenis, Tom
  Cc: Deucher, Alexander


[-- Attachment #1.1: Type: text/plain, Size: 19029 bytes --]

[AMD Official Use Only - Internal Distribution Only]

Hi @StDenis, Tom<mailto:Tom.StDenis@amd.com>,

We have merged vbios info ioctl patch.
Could you help re-merge the UMR side one again if it was reverted before?

Thanks in advance!
Jiawei

From: Gu, JiaWei (Will)
Sent: Wednesday, April 28, 2021 4:21 PM
To: Christian König <ckoenig.leichtzumerken@gmail.com>; Nieto, David M <David.Nieto@amd.com>; amd-gfx@lists.freedesktop.org
Cc: Deucher, Alexander <Alexander.Deucher@amd.com>; StDenis, Tom <Tom.StDenis@amd.com>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface


[AMD Official Use Only - Internal Distribution Only]

Thanks Christian,

I amended the commit message and resend the patch out.
Please feel free to let me know if message is not clear enough.

Best regards,
Jiawei

From: Christian König <ckoenig.leichtzumerken@gmail.com<mailto:ckoenig.leichtzumerken@gmail.com>>
Sent: Wednesday, April 28, 2021 3:43 PM
To: Nieto, David M <David.Nieto@amd.com<mailto:David.Nieto@amd.com>>; Gu, JiaWei (Will) <JiaWei.Gu@amd.com<mailto:JiaWei.Gu@amd.com>>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>
Cc: Deucher, Alexander <Alexander.Deucher@amd.com<mailto:Alexander.Deucher@amd.com>>; StDenis, Tom <Tom.StDenis@amd.com<mailto:Tom.StDenis@amd.com>>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

Yeah, makes sense. Please note that in the commit message.

With that feel free to put an Acked-by: Christian König <christian.koenig@amd.com><mailto:christian.koenig@amd.com> on it.

Regards,
Christian.
Am 28.04.21 um 09:25 schrieb Nieto, David M:
I think this change may be orthogonal to that. Here we want to provide a way for the user application to get the VBIOS information without having to parse the binary...

And I agree that we should not have strong dependencies unless the encounter buggy VBIOS on the field, but I still think it is useful for the user to be able to display in a simple way the VBIOS version in their system if they happen to encounter an issue.

Regards,
David

From: Christian König <ckoenig.leichtzumerken@gmail.com><mailto:ckoenig.leichtzumerken@gmail.com>
Date: Wednesday, April 28, 2021 at 12:15 AM
To: "Nieto, David M" <David.Nieto@amd.com><mailto:David.Nieto@amd.com>, "Gu, JiaWei (Will)" <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com>, "amd-gfx@lists.freedesktop.org"<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org><mailto:amd-gfx@lists.freedesktop.org>
Cc: "Deucher, Alexander" <Alexander.Deucher@amd.com><mailto:Alexander.Deucher@amd.com>, "StDenis, Tom" <Tom.StDenis@amd.com><mailto:Tom.StDenis@amd.com>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

Well displaying the VBIOS information along with the other firmware in userspace is certainly useful.

We should just avoid making strong dependencies on that.

Firmware and VBIOS must always be backward compatible and the driver must always work with any released firmware and VBIOS combination.

What we can do is to display a warning when we detect and/or old/buggy firmware.

Regards,
Christian.
Am 28.04.21 um 08:47 schrieb Nieto, David M:
Besides system management, it provides parseable details on the VBIOS version and information. This is useful renderer information as the GPU behavior depends not only on the driver version but also on the firmwares running on the GPU.

The AMDGPU_INFO ioctl contains a method to get the versions of the ucode for all the IPs, but for VBIOS, only a way to dump the entire image is provided. While it Is possible to implement the whole logic of VBIOS parsing on userspace, it requires the application to have details on the header and table formats to parse the data. Moreover there is no guarantee that the format and header locations will remain constant across ASIC generations, so the maintainance cost and complexity seems unreasonable.

Providing a simple, and stable interface to the application seems to us like a sensible choice.

Thanks,
David

From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org><mailto:amd-gfx-bounces@lists.freedesktop.org> on behalf of "Gu, JiaWei (Will)" <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com>
Date: Thursday, April 22, 2021 at 8:25 PM
To: Christian König <ckoenig.leichtzumerken@gmail.com><mailto:ckoenig.leichtzumerken@gmail.com>, "amd-gfx@lists.freedesktop.org"<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org><mailto:amd-gfx@lists.freedesktop.org>
Cc: "Deucher, Alexander" <Alexander.Deucher@amd.com><mailto:Alexander.Deucher@amd.com>, "StDenis, Tom" <Tom.StDenis@amd.com><mailto:Tom.StDenis@amd.com>, "Nieto, David M" <David.Nieto@amd.com><mailto:David.Nieto@amd.com>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface


[AMD Official Use Only - Internal Distribution Only]

Hi Christian,
It will be used by a user space SMI-lib for GPU status query.

Hi David, please feel free to correct my statement since I'm not sure I have a view of whole picture.

Thanks,
Jiawei

From: Christian König <ckoenig.leichtzumerken@gmail.com><mailto:ckoenig.leichtzumerken@gmail.com>
Sent: Thursday, April 22, 2021 9:27 PM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>
Cc: Deucher, Alexander <Alexander.Deucher@amd.com><mailto:Alexander.Deucher@amd.com>; StDenis, Tom <Tom.StDenis@amd.com><mailto:Tom.StDenis@amd.com>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

Is that useful to Vulkan/OpenGL/other clients in any way?

Christian.
Am 22.04.21 um 15:18 schrieb Gu, JiaWei (Will):



CC Tom.



On Apr 22, 2021, at 21:09, Gu, JiaWei (Will) <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com> wrote:



<[v2][umr]add-vbios-info-query.patch>

UMR patch which calls this new IOCTL attached.



Best regards,

Jiawei



On Apr 22, 2021, at 10:34, Jiawei Gu <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com> wrote:



Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.



Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com><mailto:Jiawei.Gu@amd.com>

---

drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  19 +++

drivers/gpu/drm/amd/amdgpu/atom.c          | 158 +++++++++++++++++++++

drivers/gpu/drm/amd/amdgpu/atom.h          |  11 ++

drivers/gpu/drm/amd/include/atomfirmware.h |  16 ++-

include/uapi/drm/amdgpu_drm.h              |  15 ++

5 files changed, 213 insertions(+), 6 deletions(-)



diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

index 39ee88d29cca..a20b016b05ab 100644

--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

@@ -861,6 +861,25 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)

                                       min((size_t)size, (size_t)(bios_size - bios_offset)))

                                   ? -EFAULT : 0;

             }

+            case AMDGPU_INFO_VBIOS_INFO: {

+                   struct drm_amdgpu_info_vbios vbios_info = {};

+                   struct atom_context *atom_context;

+

+                   atom_context = adev->mode_info.atom_context;

+                 memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));

+                 vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);

+                 memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));

+                 vbios_info.version = atom_context->version;

+                 memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));

+                 memcpy(vbios_info.serial, adev->serial, sizeof(adev->serial));

+                 vbios_info.dev_id = adev->pdev->device;

+                 vbios_info.rev_id = adev->pdev->revision;

+                 vbios_info.sub_dev_id = atom_context->sub_dev_id;

+                 vbios_info.sub_ved_id = atom_context->sub_ved_id;

+

+                   return copy_to_user(out, &vbios_info,

+                                  min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;

+            }

             default:

                  DRM_DEBUG_KMS("Invalid request %d\n",

                            info->vbios_info.type);

diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c

index 3dcb8b32f48b..0e2f0ea13b40 100644

--- a/drivers/gpu/drm/amd/amdgpu/atom.c

+++ b/drivers/gpu/drm/amd/amdgpu/atom.c

@@ -31,6 +31,7 @@



#define ATOM_DEBUG



+#include "atomfirmware.h"

#include "atom.h"

#include "atom-names.h"

#include "atom-bits.h"

@@ -1299,12 +1300,153 @@ static void atom_index_iio(struct atom_context *ctx, int base)

     }

}



+static void atom_get_vbios_name(struct atom_context *ctx)

+{

+    unsigned char *p_rom;

+    unsigned char str_num;

+    unsigned short off_to_vbios_str;

+    unsigned char *c_ptr;

+    int name_size;

+    int i;

+

+    const char *na = "--N/A--";

+    char *back;

+

+    p_rom = ctx->bios;

+

+    str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);

+    if (str_num != 0) {

+            off_to_vbios_str =

+                   *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);

+

+            c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);

+    } else {

+            /* do not know where to find name */

+            memcpy(ctx->name, na, 7);

+            ctx->name[7] = 0;

+            return;

+    }

+

+    /*

+     * skip the atombios strings, usually 4

+     * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type

+     */

+    for (i = 0; i < str_num; i++) {

+            while (*c_ptr != 0)

+                   c_ptr++;

+            c_ptr++;

+    }

+

+    /* skip the following 2 chars: 0x0D 0x0A */

+    c_ptr += 2;

+

+    name_size = strnlen(c_ptr, STRLEN_LONG - 1);

+    memcpy(ctx->name, c_ptr, name_size);

+    back = ctx->name + name_size;

+    while ((*--back) == ' ')

+            ;

+    *(back + 1) = '\0';

+}

+

+static void atom_get_vbios_date(struct atom_context *ctx)

+{

+    unsigned char *p_rom;

+    unsigned char *date_in_rom;

+

+    p_rom = ctx->bios;

+

+    date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;

+

+    ctx->date[0] = '2';

+    ctx->date[1] = '0';

+    ctx->date[2] = date_in_rom[6];

+    ctx->date[3] = date_in_rom[7];

+    ctx->date[4] = '/';

+    ctx->date[5] = date_in_rom[0];

+    ctx->date[6] = date_in_rom[1];

+    ctx->date[7] = '/';

+    ctx->date[8] = date_in_rom[3];

+    ctx->date[9] = date_in_rom[4];

+    ctx->date[10] = ' ';

+    ctx->date[11] = date_in_rom[9];

+    ctx->date[12] = date_in_rom[10];

+    ctx->date[13] = date_in_rom[11];

+    ctx->date[14] = date_in_rom[12];

+    ctx->date[15] = date_in_rom[13];

+    ctx->date[16] = '\0';

+}

+

+static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,

+                                     int end, int maxlen)

+{

+    unsigned long str_off;

+    unsigned char *p_rom;

+    unsigned short str_len;

+

+    str_off = 0;

+    str_len = strnlen(str, maxlen);

+    p_rom = ctx->bios;

+

+    for (; start <= end; ++start) {

+            for (str_off = 0; str_off < str_len; ++str_off) {

+                   if (str[str_off] != *(p_rom + start + str_off))

+                        break;

+            }

+

+            if (str_off == str_len || str[str_off] == 0)

+                   return p_rom + start;

+    }

+    return NULL;

+}

+

+static void atom_get_vbios_pn(struct atom_context *ctx)

+{

+    unsigned char *p_rom;

+    unsigned short off_to_vbios_str;

+    unsigned char *vbios_str;

+    int count;

+

+    off_to_vbios_str = 0;

+    p_rom = ctx->bios;

+

+    if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {

+            off_to_vbios_str =

+                   *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);

+

+            vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);

+    } else {

+            vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;

+    }

+

+    if (*vbios_str == 0) {

+            vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);

+            if (vbios_str == NULL)

+                   vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;

+    }

+    if (vbios_str != NULL && *vbios_str == 0)

+            vbios_str++;

+

+    if (vbios_str != NULL) {

+            count = 0;

+            while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&

+                   vbios_str[count] <= 'z') {

+                 ctx->vbios_pn[count] = vbios_str[count];

+                   count++;

+            }

+

+            ctx->vbios_pn[count] = 0;

+    }

+}

+

struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)

{

     int base;

     struct atom_context *ctx =

         kzalloc(sizeof(struct atom_context), GFP_KERNEL);

     char *str;

+    struct _ATOM_ROM_HEADER *atom_rom_header;

+    struct _ATOM_MASTER_DATA_TABLE *master_table;

+    struct _ATOM_FIRMWARE_INFO *atom_fw_info;

     u16 idx;



     if (!ctx)

@@ -1353,6 +1495,22 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)

          strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));

     }



+    atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);

+    ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;

+    ctx->sub_ved_id = atom_rom_header->usSubsystemID;

+    if (atom_rom_header->usMasterDataTableOffset != 0) {

+            master_table = (struct _ATOM_MASTER_DATA_TABLE *)

+                    CSTR(atom_rom_header->usMasterDataTableOffset);

+            if (master_table->ListOfDataTables.FirmwareInfo != 0) {

+                   atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)

+                           CSTR(master_table->ListOfDataTables.FirmwareInfo);

+                   ctx->version = atom_fw_info->ulFirmwareRevision;

+            }

+    }

+

+    atom_get_vbios_name(ctx);

+    atom_get_vbios_pn(ctx);

+    atom_get_vbios_date(ctx);



     return ctx;

}

diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h

index d279759cab47..c729f7ceba4f 100644

--- a/drivers/gpu/drm/amd/amdgpu/atom.h

+++ b/drivers/gpu/drm/amd/amdgpu/atom.h

@@ -112,6 +112,10 @@ struct drm_device;

#define ATOM_IO_SYSIO              2

#define ATOM_IO_IIO         0x80



+#define STRLEN_NORMAL             32

+#define STRLEN_LONG        64

+#define STRLEN_VERYLONG           254

+

struct card_info {

     struct drm_device *dev;

     void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */

@@ -140,6 +144,13 @@ struct atom_context {

     uint32_t *scratch;

     int scratch_size_bytes;

     char vbios_version[20];

+

+    uint8_t name[STRLEN_LONG];

+    uint8_t vbios_pn[STRLEN_LONG];

+    uint32_t version;

+    uint8_t date[STRLEN_NORMAL];

+    uint32_t sub_dev_id;

+    uint32_t sub_ved_id;

};



extern int amdgpu_atom_debug;

diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h

index c77ed38c20fb..3a8e404099b0 100644

--- a/drivers/gpu/drm/amd/include/atomfirmware.h

+++ b/drivers/gpu/drm/amd/include/atomfirmware.h

@@ -197,6 +197,8 @@ enum atom_dp_vs_preemph_def{

 DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,

};



+#define BIOS_ATOM_PREFIX   "ATOMBIOS"

+#define BIOS_STRING_LENGTH 43



/*

enum atom_string_def{

@@ -209,12 +211,14 @@ atom_bios_string          = "ATOM"

#pragma pack(1)                          /* BIOS data must use byte aligment*/



enum atombios_image_offset{

-OFFSET_TO_ATOM_ROM_HEADER_POINTER          =0x00000048,

-OFFSET_TO_ATOM_ROM_IMAGE_SIZE              =0x00000002,

-OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       =0x94,

-MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      =20,  /*including the terminator 0x0!*/

-OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   =0x2f,

-OFFSET_TO_GET_ATOMBIOS_STRING_START        =0x6e,

+  OFFSET_TO_ATOM_ROM_HEADER_POINTER          = 0x00000048,

+  OFFSET_TO_ATOM_ROM_IMAGE_SIZE              = 0x00000002,

+  OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       = 0x94,

+  MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/

+  OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,

+  OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,

+  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,

+  OFFSET_TO_VBIOS_DATE                       = 0x50,

};



/****************************************************************************

diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h

index 8b832f7458f2..77980445d486 100644

--- a/include/uapi/drm/amdgpu_drm.h

+++ b/include/uapi/drm/amdgpu_drm.h

@@ -758,6 +758,8 @@ struct drm_amdgpu_cs_chunk_data {

     #define AMDGPU_INFO_VBIOS_SIZE             0x1

     /* Subquery id: Query vbios image */

     #define AMDGPU_INFO_VBIOS_IMAGE            0x2

+    /* Subquery id: Query vbios info */

+    #define AMDGPU_INFO_VBIOS_INFO             0x3

/* Query UVD handles */

#define AMDGPU_INFO_NUM_HANDLES                    0x1C

/* Query sensor related information */

@@ -951,6 +953,19 @@ struct drm_amdgpu_info_firmware {

     __u32 feature;

};



+struct drm_amdgpu_info_vbios {

+    __u8 name[64];

+    __u32 dbdf;

+    __u8 vbios_pn[64];

+    __u32 version;

+    __u8 date[32];

+    __u8 serial[16];

+    __u32 dev_id;

+    __u32 rev_id;

+    __u32 sub_dev_id;

+    __u32 sub_ved_id;

+};

+

#define AMDGPU_VRAM_TYPE_UNKNOWN 0

#define AMDGPU_VRAM_TYPE_GDDR1 1

#define AMDGPU_VRAM_TYPE_DDR2  2

--

2.17.1








_______________________________________________

amd-gfx mailing list

amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>

https://lists.freedesktop.org/mailman/listinfo/amd-gfx<https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=04%7C01%7CJiaWei.Gu%40amd.com%7Cfc8d3420d88745c257bf08d90a1934d6%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637551925654186287%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=Y9%2B4WCgVSr0pS%2Bdf5PzTCddGhjitFaCsNhp%2Fu%2F%2FnmII%3D&reserved=0>




[-- Attachment #1.2: Type: text/html, Size: 42511 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-04-28  7:42               ` Christian König
@ 2021-04-28  8:21                 ` Gu, JiaWei (Will)
  2021-04-28 10:38                   ` Gu, JiaWei (Will)
  0 siblings, 1 reply; 47+ messages in thread
From: Gu, JiaWei (Will) @ 2021-04-28  8:21 UTC (permalink / raw)
  To: Christian König, Nieto, David M, amd-gfx
  Cc: Deucher, Alexander, StDenis, Tom


[-- Attachment #1.1: Type: text/plain, Size: 18236 bytes --]

[AMD Official Use Only - Internal Distribution Only]

Thanks Christian,

I amended the commit message and resend the patch out.
Please feel free to let me know if message is not clear enough.

Best regards,
Jiawei

From: Christian König <ckoenig.leichtzumerken@gmail.com>
Sent: Wednesday, April 28, 2021 3:43 PM
To: Nieto, David M <David.Nieto@amd.com>; Gu, JiaWei (Will) <JiaWei.Gu@amd.com>; amd-gfx@lists.freedesktop.org
Cc: Deucher, Alexander <Alexander.Deucher@amd.com>; StDenis, Tom <Tom.StDenis@amd.com>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

Yeah, makes sense. Please note that in the commit message.

With that feel free to put an Acked-by: Christian König <christian.koenig@amd.com><mailto:christian.koenig@amd.com> on it.

Regards,
Christian.
Am 28.04.21 um 09:25 schrieb Nieto, David M:
I think this change may be orthogonal to that. Here we want to provide a way for the user application to get the VBIOS information without having to parse the binary...

And I agree that we should not have strong dependencies unless the encounter buggy VBIOS on the field, but I still think it is useful for the user to be able to display in a simple way the VBIOS version in their system if they happen to encounter an issue.

Regards,
David

From: Christian König <ckoenig.leichtzumerken@gmail.com><mailto:ckoenig.leichtzumerken@gmail.com>
Date: Wednesday, April 28, 2021 at 12:15 AM
To: "Nieto, David M" <David.Nieto@amd.com><mailto:David.Nieto@amd.com>, "Gu, JiaWei (Will)" <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com>, "amd-gfx@lists.freedesktop.org"<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org><mailto:amd-gfx@lists.freedesktop.org>
Cc: "Deucher, Alexander" <Alexander.Deucher@amd.com><mailto:Alexander.Deucher@amd.com>, "StDenis, Tom" <Tom.StDenis@amd.com><mailto:Tom.StDenis@amd.com>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

Well displaying the VBIOS information along with the other firmware in userspace is certainly useful.

We should just avoid making strong dependencies on that.

Firmware and VBIOS must always be backward compatible and the driver must always work with any released firmware and VBIOS combination.

What we can do is to display a warning when we detect and/or old/buggy firmware.

Regards,
Christian.
Am 28.04.21 um 08:47 schrieb Nieto, David M:
Besides system management, it provides parseable details on the VBIOS version and information. This is useful renderer information as the GPU behavior depends not only on the driver version but also on the firmwares running on the GPU.

The AMDGPU_INFO ioctl contains a method to get the versions of the ucode for all the IPs, but for VBIOS, only a way to dump the entire image is provided. While it Is possible to implement the whole logic of VBIOS parsing on userspace, it requires the application to have details on the header and table formats to parse the data. Moreover there is no guarantee that the format and header locations will remain constant across ASIC generations, so the maintainance cost and complexity seems unreasonable.

Providing a simple, and stable interface to the application seems to us like a sensible choice.

Thanks,
David

From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org><mailto:amd-gfx-bounces@lists.freedesktop.org> on behalf of "Gu, JiaWei (Will)" <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com>
Date: Thursday, April 22, 2021 at 8:25 PM
To: Christian König <ckoenig.leichtzumerken@gmail.com><mailto:ckoenig.leichtzumerken@gmail.com>, "amd-gfx@lists.freedesktop.org"<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org><mailto:amd-gfx@lists.freedesktop.org>
Cc: "Deucher, Alexander" <Alexander.Deucher@amd.com><mailto:Alexander.Deucher@amd.com>, "StDenis, Tom" <Tom.StDenis@amd.com><mailto:Tom.StDenis@amd.com>, "Nieto, David M" <David.Nieto@amd.com><mailto:David.Nieto@amd.com>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface


[AMD Official Use Only - Internal Distribution Only]

Hi Christian,
It will be used by a user space SMI-lib for GPU status query.

Hi David, please feel free to correct my statement since I'm not sure I have a view of whole picture.

Thanks,
Jiawei

From: Christian König <ckoenig.leichtzumerken@gmail.com><mailto:ckoenig.leichtzumerken@gmail.com>
Sent: Thursday, April 22, 2021 9:27 PM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>
Cc: Deucher, Alexander <Alexander.Deucher@amd.com><mailto:Alexander.Deucher@amd.com>; StDenis, Tom <Tom.StDenis@amd.com><mailto:Tom.StDenis@amd.com>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

Is that useful to Vulkan/OpenGL/other clients in any way?

Christian.
Am 22.04.21 um 15:18 schrieb Gu, JiaWei (Will):



CC Tom.



On Apr 22, 2021, at 21:09, Gu, JiaWei (Will) <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com> wrote:



<[v2][umr]add-vbios-info-query.patch>

UMR patch which calls this new IOCTL attached.



Best regards,

Jiawei



On Apr 22, 2021, at 10:34, Jiawei Gu <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com> wrote:



Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.



Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com><mailto:Jiawei.Gu@amd.com>

---

drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  19 +++

drivers/gpu/drm/amd/amdgpu/atom.c          | 158 +++++++++++++++++++++

drivers/gpu/drm/amd/amdgpu/atom.h          |  11 ++

drivers/gpu/drm/amd/include/atomfirmware.h |  16 ++-

include/uapi/drm/amdgpu_drm.h              |  15 ++

5 files changed, 213 insertions(+), 6 deletions(-)



diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

index 39ee88d29cca..a20b016b05ab 100644

--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

@@ -861,6 +861,25 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)

                                       min((size_t)size, (size_t)(bios_size - bios_offset)))

                                   ? -EFAULT : 0;

             }

+            case AMDGPU_INFO_VBIOS_INFO: {

+                   struct drm_amdgpu_info_vbios vbios_info = {};

+                   struct atom_context *atom_context;

+

+                   atom_context = adev->mode_info.atom_context;

+                 memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));

+                 vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);

+                 memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));

+                 vbios_info.version = atom_context->version;

+                 memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));

+                 memcpy(vbios_info.serial, adev->serial, sizeof(adev->serial));

+                 vbios_info.dev_id = adev->pdev->device;

+                 vbios_info.rev_id = adev->pdev->revision;

+                 vbios_info.sub_dev_id = atom_context->sub_dev_id;

+                 vbios_info.sub_ved_id = atom_context->sub_ved_id;

+

+                   return copy_to_user(out, &vbios_info,

+                                  min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;

+            }

             default:

                  DRM_DEBUG_KMS("Invalid request %d\n",

                            info->vbios_info.type);

diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c

index 3dcb8b32f48b..0e2f0ea13b40 100644

--- a/drivers/gpu/drm/amd/amdgpu/atom.c

+++ b/drivers/gpu/drm/amd/amdgpu/atom.c

@@ -31,6 +31,7 @@



#define ATOM_DEBUG



+#include "atomfirmware.h"

#include "atom.h"

#include "atom-names.h"

#include "atom-bits.h"

@@ -1299,12 +1300,153 @@ static void atom_index_iio(struct atom_context *ctx, int base)

     }

}



+static void atom_get_vbios_name(struct atom_context *ctx)

+{

+    unsigned char *p_rom;

+    unsigned char str_num;

+    unsigned short off_to_vbios_str;

+    unsigned char *c_ptr;

+    int name_size;

+    int i;

+

+    const char *na = "--N/A--";

+    char *back;

+

+    p_rom = ctx->bios;

+

+    str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);

+    if (str_num != 0) {

+            off_to_vbios_str =

+                   *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);

+

+            c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);

+    } else {

+            /* do not know where to find name */

+            memcpy(ctx->name, na, 7);

+            ctx->name[7] = 0;

+            return;

+    }

+

+    /*

+     * skip the atombios strings, usually 4

+     * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type

+     */

+    for (i = 0; i < str_num; i++) {

+            while (*c_ptr != 0)

+                   c_ptr++;

+            c_ptr++;

+    }

+

+    /* skip the following 2 chars: 0x0D 0x0A */

+    c_ptr += 2;

+

+    name_size = strnlen(c_ptr, STRLEN_LONG - 1);

+    memcpy(ctx->name, c_ptr, name_size);

+    back = ctx->name + name_size;

+    while ((*--back) == ' ')

+            ;

+    *(back + 1) = '\0';

+}

+

+static void atom_get_vbios_date(struct atom_context *ctx)

+{

+    unsigned char *p_rom;

+    unsigned char *date_in_rom;

+

+    p_rom = ctx->bios;

+

+    date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;

+

+    ctx->date[0] = '2';

+    ctx->date[1] = '0';

+    ctx->date[2] = date_in_rom[6];

+    ctx->date[3] = date_in_rom[7];

+    ctx->date[4] = '/';

+    ctx->date[5] = date_in_rom[0];

+    ctx->date[6] = date_in_rom[1];

+    ctx->date[7] = '/';

+    ctx->date[8] = date_in_rom[3];

+    ctx->date[9] = date_in_rom[4];

+    ctx->date[10] = ' ';

+    ctx->date[11] = date_in_rom[9];

+    ctx->date[12] = date_in_rom[10];

+    ctx->date[13] = date_in_rom[11];

+    ctx->date[14] = date_in_rom[12];

+    ctx->date[15] = date_in_rom[13];

+    ctx->date[16] = '\0';

+}

+

+static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,

+                                     int end, int maxlen)

+{

+    unsigned long str_off;

+    unsigned char *p_rom;

+    unsigned short str_len;

+

+    str_off = 0;

+    str_len = strnlen(str, maxlen);

+    p_rom = ctx->bios;

+

+    for (; start <= end; ++start) {

+            for (str_off = 0; str_off < str_len; ++str_off) {

+                   if (str[str_off] != *(p_rom + start + str_off))

+                        break;

+            }

+

+            if (str_off == str_len || str[str_off] == 0)

+                   return p_rom + start;

+    }

+    return NULL;

+}

+

+static void atom_get_vbios_pn(struct atom_context *ctx)

+{

+    unsigned char *p_rom;

+    unsigned short off_to_vbios_str;

+    unsigned char *vbios_str;

+    int count;

+

+    off_to_vbios_str = 0;

+    p_rom = ctx->bios;

+

+    if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {

+            off_to_vbios_str =

+                   *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);

+

+            vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);

+    } else {

+            vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;

+    }

+

+    if (*vbios_str == 0) {

+            vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);

+            if (vbios_str == NULL)

+                   vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;

+    }

+    if (vbios_str != NULL && *vbios_str == 0)

+            vbios_str++;

+

+    if (vbios_str != NULL) {

+            count = 0;

+            while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&

+                   vbios_str[count] <= 'z') {

+                 ctx->vbios_pn[count] = vbios_str[count];

+                   count++;

+            }

+

+            ctx->vbios_pn[count] = 0;

+    }

+}

+

struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)

{

     int base;

     struct atom_context *ctx =

         kzalloc(sizeof(struct atom_context), GFP_KERNEL);

     char *str;

+    struct _ATOM_ROM_HEADER *atom_rom_header;

+    struct _ATOM_MASTER_DATA_TABLE *master_table;

+    struct _ATOM_FIRMWARE_INFO *atom_fw_info;

     u16 idx;



     if (!ctx)

@@ -1353,6 +1495,22 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)

          strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));

     }



+    atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);

+    ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;

+    ctx->sub_ved_id = atom_rom_header->usSubsystemID;

+    if (atom_rom_header->usMasterDataTableOffset != 0) {

+            master_table = (struct _ATOM_MASTER_DATA_TABLE *)

+                    CSTR(atom_rom_header->usMasterDataTableOffset);

+            if (master_table->ListOfDataTables.FirmwareInfo != 0) {

+                   atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)

+                           CSTR(master_table->ListOfDataTables.FirmwareInfo);

+                   ctx->version = atom_fw_info->ulFirmwareRevision;

+            }

+    }

+

+    atom_get_vbios_name(ctx);

+    atom_get_vbios_pn(ctx);

+    atom_get_vbios_date(ctx);



     return ctx;

}

diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h

index d279759cab47..c729f7ceba4f 100644

--- a/drivers/gpu/drm/amd/amdgpu/atom.h

+++ b/drivers/gpu/drm/amd/amdgpu/atom.h

@@ -112,6 +112,10 @@ struct drm_device;

#define ATOM_IO_SYSIO              2

#define ATOM_IO_IIO         0x80



+#define STRLEN_NORMAL             32

+#define STRLEN_LONG        64

+#define STRLEN_VERYLONG           254

+

struct card_info {

     struct drm_device *dev;

     void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */

@@ -140,6 +144,13 @@ struct atom_context {

     uint32_t *scratch;

     int scratch_size_bytes;

     char vbios_version[20];

+

+    uint8_t name[STRLEN_LONG];

+    uint8_t vbios_pn[STRLEN_LONG];

+    uint32_t version;

+    uint8_t date[STRLEN_NORMAL];

+    uint32_t sub_dev_id;

+    uint32_t sub_ved_id;

};



extern int amdgpu_atom_debug;

diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h

index c77ed38c20fb..3a8e404099b0 100644

--- a/drivers/gpu/drm/amd/include/atomfirmware.h

+++ b/drivers/gpu/drm/amd/include/atomfirmware.h

@@ -197,6 +197,8 @@ enum atom_dp_vs_preemph_def{

 DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,

};



+#define BIOS_ATOM_PREFIX   "ATOMBIOS"

+#define BIOS_STRING_LENGTH 43



/*

enum atom_string_def{

@@ -209,12 +211,14 @@ atom_bios_string          = "ATOM"

#pragma pack(1)                          /* BIOS data must use byte aligment*/



enum atombios_image_offset{

-OFFSET_TO_ATOM_ROM_HEADER_POINTER          =0x00000048,

-OFFSET_TO_ATOM_ROM_IMAGE_SIZE              =0x00000002,

-OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       =0x94,

-MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      =20,  /*including the terminator 0x0!*/

-OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   =0x2f,

-OFFSET_TO_GET_ATOMBIOS_STRING_START        =0x6e,

+  OFFSET_TO_ATOM_ROM_HEADER_POINTER          = 0x00000048,

+  OFFSET_TO_ATOM_ROM_IMAGE_SIZE              = 0x00000002,

+  OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       = 0x94,

+  MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/

+  OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,

+  OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,

+  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,

+  OFFSET_TO_VBIOS_DATE                       = 0x50,

};



/****************************************************************************

diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h

index 8b832f7458f2..77980445d486 100644

--- a/include/uapi/drm/amdgpu_drm.h

+++ b/include/uapi/drm/amdgpu_drm.h

@@ -758,6 +758,8 @@ struct drm_amdgpu_cs_chunk_data {

     #define AMDGPU_INFO_VBIOS_SIZE             0x1

     /* Subquery id: Query vbios image */

     #define AMDGPU_INFO_VBIOS_IMAGE            0x2

+    /* Subquery id: Query vbios info */

+    #define AMDGPU_INFO_VBIOS_INFO             0x3

/* Query UVD handles */

#define AMDGPU_INFO_NUM_HANDLES                    0x1C

/* Query sensor related information */

@@ -951,6 +953,19 @@ struct drm_amdgpu_info_firmware {

     __u32 feature;

};



+struct drm_amdgpu_info_vbios {

+    __u8 name[64];

+    __u32 dbdf;

+    __u8 vbios_pn[64];

+    __u32 version;

+    __u8 date[32];

+    __u8 serial[16];

+    __u32 dev_id;

+    __u32 rev_id;

+    __u32 sub_dev_id;

+    __u32 sub_ved_id;

+};

+

#define AMDGPU_VRAM_TYPE_UNKNOWN 0

#define AMDGPU_VRAM_TYPE_GDDR1 1

#define AMDGPU_VRAM_TYPE_DDR2  2

--

2.17.1








_______________________________________________

amd-gfx mailing list

amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>

https://lists.freedesktop.org/mailman/listinfo/amd-gfx<https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=04%7C01%7CJiaWei.Gu%40amd.com%7Cfc8d3420d88745c257bf08d90a1934d6%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637551925654186287%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=Y9%2B4WCgVSr0pS%2Bdf5PzTCddGhjitFaCsNhp%2Fu%2F%2FnmII%3D&reserved=0>





[-- Attachment #1.2: Type: text/html, Size: 40753 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH] drm/amdgpu: Add vbios info ioctl interface
@ 2021-04-28  8:18 Jiawei Gu
  0 siblings, 0 replies; 47+ messages in thread
From: Jiawei Gu @ 2021-04-28  8:18 UTC (permalink / raw)
  To: amd-gfx; +Cc: Jiawei Gu, christian.koenig, david.nieto

Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.

Provides a way for the user application to get the VBIOS
information without having to parse the binary.
It is useful for the user to be able to display in a simple way the VBIOS
version in their system if they happen to encounter an issue.

Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  19 +++
 drivers/gpu/drm/amd/amdgpu/atom.c          | 158 +++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/atom.h          |  11 ++
 drivers/gpu/drm/amd/include/atomfirmware.h |  16 ++-
 include/uapi/drm/amdgpu_drm.h              |  15 ++
 5 files changed, 213 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 39ee88d29cca..a20b016b05ab 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -861,6 +861,25 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
 					    min((size_t)size, (size_t)(bios_size - bios_offset)))
 					? -EFAULT : 0;
 		}
+		case AMDGPU_INFO_VBIOS_INFO: {
+			struct drm_amdgpu_info_vbios vbios_info = {};
+			struct atom_context *atom_context;
+
+			atom_context = adev->mode_info.atom_context;
+			memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
+			vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
+			memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
+			vbios_info.version = atom_context->version;
+			memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
+			memcpy(vbios_info.serial, adev->serial, sizeof(adev->serial));
+			vbios_info.dev_id = adev->pdev->device;
+			vbios_info.rev_id = adev->pdev->revision;
+			vbios_info.sub_dev_id = atom_context->sub_dev_id;
+			vbios_info.sub_ved_id = atom_context->sub_ved_id;
+
+			return copy_to_user(out, &vbios_info,
+						min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
+		}
 		default:
 			DRM_DEBUG_KMS("Invalid request %d\n",
 					info->vbios_info.type);
diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c
index 3dcb8b32f48b..0e2f0ea13b40 100644
--- a/drivers/gpu/drm/amd/amdgpu/atom.c
+++ b/drivers/gpu/drm/amd/amdgpu/atom.c
@@ -31,6 +31,7 @@
 
 #define ATOM_DEBUG
 
+#include "atomfirmware.h"
 #include "atom.h"
 #include "atom-names.h"
 #include "atom-bits.h"
@@ -1299,12 +1300,153 @@ static void atom_index_iio(struct atom_context *ctx, int base)
 	}
 }
 
+static void atom_get_vbios_name(struct atom_context *ctx)
+{
+	unsigned char *p_rom;
+	unsigned char str_num;
+	unsigned short off_to_vbios_str;
+	unsigned char *c_ptr;
+	int name_size;
+	int i;
+
+	const char *na = "--N/A--";
+	char *back;
+
+	p_rom = ctx->bios;
+
+	str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
+	if (str_num != 0) {
+		off_to_vbios_str =
+			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
+
+		c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
+	} else {
+		/* do not know where to find name */
+		memcpy(ctx->name, na, 7);
+		ctx->name[7] = 0;
+		return;
+	}
+
+	/*
+	 * skip the atombios strings, usually 4
+	 * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
+	 */
+	for (i = 0; i < str_num; i++) {
+		while (*c_ptr != 0)
+			c_ptr++;
+		c_ptr++;
+	}
+
+	/* skip the following 2 chars: 0x0D 0x0A */
+	c_ptr += 2;
+
+	name_size = strnlen(c_ptr, STRLEN_LONG - 1);
+	memcpy(ctx->name, c_ptr, name_size);
+	back = ctx->name + name_size;
+	while ((*--back) == ' ')
+		;
+	*(back + 1) = '\0';
+}
+
+static void atom_get_vbios_date(struct atom_context *ctx)
+{
+	unsigned char *p_rom;
+	unsigned char *date_in_rom;
+
+	p_rom = ctx->bios;
+
+	date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
+
+	ctx->date[0] = '2';
+	ctx->date[1] = '0';
+	ctx->date[2] = date_in_rom[6];
+	ctx->date[3] = date_in_rom[7];
+	ctx->date[4] = '/';
+	ctx->date[5] = date_in_rom[0];
+	ctx->date[6] = date_in_rom[1];
+	ctx->date[7] = '/';
+	ctx->date[8] = date_in_rom[3];
+	ctx->date[9] = date_in_rom[4];
+	ctx->date[10] = ' ';
+	ctx->date[11] = date_in_rom[9];
+	ctx->date[12] = date_in_rom[10];
+	ctx->date[13] = date_in_rom[11];
+	ctx->date[14] = date_in_rom[12];
+	ctx->date[15] = date_in_rom[13];
+	ctx->date[16] = '\0';
+}
+
+static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
+					   int end, int maxlen)
+{
+	unsigned long str_off;
+	unsigned char *p_rom;
+	unsigned short str_len;
+
+	str_off = 0;
+	str_len = strnlen(str, maxlen);
+	p_rom = ctx->bios;
+
+	for (; start <= end; ++start) {
+		for (str_off = 0; str_off < str_len; ++str_off) {
+			if (str[str_off] != *(p_rom + start + str_off))
+				break;
+		}
+
+		if (str_off == str_len || str[str_off] == 0)
+			return p_rom + start;
+	}
+	return NULL;
+}
+
+static void atom_get_vbios_pn(struct atom_context *ctx)
+{
+	unsigned char *p_rom;
+	unsigned short off_to_vbios_str;
+	unsigned char *vbios_str;
+	int count;
+
+	off_to_vbios_str = 0;
+	p_rom = ctx->bios;
+
+	if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
+		off_to_vbios_str =
+			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
+
+		vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
+	} else {
+		vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
+	}
+
+	if (*vbios_str == 0) {
+		vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
+		if (vbios_str == NULL)
+			vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
+	}
+	if (vbios_str != NULL && *vbios_str == 0)
+		vbios_str++;
+
+	if (vbios_str != NULL) {
+		count = 0;
+		while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
+		       vbios_str[count] <= 'z') {
+			ctx->vbios_pn[count] = vbios_str[count];
+			count++;
+		}
+
+		ctx->vbios_pn[count] = 0;
+	}
+}
+
 struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
 {
 	int base;
 	struct atom_context *ctx =
 	    kzalloc(sizeof(struct atom_context), GFP_KERNEL);
 	char *str;
+	struct _ATOM_ROM_HEADER *atom_rom_header;
+	struct _ATOM_MASTER_DATA_TABLE *master_table;
+	struct _ATOM_FIRMWARE_INFO *atom_fw_info;
 	u16 idx;
 
 	if (!ctx)
@@ -1353,6 +1495,22 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
 		strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
 	}
 
+	atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
+	ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
+	ctx->sub_ved_id = atom_rom_header->usSubsystemID;
+	if (atom_rom_header->usMasterDataTableOffset != 0) {
+		master_table = (struct _ATOM_MASTER_DATA_TABLE *)
+				CSTR(atom_rom_header->usMasterDataTableOffset);
+		if (master_table->ListOfDataTables.FirmwareInfo != 0) {
+			atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
+					CSTR(master_table->ListOfDataTables.FirmwareInfo);
+			ctx->version = atom_fw_info->ulFirmwareRevision;
+		}
+	}
+
+	atom_get_vbios_name(ctx);
+	atom_get_vbios_pn(ctx);
+	atom_get_vbios_date(ctx);
 
 	return ctx;
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h
index d279759cab47..c729f7ceba4f 100644
--- a/drivers/gpu/drm/amd/amdgpu/atom.h
+++ b/drivers/gpu/drm/amd/amdgpu/atom.h
@@ -112,6 +112,10 @@ struct drm_device;
 #define ATOM_IO_SYSIO		2
 #define ATOM_IO_IIO		0x80
 
+#define STRLEN_NORMAL		32
+#define STRLEN_LONG		64
+#define STRLEN_VERYLONG		254
+
 struct card_info {
 	struct drm_device *dev;
 	void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
@@ -140,6 +144,13 @@ struct atom_context {
 	uint32_t *scratch;
 	int scratch_size_bytes;
 	char vbios_version[20];
+
+	uint8_t name[STRLEN_LONG];
+	uint8_t vbios_pn[STRLEN_LONG];
+	uint32_t version;
+	uint8_t date[STRLEN_NORMAL];
+	uint32_t sub_dev_id;
+	uint32_t sub_ved_id;
 };
 
 extern int amdgpu_atom_debug;
diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
index c77ed38c20fb..3a8e404099b0 100644
--- a/drivers/gpu/drm/amd/include/atomfirmware.h
+++ b/drivers/gpu/drm/amd/include/atomfirmware.h
@@ -197,6 +197,8 @@ enum atom_dp_vs_preemph_def{
   DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
 };
 
+#define BIOS_ATOM_PREFIX   "ATOMBIOS"
+#define BIOS_STRING_LENGTH 43
 
 /*
 enum atom_string_def{
@@ -209,12 +211,14 @@ atom_bios_string          = "ATOM"
 #pragma pack(1)                          /* BIOS data must use byte aligment*/
 
 enum atombios_image_offset{
-OFFSET_TO_ATOM_ROM_HEADER_POINTER          =0x00000048,
-OFFSET_TO_ATOM_ROM_IMAGE_SIZE              =0x00000002,
-OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       =0x94,
-MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      =20,  /*including the terminator 0x0!*/
-OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   =0x2f,
-OFFSET_TO_GET_ATOMBIOS_STRING_START        =0x6e,
+  OFFSET_TO_ATOM_ROM_HEADER_POINTER          = 0x00000048,
+  OFFSET_TO_ATOM_ROM_IMAGE_SIZE              = 0x00000002,
+  OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       = 0x94,
+  MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
+  OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
+  OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
+  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
+  OFFSET_TO_VBIOS_DATE                       = 0x50,
 };
 
 /****************************************************************************   
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index 8b832f7458f2..77980445d486 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -758,6 +758,8 @@ struct drm_amdgpu_cs_chunk_data {
 	#define AMDGPU_INFO_VBIOS_SIZE		0x1
 	/* Subquery id: Query vbios image */
 	#define AMDGPU_INFO_VBIOS_IMAGE		0x2
+	/* Subquery id: Query vbios info */
+	#define AMDGPU_INFO_VBIOS_INFO		0x3
 /* Query UVD handles */
 #define AMDGPU_INFO_NUM_HANDLES			0x1C
 /* Query sensor related information */
@@ -951,6 +953,19 @@ struct drm_amdgpu_info_firmware {
 	__u32 feature;
 };
 
+struct drm_amdgpu_info_vbios {
+	__u8 name[64];
+	__u32 dbdf;
+	__u8 vbios_pn[64];
+	__u32 version;
+	__u8 date[32];
+	__u8 serial[16];
+	__u32 dev_id;
+	__u32 rev_id;
+	__u32 sub_dev_id;
+	__u32 sub_ved_id;
+};
+
 #define AMDGPU_VRAM_TYPE_UNKNOWN 0
 #define AMDGPU_VRAM_TYPE_GDDR1 1
 #define AMDGPU_VRAM_TYPE_DDR2  2
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-04-28  7:25             ` Nieto, David M
@ 2021-04-28  7:42               ` Christian König
  2021-04-28  8:21                 ` Gu, JiaWei (Will)
  0 siblings, 1 reply; 47+ messages in thread
From: Christian König @ 2021-04-28  7:42 UTC (permalink / raw)
  To: Nieto, David M, Gu, JiaWei (Will), amd-gfx
  Cc: Deucher, Alexander, StDenis, Tom


[-- Attachment #1.1: Type: text/plain, Size: 25337 bytes --]

Yeah, makes sense. Please note that in the commit message.

With that feel free to put an Acked-by: Christian König 
<christian.koenig@amd.com> on it.

Regards,
Christian.

Am 28.04.21 um 09:25 schrieb Nieto, David M:
>
> I think this change may be orthogonal to that. Here we want to provide 
> a way for the user application to get the VBIOS information without 
> having to parse the binary…
>
> And I agree that we should not have strong dependencies unless the 
> encounter buggy VBIOS on the field, but I still think it is useful for 
> the user to be able to display in a simple way the VBIOS version in 
> their system if they happen to encounter an issue.
>
> Regards,
>
> David
>
> *From: *Christian König <ckoenig.leichtzumerken@gmail.com>
> *Date: *Wednesday, April 28, 2021 at 12:15 AM
> *To: *"Nieto, David M" <David.Nieto@amd.com>, "Gu, JiaWei (Will)" 
> <JiaWei.Gu@amd.com>, "amd-gfx@lists.freedesktop.org" 
> <amd-gfx@lists.freedesktop.org>
> *Cc: *"Deucher, Alexander" <Alexander.Deucher@amd.com>, "StDenis, Tom" 
> <Tom.StDenis@amd.com>
> *Subject: *Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> Well displaying the VBIOS information along with the other firmware in 
> userspace is certainly useful.
>
> We should just avoid making strong dependencies on that.
>
> Firmware and VBIOS must always be backward compatible and the driver 
> must always work with any released firmware and VBIOS combination.
>
> What we can do is to display a warning when we detect and/or old/buggy 
> firmware.
>
> Regards,
> Christian.
>
> Am 28.04.21 um 08:47 schrieb Nieto, David M:
>
>     Besides system management, it provides parseable details on the
>     VBIOS version and information. This is useful renderer information
>     as the GPU behavior depends not only on the driver version but
>     also on the firmwares running on the GPU.
>
>     The AMDGPU_INFO ioctl contains a method to get the versions of the
>     ucode for all the IPs, but for VBIOS, only a way to dump the
>     entire image is provided. While it Is possible to implement the
>     whole logic of VBIOS parsing on userspace, it requires the
>     application to have details on the header and table formats to
>     parse the data. Moreover there is no guarantee that the format and
>     header locations will remain constant across ASIC generations, so
>     the maintainance cost and complexity seems unreasonable.
>
>     Providing a simple, and stable interface to the application seems
>     to us like a sensible choice.
>
>     Thanks,
>
>     David
>
>     *From: *amd-gfx <amd-gfx-bounces@lists.freedesktop.org>
>     <mailto:amd-gfx-bounces@lists.freedesktop.org> on behalf of "Gu,
>     JiaWei (Will)" <JiaWei.Gu@amd.com> <mailto:JiaWei.Gu@amd.com>
>     *Date: *Thursday, April 22, 2021 at 8:25 PM
>     *To: *Christian König <ckoenig.leichtzumerken@gmail.com>
>     <mailto:ckoenig.leichtzumerken@gmail.com>,
>     "amd-gfx@lists.freedesktop.org"
>     <mailto:amd-gfx@lists.freedesktop.org>
>     <amd-gfx@lists.freedesktop.org> <mailto:amd-gfx@lists.freedesktop.org>
>     *Cc: *"Deucher, Alexander" <Alexander.Deucher@amd.com>
>     <mailto:Alexander.Deucher@amd.com>, "StDenis, Tom"
>     <Tom.StDenis@amd.com> <mailto:Tom.StDenis@amd.com>, "Nieto, David
>     M" <David.Nieto@amd.com> <mailto:David.Nieto@amd.com>
>     *Subject: *RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
>     [AMD Official Use Only - Internal Distribution Only]
>
>     Hi Christian,
>
>     It will be used by a user space SMI-lib for GPU status query.
>
>     Hi David, please feel free to correct my statement since I’m not
>     sure I have a view of whole picture.
>
>     Thanks,
>
>     Jiawei
>
>     *From:* Christian König <ckoenig.leichtzumerken@gmail.com>
>     <mailto:ckoenig.leichtzumerken@gmail.com>
>     *Sent:* Thursday, April 22, 2021 9:27 PM
>     *To:* Gu, JiaWei (Will) <JiaWei.Gu@amd.com>
>     <mailto:JiaWei.Gu@amd.com>; amd-gfx@lists.freedesktop.org
>     <mailto:amd-gfx@lists.freedesktop.org>
>     *Cc:* Deucher, Alexander <Alexander.Deucher@amd.com>
>     <mailto:Alexander.Deucher@amd.com>; StDenis, Tom
>     <Tom.StDenis@amd.com> <mailto:Tom.StDenis@amd.com>
>     *Subject:* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
>     Is that useful to Vulkan/OpenGL/other clients in any way?
>
>     Christian.
>
>     Am 22.04.21 um 15:18 schrieb Gu, JiaWei (Will):
>
>           
>
>         CC Tom.
>
>           
>
>             On Apr 22, 2021, at 21:09, Gu, JiaWei (Will)<JiaWei.Gu@amd.com>  <mailto:JiaWei.Gu@amd.com>  wrote:
>
>               
>
>             <[v2][umr]add-vbios-info-query.patch>
>
>             UMR patch which calls this new IOCTL attached.
>
>               
>
>             Best regards,
>
>             Jiawei
>
>               
>
>                 On Apr 22, 2021, at 10:34, Jiawei Gu<JiaWei.Gu@amd.com>  <mailto:JiaWei.Gu@amd.com>  wrote:
>
>                   
>
>                 Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.
>
>                   
>
>                 Signed-off-by: Jiawei Gu<Jiawei.Gu@amd.com>  <mailto:Jiawei.Gu@amd.com>
>
>                 ---
>
>                 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  19 +++
>
>                 drivers/gpu/drm/amd/amdgpu/atom.c          | 158 +++++++++++++++++++++
>
>                 drivers/gpu/drm/amd/amdgpu/atom.h          |  11 ++
>
>                 drivers/gpu/drm/amd/include/atomfirmware.h |  16 ++-
>
>                 include/uapi/drm/amdgpu_drm.h              |  15 ++
>
>                 5 files changed, 213 insertions(+), 6 deletions(-)
>
>                   
>
>                 diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>
>                 index 39ee88d29cca..a20b016b05ab 100644
>
>                 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>
>                 +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>
>                 @@ -861,6 +861,25 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
>
>                                                         min((size_t)size, (size_t)(bios_size - bios_offset)))
>
>                                                     ? -EFAULT : 0;
>
>                               }
>
>                 +            case AMDGPU_INFO_VBIOS_INFO: {
>
>                 +                   struct drm_amdgpu_info_vbios vbios_info = {};
>
>                 +                   struct atom_context *atom_context;
>
>                 +
>
>                 +                   atom_context = adev->mode_info.atom_context;
>
>                 +                 memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
>
>                 +                 vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
>
>                 +                 memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
>
>                 +                 vbios_info.version = atom_context->version;
>
>                 +                 memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
>
>                 +                 memcpy(vbios_info.serial, adev->serial, sizeof(adev->serial));
>
>                 +                 vbios_info.dev_id = adev->pdev->device;
>
>                 +                 vbios_info.rev_id = adev->pdev->revision;
>
>                 +                 vbios_info.sub_dev_id = atom_context->sub_dev_id;
>
>                 +                 vbios_info.sub_ved_id = atom_context->sub_ved_id;
>
>                 +
>
>                 +                   return copy_to_user(out, &vbios_info,
>
>                 +                                  min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
>
>                 +            }
>
>                               default:
>
>                                    DRM_DEBUG_KMS("Invalid request %d\n",
>
>                                              info->vbios_info.type);
>
>                 diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c
>
>                 index 3dcb8b32f48b..0e2f0ea13b40 100644
>
>                 --- a/drivers/gpu/drm/amd/amdgpu/atom.c
>
>                 +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
>
>                 @@ -31,6 +31,7 @@
>
>                   
>
>                 #define ATOM_DEBUG
>
>                   
>
>                 +#include "atomfirmware.h"
>
>                 #include "atom.h"
>
>                 #include "atom-names.h"
>
>                 #include "atom-bits.h"
>
>                 @@ -1299,12 +1300,153 @@ static void atom_index_iio(struct atom_context *ctx, int base)
>
>                       }
>
>                 }
>
>                   
>
>                 +static void atom_get_vbios_name(struct atom_context *ctx)
>
>                 +{
>
>                 +    unsigned char *p_rom;
>
>                 +    unsigned char str_num;
>
>                 +    unsigned short off_to_vbios_str;
>
>                 +    unsigned char *c_ptr;
>
>                 +    int name_size;
>
>                 +    int i;
>
>                 +
>
>                 +    const char *na = "--N/A--";
>
>                 +    char *back;
>
>                 +
>
>                 +    p_rom = ctx->bios;
>
>                 +
>
>                 +    str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
>
>                 +    if (str_num != 0) {
>
>                 +            off_to_vbios_str =
>
>                 +                   *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
>
>                 +
>
>                 +            c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
>
>                 +    } else {
>
>                 +            /* do not know where to find name */
>
>                 +            memcpy(ctx->name, na, 7);
>
>                 +            ctx->name[7] = 0;
>
>                 +            return;
>
>                 +    }
>
>                 +
>
>                 +    /*
>
>                 +     * skip the atombios strings, usually 4
>
>                 +     * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
>
>                 +     */
>
>                 +    for (i = 0; i < str_num; i++) {
>
>                 +            while (*c_ptr != 0)
>
>                 +                   c_ptr++;
>
>                 +            c_ptr++;
>
>                 +    }
>
>                 +
>
>                 +    /* skip the following 2 chars: 0x0D 0x0A */
>
>                 +    c_ptr += 2;
>
>                 +
>
>                 +    name_size = strnlen(c_ptr, STRLEN_LONG - 1);
>
>                 +    memcpy(ctx->name, c_ptr, name_size);
>
>                 +    back = ctx->name + name_size;
>
>                 +    while ((*--back) == ' ')
>
>                 +            ;
>
>                 +    *(back + 1) = '\0';
>
>                 +}
>
>                 +
>
>                 +static void atom_get_vbios_date(struct atom_context *ctx)
>
>                 +{
>
>                 +    unsigned char *p_rom;
>
>                 +    unsigned char *date_in_rom;
>
>                 +
>
>                 +    p_rom = ctx->bios;
>
>                 +
>
>                 +    date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
>
>                 +
>
>                 +    ctx->date[0] = '2';
>
>                 +    ctx->date[1] = '0';
>
>                 +    ctx->date[2] = date_in_rom[6];
>
>                 +    ctx->date[3] = date_in_rom[7];
>
>                 +    ctx->date[4] = '/';
>
>                 +    ctx->date[5] = date_in_rom[0];
>
>                 +    ctx->date[6] = date_in_rom[1];
>
>                 +    ctx->date[7] = '/';
>
>                 +    ctx->date[8] = date_in_rom[3];
>
>                 +    ctx->date[9] = date_in_rom[4];
>
>                 +    ctx->date[10] = ' ';
>
>                 +    ctx->date[11] = date_in_rom[9];
>
>                 +    ctx->date[12] = date_in_rom[10];
>
>                 +    ctx->date[13] = date_in_rom[11];
>
>                 +    ctx->date[14] = date_in_rom[12];
>
>                 +    ctx->date[15] = date_in_rom[13];
>
>                 +    ctx->date[16] = '\0';
>
>                 +}
>
>                 +
>
>                 +static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
>
>                 +                                     int end, int maxlen)
>
>                 +{
>
>                 +    unsigned long str_off;
>
>                 +    unsigned char *p_rom;
>
>                 +    unsigned short str_len;
>
>                 +
>
>                 +    str_off = 0;
>
>                 +    str_len = strnlen(str, maxlen);
>
>                 +    p_rom = ctx->bios;
>
>                 +
>
>                 +    for (; start <= end; ++start) {
>
>                 +            for (str_off = 0; str_off < str_len; ++str_off) {
>
>                 +                   if (str[str_off] != *(p_rom + start + str_off))
>
>                 +                        break;
>
>                 +            }
>
>                 +
>
>                 +            if (str_off == str_len || str[str_off] == 0)
>
>                 +                   return p_rom + start;
>
>                 +    }
>
>                 +    return NULL;
>
>                 +}
>
>                 +
>
>                 +static void atom_get_vbios_pn(struct atom_context *ctx)
>
>                 +{
>
>                 +    unsigned char *p_rom;
>
>                 +    unsigned short off_to_vbios_str;
>
>                 +    unsigned char *vbios_str;
>
>                 +    int count;
>
>                 +
>
>                 +    off_to_vbios_str = 0;
>
>                 +    p_rom = ctx->bios;
>
>                 +
>
>                 +    if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
>
>                 +            off_to_vbios_str =
>
>                 +                   *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
>
>                 +
>
>                 +            vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
>
>                 +    } else {
>
>                 +            vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
>
>                 +    }
>
>                 +
>
>                 +    if (*vbios_str == 0) {
>
>                 +            vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
>
>                 +            if (vbios_str == NULL)
>
>                 +                   vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
>
>                 +    }
>
>                 +    if (vbios_str != NULL && *vbios_str == 0)
>
>                 +            vbios_str++;
>
>                 +
>
>                 +    if (vbios_str != NULL) {
>
>                 +            count = 0;
>
>                 +            while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
>
>                 +                   vbios_str[count] <= 'z') {
>
>                 +                 ctx->vbios_pn[count] = vbios_str[count];
>
>                 +                   count++;
>
>                 +            }
>
>                 +
>
>                 +            ctx->vbios_pn[count] = 0;
>
>                 +    }
>
>                 +}
>
>                 +
>
>                 struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>
>                 {
>
>                       int base;
>
>                       struct atom_context *ctx =
>
>                           kzalloc(sizeof(struct atom_context), GFP_KERNEL);
>
>                       char *str;
>
>                 +    struct _ATOM_ROM_HEADER *atom_rom_header;
>
>                 +    struct _ATOM_MASTER_DATA_TABLE *master_table;
>
>                 +    struct _ATOM_FIRMWARE_INFO *atom_fw_info;
>
>                       u16 idx;
>
>                   
>
>                       if (!ctx)
>
>                 @@ -1353,6 +1495,22 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>
>                            strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
>
>                       }
>
>                   
>
>                 +    atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
>
>                 +    ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
>
>                 +    ctx->sub_ved_id = atom_rom_header->usSubsystemID;
>
>                 +    if (atom_rom_header->usMasterDataTableOffset != 0) {
>
>                 +            master_table = (struct _ATOM_MASTER_DATA_TABLE *)
>
>                 +                    CSTR(atom_rom_header->usMasterDataTableOffset);
>
>                 +            if (master_table->ListOfDataTables.FirmwareInfo != 0) {
>
>                 +                   atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
>
>                 +                           CSTR(master_table->ListOfDataTables.FirmwareInfo);
>
>                 +                   ctx->version = atom_fw_info->ulFirmwareRevision;
>
>                 +            }
>
>                 +    }
>
>                 +
>
>                 +    atom_get_vbios_name(ctx);
>
>                 +    atom_get_vbios_pn(ctx);
>
>                 +    atom_get_vbios_date(ctx);
>
>                   
>
>                       return ctx;
>
>                 }
>
>                 diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h
>
>                 index d279759cab47..c729f7ceba4f 100644
>
>                 --- a/drivers/gpu/drm/amd/amdgpu/atom.h
>
>                 +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
>
>                 @@ -112,6 +112,10 @@ struct drm_device;
>
>                 #define ATOM_IO_SYSIO              2
>
>                 #define ATOM_IO_IIO         0x80
>
>                   
>
>                 +#define STRLEN_NORMAL             32
>
>                 +#define STRLEN_LONG        64
>
>                 +#define STRLEN_VERYLONG           254
>
>                 +
>
>                 struct card_info {
>
>                       struct drm_device *dev;
>
>                       void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
>
>                 @@ -140,6 +144,13 @@ struct atom_context {
>
>                       uint32_t *scratch;
>
>                       int scratch_size_bytes;
>
>                       char vbios_version[20];
>
>                 +
>
>                 +    uint8_t name[STRLEN_LONG];
>
>                 +    uint8_t vbios_pn[STRLEN_LONG];
>
>                 +    uint32_t version;
>
>                 +    uint8_t date[STRLEN_NORMAL];
>
>                 +    uint32_t sub_dev_id;
>
>                 +    uint32_t sub_ved_id;
>
>                 };
>
>                   
>
>                 extern int amdgpu_atom_debug;
>
>                 diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
>
>                 index c77ed38c20fb..3a8e404099b0 100644
>
>                 --- a/drivers/gpu/drm/amd/include/atomfirmware.h
>
>                 +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
>
>                 @@ -197,6 +197,8 @@ enum atom_dp_vs_preemph_def{
>
>                   DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
>
>                 };
>
>                   
>
>                 +#define BIOS_ATOM_PREFIX   "ATOMBIOS"
>
>                 +#define BIOS_STRING_LENGTH 43
>
>                   
>
>                 /*
>
>                 enum atom_string_def{
>
>                 @@ -209,12 +211,14 @@ atom_bios_string          = "ATOM"
>
>                 #pragma pack(1)                          /* BIOS data must use byte aligment*/
>
>                   
>
>                 enum atombios_image_offset{
>
>                 -OFFSET_TO_ATOM_ROM_HEADER_POINTER          =0x00000048,
>
>                 -OFFSET_TO_ATOM_ROM_IMAGE_SIZE              =0x00000002,
>
>                 -OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       =0x94,
>
>                 -MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      =20,  /*including the terminator 0x0!*/
>
>                 -OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   =0x2f,
>
>                 -OFFSET_TO_GET_ATOMBIOS_STRING_START        =0x6e,
>
>                 +  OFFSET_TO_ATOM_ROM_HEADER_POINTER          = 0x00000048,
>
>                 +  OFFSET_TO_ATOM_ROM_IMAGE_SIZE              = 0x00000002,
>
>                 +  OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       = 0x94,
>
>                 +  MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
>
>                 +  OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
>
>                 +  OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
>
>                 +  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
>
>                 +  OFFSET_TO_VBIOS_DATE                       = 0x50,
>
>                 };
>
>                   
>
>                 /****************************************************************************
>
>                 diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
>
>                 index 8b832f7458f2..77980445d486 100644
>
>                 --- a/include/uapi/drm/amdgpu_drm.h
>
>                 +++ b/include/uapi/drm/amdgpu_drm.h
>
>                 @@ -758,6 +758,8 @@ struct drm_amdgpu_cs_chunk_data {
>
>                       #define AMDGPU_INFO_VBIOS_SIZE             0x1
>
>                       /* Subquery id: Query vbios image */
>
>                       #define AMDGPU_INFO_VBIOS_IMAGE            0x2
>
>                 +    /* Subquery id: Query vbios info */
>
>                 +    #define AMDGPU_INFO_VBIOS_INFO             0x3
>
>                 /* Query UVD handles */
>
>                 #define AMDGPU_INFO_NUM_HANDLES                    0x1C
>
>                 /* Query sensor related information */
>
>                 @@ -951,6 +953,19 @@ struct drm_amdgpu_info_firmware {
>
>                       __u32 feature;
>
>                 };
>
>                   
>
>                 +struct drm_amdgpu_info_vbios {
>
>                 +    __u8 name[64];
>
>                 +    __u32 dbdf;
>
>                 +    __u8 vbios_pn[64];
>
>                 +    __u32 version;
>
>                 +    __u8 date[32];
>
>                 +    __u8 serial[16];
>
>                 +    __u32 dev_id;
>
>                 +    __u32 rev_id;
>
>                 +    __u32 sub_dev_id;
>
>                 +    __u32 sub_ved_id;
>
>                 +};
>
>                 +
>
>                 #define AMDGPU_VRAM_TYPE_UNKNOWN 0
>
>                 #define AMDGPU_VRAM_TYPE_GDDR1 1
>
>                 #define AMDGPU_VRAM_TYPE_DDR2  2
>
>                 -- 
>
>                 2.17.1
>
>                   
>
>               
>
>           
>
>         _______________________________________________
>
>         amd-gfx mailing list
>
>         amd-gfx@lists.freedesktop.org  <mailto:amd-gfx@lists.freedesktop.org>
>
>         https://lists.freedesktop.org/mailman/listinfo/amd-gfx  <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=04%7C01%7CDavid.Nieto%40amd.com%7C03a24b6d57b44477621e08d90a156f23%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637551909454667370%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=j9a61eEQsky9GUgP%2FrGMsbreQluUCnjRyFZWRG5na%2Fk%3D&reserved=0>
>
>
>


[-- Attachment #1.2: Type: text/html, Size: 39865 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-04-28  7:15           ` Christian König
@ 2021-04-28  7:25             ` Nieto, David M
  2021-04-28  7:42               ` Christian König
  0 siblings, 1 reply; 47+ messages in thread
From: Nieto, David M @ 2021-04-28  7:25 UTC (permalink / raw)
  To: Christian König, Gu, JiaWei (Will), amd-gfx
  Cc: Deucher, Alexander, StDenis, Tom


[-- Attachment #1.1: Type: text/plain, Size: 17155 bytes --]

I think this change may be orthogonal to that. Here we want to provide a way for the user application to get the VBIOS information without having to parse the binary…

And I agree that we should not have strong dependencies unless the encounter buggy VBIOS on the field, but I still think it is useful for the user to be able to display in a simple way the VBIOS version in their system if they happen to encounter an issue.

Regards,
David

From: Christian König <ckoenig.leichtzumerken@gmail.com>
Date: Wednesday, April 28, 2021 at 12:15 AM
To: "Nieto, David M" <David.Nieto@amd.com>, "Gu, JiaWei (Will)" <JiaWei.Gu@amd.com>, "amd-gfx@lists.freedesktop.org" <amd-gfx@lists.freedesktop.org>
Cc: "Deucher, Alexander" <Alexander.Deucher@amd.com>, "StDenis, Tom" <Tom.StDenis@amd.com>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

Well displaying the VBIOS information along with the other firmware in userspace is certainly useful.

We should just avoid making strong dependencies on that.

Firmware and VBIOS must always be backward compatible and the driver must always work with any released firmware and VBIOS combination.

What we can do is to display a warning when we detect and/or old/buggy firmware.

Regards,
Christian.
Am 28.04.21 um 08:47 schrieb Nieto, David M:
Besides system management, it provides parseable details on the VBIOS version and information. This is useful renderer information as the GPU behavior depends not only on the driver version but also on the firmwares running on the GPU.

The AMDGPU_INFO ioctl contains a method to get the versions of the ucode for all the IPs, but for VBIOS, only a way to dump the entire image is provided. While it Is possible to implement the whole logic of VBIOS parsing on userspace, it requires the application to have details on the header and table formats to parse the data. Moreover there is no guarantee that the format and header locations will remain constant across ASIC generations, so the maintainance cost and complexity seems unreasonable.

Providing a simple, and stable interface to the application seems to us like a sensible choice.

Thanks,
David

From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org><mailto:amd-gfx-bounces@lists.freedesktop.org> on behalf of "Gu, JiaWei (Will)" <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com>
Date: Thursday, April 22, 2021 at 8:25 PM
To: Christian König <ckoenig.leichtzumerken@gmail.com><mailto:ckoenig.leichtzumerken@gmail.com>, "amd-gfx@lists.freedesktop.org"<mailto:amd-gfx@lists.freedesktop.org> <amd-gfx@lists.freedesktop.org><mailto:amd-gfx@lists.freedesktop.org>
Cc: "Deucher, Alexander" <Alexander.Deucher@amd.com><mailto:Alexander.Deucher@amd.com>, "StDenis, Tom" <Tom.StDenis@amd.com><mailto:Tom.StDenis@amd.com>, "Nieto, David M" <David.Nieto@amd.com><mailto:David.Nieto@amd.com>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface


[AMD Official Use Only - Internal Distribution Only]

Hi Christian,
It will be used by a user space SMI-lib for GPU status query.

Hi David, please feel free to correct my statement since I’m not sure I have a view of whole picture.

Thanks,
Jiawei

From: Christian König <ckoenig.leichtzumerken@gmail.com><mailto:ckoenig.leichtzumerken@gmail.com>
Sent: Thursday, April 22, 2021 9:27 PM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>
Cc: Deucher, Alexander <Alexander.Deucher@amd.com><mailto:Alexander.Deucher@amd.com>; StDenis, Tom <Tom.StDenis@amd.com><mailto:Tom.StDenis@amd.com>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

Is that useful to Vulkan/OpenGL/other clients in any way?

Christian.
Am 22.04.21 um 15:18 schrieb Gu, JiaWei (Will):



CC Tom.



On Apr 22, 2021, at 21:09, Gu, JiaWei (Will) <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com> wrote:



<[v2][umr]add-vbios-info-query.patch>

UMR patch which calls this new IOCTL attached.



Best regards,

Jiawei



On Apr 22, 2021, at 10:34, Jiawei Gu <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com> wrote:



Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.



Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com><mailto:Jiawei.Gu@amd.com>

---

drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  19 +++

drivers/gpu/drm/amd/amdgpu/atom.c          | 158 +++++++++++++++++++++

drivers/gpu/drm/amd/amdgpu/atom.h          |  11 ++

drivers/gpu/drm/amd/include/atomfirmware.h |  16 ++-

include/uapi/drm/amdgpu_drm.h              |  15 ++

5 files changed, 213 insertions(+), 6 deletions(-)



diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

index 39ee88d29cca..a20b016b05ab 100644

--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

@@ -861,6 +861,25 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)

                                       min((size_t)size, (size_t)(bios_size - bios_offset)))

                                   ? -EFAULT : 0;

             }

+            case AMDGPU_INFO_VBIOS_INFO: {

+                   struct drm_amdgpu_info_vbios vbios_info = {};

+                   struct atom_context *atom_context;

+

+                   atom_context = adev->mode_info.atom_context;

+                 memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));

+                 vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);

+                 memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));

+                 vbios_info.version = atom_context->version;

+                 memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));

+                 memcpy(vbios_info.serial, adev->serial, sizeof(adev->serial));

+                 vbios_info.dev_id = adev->pdev->device;

+                 vbios_info.rev_id = adev->pdev->revision;

+                 vbios_info.sub_dev_id = atom_context->sub_dev_id;

+                 vbios_info.sub_ved_id = atom_context->sub_ved_id;

+

+                   return copy_to_user(out, &vbios_info,

+                                  min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;

+            }

             default:

                  DRM_DEBUG_KMS("Invalid request %d\n",

                            info->vbios_info.type);

diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c

index 3dcb8b32f48b..0e2f0ea13b40 100644

--- a/drivers/gpu/drm/amd/amdgpu/atom.c

+++ b/drivers/gpu/drm/amd/amdgpu/atom.c

@@ -31,6 +31,7 @@



#define ATOM_DEBUG



+#include "atomfirmware.h"

#include "atom.h"

#include "atom-names.h"

#include "atom-bits.h"

@@ -1299,12 +1300,153 @@ static void atom_index_iio(struct atom_context *ctx, int base)

     }

}



+static void atom_get_vbios_name(struct atom_context *ctx)

+{

+    unsigned char *p_rom;

+    unsigned char str_num;

+    unsigned short off_to_vbios_str;

+    unsigned char *c_ptr;

+    int name_size;

+    int i;

+

+    const char *na = "--N/A--";

+    char *back;

+

+    p_rom = ctx->bios;

+

+    str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);

+    if (str_num != 0) {

+            off_to_vbios_str =

+                   *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);

+

+            c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);

+    } else {

+            /* do not know where to find name */

+            memcpy(ctx->name, na, 7);

+            ctx->name[7] = 0;

+            return;

+    }

+

+    /*

+     * skip the atombios strings, usually 4

+     * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type

+     */

+    for (i = 0; i < str_num; i++) {

+            while (*c_ptr != 0)

+                   c_ptr++;

+            c_ptr++;

+    }

+

+    /* skip the following 2 chars: 0x0D 0x0A */

+    c_ptr += 2;

+

+    name_size = strnlen(c_ptr, STRLEN_LONG - 1);

+    memcpy(ctx->name, c_ptr, name_size);

+    back = ctx->name + name_size;

+    while ((*--back) == ' ')

+            ;

+    *(back + 1) = '\0';

+}

+

+static void atom_get_vbios_date(struct atom_context *ctx)

+{

+    unsigned char *p_rom;

+    unsigned char *date_in_rom;

+

+    p_rom = ctx->bios;

+

+    date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;

+

+    ctx->date[0] = '2';

+    ctx->date[1] = '0';

+    ctx->date[2] = date_in_rom[6];

+    ctx->date[3] = date_in_rom[7];

+    ctx->date[4] = '/';

+    ctx->date[5] = date_in_rom[0];

+    ctx->date[6] = date_in_rom[1];

+    ctx->date[7] = '/';

+    ctx->date[8] = date_in_rom[3];

+    ctx->date[9] = date_in_rom[4];

+    ctx->date[10] = ' ';

+    ctx->date[11] = date_in_rom[9];

+    ctx->date[12] = date_in_rom[10];

+    ctx->date[13] = date_in_rom[11];

+    ctx->date[14] = date_in_rom[12];

+    ctx->date[15] = date_in_rom[13];

+    ctx->date[16] = '\0';

+}

+

+static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,

+                                     int end, int maxlen)

+{

+    unsigned long str_off;

+    unsigned char *p_rom;

+    unsigned short str_len;

+

+    str_off = 0;

+    str_len = strnlen(str, maxlen);

+    p_rom = ctx->bios;

+

+    for (; start <= end; ++start) {

+            for (str_off = 0; str_off < str_len; ++str_off) {

+                   if (str[str_off] != *(p_rom + start + str_off))

+                        break;

+            }

+

+            if (str_off == str_len || str[str_off] == 0)

+                   return p_rom + start;

+    }

+    return NULL;

+}

+

+static void atom_get_vbios_pn(struct atom_context *ctx)

+{

+    unsigned char *p_rom;

+    unsigned short off_to_vbios_str;

+    unsigned char *vbios_str;

+    int count;

+

+    off_to_vbios_str = 0;

+    p_rom = ctx->bios;

+

+    if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {

+            off_to_vbios_str =

+                   *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);

+

+            vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);

+    } else {

+            vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;

+    }

+

+    if (*vbios_str == 0) {

+            vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);

+            if (vbios_str == NULL)

+                   vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;

+    }

+    if (vbios_str != NULL && *vbios_str == 0)

+            vbios_str++;

+

+    if (vbios_str != NULL) {

+            count = 0;

+            while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&

+                   vbios_str[count] <= 'z') {

+                 ctx->vbios_pn[count] = vbios_str[count];

+                   count++;

+            }

+

+            ctx->vbios_pn[count] = 0;

+    }

+}

+

struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)

{

     int base;

     struct atom_context *ctx =

         kzalloc(sizeof(struct atom_context), GFP_KERNEL);

     char *str;

+    struct _ATOM_ROM_HEADER *atom_rom_header;

+    struct _ATOM_MASTER_DATA_TABLE *master_table;

+    struct _ATOM_FIRMWARE_INFO *atom_fw_info;

     u16 idx;



     if (!ctx)

@@ -1353,6 +1495,22 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)

          strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));

     }



+    atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);

+    ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;

+    ctx->sub_ved_id = atom_rom_header->usSubsystemID;

+    if (atom_rom_header->usMasterDataTableOffset != 0) {

+            master_table = (struct _ATOM_MASTER_DATA_TABLE *)

+                    CSTR(atom_rom_header->usMasterDataTableOffset);

+            if (master_table->ListOfDataTables.FirmwareInfo != 0) {

+                   atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)

+                           CSTR(master_table->ListOfDataTables.FirmwareInfo);

+                   ctx->version = atom_fw_info->ulFirmwareRevision;

+            }

+    }

+

+    atom_get_vbios_name(ctx);

+    atom_get_vbios_pn(ctx);

+    atom_get_vbios_date(ctx);



     return ctx;

}

diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h

index d279759cab47..c729f7ceba4f 100644

--- a/drivers/gpu/drm/amd/amdgpu/atom.h

+++ b/drivers/gpu/drm/amd/amdgpu/atom.h

@@ -112,6 +112,10 @@ struct drm_device;

#define ATOM_IO_SYSIO              2

#define ATOM_IO_IIO         0x80



+#define STRLEN_NORMAL             32

+#define STRLEN_LONG        64

+#define STRLEN_VERYLONG           254

+

struct card_info {

     struct drm_device *dev;

     void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */

@@ -140,6 +144,13 @@ struct atom_context {

     uint32_t *scratch;

     int scratch_size_bytes;

     char vbios_version[20];

+

+    uint8_t name[STRLEN_LONG];

+    uint8_t vbios_pn[STRLEN_LONG];

+    uint32_t version;

+    uint8_t date[STRLEN_NORMAL];

+    uint32_t sub_dev_id;

+    uint32_t sub_ved_id;

};



extern int amdgpu_atom_debug;

diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h

index c77ed38c20fb..3a8e404099b0 100644

--- a/drivers/gpu/drm/amd/include/atomfirmware.h

+++ b/drivers/gpu/drm/amd/include/atomfirmware.h

@@ -197,6 +197,8 @@ enum atom_dp_vs_preemph_def{

 DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,

};



+#define BIOS_ATOM_PREFIX   "ATOMBIOS"

+#define BIOS_STRING_LENGTH 43



/*

enum atom_string_def{

@@ -209,12 +211,14 @@ atom_bios_string          = "ATOM"

#pragma pack(1)                          /* BIOS data must use byte aligment*/



enum atombios_image_offset{

-OFFSET_TO_ATOM_ROM_HEADER_POINTER          =0x00000048,

-OFFSET_TO_ATOM_ROM_IMAGE_SIZE              =0x00000002,

-OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       =0x94,

-MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      =20,  /*including the terminator 0x0!*/

-OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   =0x2f,

-OFFSET_TO_GET_ATOMBIOS_STRING_START        =0x6e,

+  OFFSET_TO_ATOM_ROM_HEADER_POINTER          = 0x00000048,

+  OFFSET_TO_ATOM_ROM_IMAGE_SIZE              = 0x00000002,

+  OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       = 0x94,

+  MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/

+  OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,

+  OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,

+  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,

+  OFFSET_TO_VBIOS_DATE                       = 0x50,

};



/****************************************************************************

diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h

index 8b832f7458f2..77980445d486 100644

--- a/include/uapi/drm/amdgpu_drm.h

+++ b/include/uapi/drm/amdgpu_drm.h

@@ -758,6 +758,8 @@ struct drm_amdgpu_cs_chunk_data {

     #define AMDGPU_INFO_VBIOS_SIZE             0x1

     /* Subquery id: Query vbios image */

     #define AMDGPU_INFO_VBIOS_IMAGE            0x2

+    /* Subquery id: Query vbios info */

+    #define AMDGPU_INFO_VBIOS_INFO             0x3

/* Query UVD handles */

#define AMDGPU_INFO_NUM_HANDLES                    0x1C

/* Query sensor related information */

@@ -951,6 +953,19 @@ struct drm_amdgpu_info_firmware {

     __u32 feature;

};



+struct drm_amdgpu_info_vbios {

+    __u8 name[64];

+    __u32 dbdf;

+    __u8 vbios_pn[64];

+    __u32 version;

+    __u8 date[32];

+    __u8 serial[16];

+    __u32 dev_id;

+    __u32 rev_id;

+    __u32 sub_dev_id;

+    __u32 sub_ved_id;

+};

+

#define AMDGPU_VRAM_TYPE_UNKNOWN 0

#define AMDGPU_VRAM_TYPE_GDDR1 1

#define AMDGPU_VRAM_TYPE_DDR2  2

--

2.17.1








_______________________________________________

amd-gfx mailing list

amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>

https://lists.freedesktop.org/mailman/listinfo/amd-gfx<https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=04%7C01%7CDavid.Nieto%40amd.com%7C03a24b6d57b44477621e08d90a156f23%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637551909454667370%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=j9a61eEQsky9GUgP%2FrGMsbreQluUCnjRyFZWRG5na%2Fk%3D&reserved=0>




[-- Attachment #1.2: Type: text/html, Size: 38662 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-04-28  6:47         ` Nieto, David M
@ 2021-04-28  7:15           ` Christian König
  2021-04-28  7:25             ` Nieto, David M
  0 siblings, 1 reply; 47+ messages in thread
From: Christian König @ 2021-04-28  7:15 UTC (permalink / raw)
  To: Nieto, David M, Gu, JiaWei (Will), amd-gfx
  Cc: Deucher, Alexander, StDenis, Tom


[-- Attachment #1.1: Type: text/plain, Size: 22120 bytes --]

Well displaying the VBIOS information along with the other firmware in 
userspace is certainly useful.

We should just avoid making strong dependencies on that.

Firmware and VBIOS must always be backward compatible and the driver 
must always work with any released firmware and VBIOS combination.

What we can do is to display a warning when we detect and/or old/buggy 
firmware.

Regards,
Christian.

Am 28.04.21 um 08:47 schrieb Nieto, David M:
>
> Besides system management, it provides parseable details on the VBIOS 
> version and information. This is useful renderer information as the 
> GPU behavior depends not only on the driver version but also on the 
> firmwares running on the GPU.
>
> The AMDGPU_INFO ioctl contains a method to get the versions of the 
> ucode for all the IPs, but for VBIOS, only a way to dump the entire 
> image is provided. While it Is possible to implement the whole logic 
> of VBIOS parsing on userspace, it requires the application to have 
> details on the header and table formats to parse the data. Moreover 
> there is no guarantee that the format and header locations will remain 
> constant across ASIC generations, so the maintainance cost and 
> complexity seems unreasonable.
>
> Providing a simple, and stable interface to the application seems to 
> us like a sensible choice.
>
> Thanks,
>
> David
>
> *From: *amd-gfx <amd-gfx-bounces@lists.freedesktop.org> on behalf of 
> "Gu, JiaWei (Will)" <JiaWei.Gu@amd.com>
> *Date: *Thursday, April 22, 2021 at 8:25 PM
> *To: *Christian König <ckoenig.leichtzumerken@gmail.com>, 
> "amd-gfx@lists.freedesktop.org" <amd-gfx@lists.freedesktop.org>
> *Cc: *"Deucher, Alexander" <Alexander.Deucher@amd.com>, "StDenis, Tom" 
> <Tom.StDenis@amd.com>, "Nieto, David M" <David.Nieto@amd.com>
> *Subject: *RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> [AMD Official Use Only - Internal Distribution Only]
>
> Hi Christian,
>
> It will be used by a user space SMI-lib for GPU status query.
>
> Hi David, please feel free to correct my statement since I’m not sure 
> I have a view of whole picture.
>
> Thanks,
>
> Jiawei
>
> *From:* Christian König <ckoenig.leichtzumerken@gmail.com>
> *Sent:* Thursday, April 22, 2021 9:27 PM
> *To:* Gu, JiaWei (Will) <JiaWei.Gu@amd.com>; amd-gfx@lists.freedesktop.org
> *Cc:* Deucher, Alexander <Alexander.Deucher@amd.com>; StDenis, Tom 
> <Tom.StDenis@amd.com>
> *Subject:* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
>
> Is that useful to Vulkan/OpenGL/other clients in any way?
>
> Christian.
>
> Am 22.04.21 um 15:18 schrieb Gu, JiaWei (Will):
>
>       
>
>     CC Tom.
>
>       
>
>         On Apr 22, 2021, at 21:09, Gu, JiaWei (Will)<JiaWei.Gu@amd.com>  <mailto:JiaWei.Gu@amd.com>  wrote:
>
>           
>
>         <[v2][umr]add-vbios-info-query.patch>
>
>         UMR patch which calls this new IOCTL attached.
>
>           
>
>         Best regards,
>
>         Jiawei
>
>           
>
>             On Apr 22, 2021, at 10:34, Jiawei Gu<JiaWei.Gu@amd.com>  <mailto:JiaWei.Gu@amd.com>  wrote:
>
>               
>
>             Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.
>
>               
>
>             Signed-off-by: Jiawei Gu<Jiawei.Gu@amd.com>  <mailto:Jiawei.Gu@amd.com>
>
>             ---
>
>             drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  19 +++
>
>             drivers/gpu/drm/amd/amdgpu/atom.c          | 158 +++++++++++++++++++++
>
>             drivers/gpu/drm/amd/amdgpu/atom.h          |  11 ++
>
>             drivers/gpu/drm/amd/include/atomfirmware.h |  16 ++-
>
>             include/uapi/drm/amdgpu_drm.h              |  15 ++
>
>             5 files changed, 213 insertions(+), 6 deletions(-)
>
>               
>
>             diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>
>             index 39ee88d29cca..a20b016b05ab 100644
>
>             --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>
>             +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>
>             @@ -861,6 +861,25 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
>
>                                                     min((size_t)size, (size_t)(bios_size - bios_offset)))
>
>                                                 ? -EFAULT : 0;
>
>                           }
>
>             +            case AMDGPU_INFO_VBIOS_INFO: {
>
>             +                   struct drm_amdgpu_info_vbios vbios_info = {};
>
>             +                   struct atom_context *atom_context;
>
>             +
>
>             +                   atom_context = adev->mode_info.atom_context;
>
>             +                 memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
>
>             +                 vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
>
>             +                 memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
>
>             +                 vbios_info.version = atom_context->version;
>
>             +                 memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
>
>             +                 memcpy(vbios_info.serial, adev->serial, sizeof(adev->serial));
>
>             +                 vbios_info.dev_id = adev->pdev->device;
>
>             +                 vbios_info.rev_id = adev->pdev->revision;
>
>             +                 vbios_info.sub_dev_id = atom_context->sub_dev_id;
>
>             +                 vbios_info.sub_ved_id = atom_context->sub_ved_id;
>
>             +
>
>             +                   return copy_to_user(out, &vbios_info,
>
>             +                                  min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
>
>             +            }
>
>                           default:
>
>                                DRM_DEBUG_KMS("Invalid request %d\n",
>
>                                          info->vbios_info.type);
>
>             diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c
>
>             index 3dcb8b32f48b..0e2f0ea13b40 100644
>
>             --- a/drivers/gpu/drm/amd/amdgpu/atom.c
>
>             +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
>
>             @@ -31,6 +31,7 @@
>
>               
>
>             #define ATOM_DEBUG
>
>               
>
>             +#include "atomfirmware.h"
>
>             #include "atom.h"
>
>             #include "atom-names.h"
>
>             #include "atom-bits.h"
>
>             @@ -1299,12 +1300,153 @@ static void atom_index_iio(struct atom_context *ctx, int base)
>
>                   }
>
>             }
>
>               
>
>             +static void atom_get_vbios_name(struct atom_context *ctx)
>
>             +{
>
>             +    unsigned char *p_rom;
>
>             +    unsigned char str_num;
>
>             +    unsigned short off_to_vbios_str;
>
>             +    unsigned char *c_ptr;
>
>             +    int name_size;
>
>             +    int i;
>
>             +
>
>             +    const char *na = "--N/A--";
>
>             +    char *back;
>
>             +
>
>             +    p_rom = ctx->bios;
>
>             +
>
>             +    str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
>
>             +    if (str_num != 0) {
>
>             +            off_to_vbios_str =
>
>             +                   *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
>
>             +
>
>             +            c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
>
>             +    } else {
>
>             +            /* do not know where to find name */
>
>             +            memcpy(ctx->name, na, 7);
>
>             +            ctx->name[7] = 0;
>
>             +            return;
>
>             +    }
>
>             +
>
>             +    /*
>
>             +     * skip the atombios strings, usually 4
>
>             +     * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
>
>             +     */
>
>             +    for (i = 0; i < str_num; i++) {
>
>             +            while (*c_ptr != 0)
>
>             +                   c_ptr++;
>
>             +            c_ptr++;
>
>             +    }
>
>             +
>
>             +    /* skip the following 2 chars: 0x0D 0x0A */
>
>             +    c_ptr += 2;
>
>             +
>
>             +    name_size = strnlen(c_ptr, STRLEN_LONG - 1);
>
>             +    memcpy(ctx->name, c_ptr, name_size);
>
>             +    back = ctx->name + name_size;
>
>             +    while ((*--back) == ' ')
>
>             +            ;
>
>             +    *(back + 1) = '\0';
>
>             +}
>
>             +
>
>             +static void atom_get_vbios_date(struct atom_context *ctx)
>
>             +{
>
>             +    unsigned char *p_rom;
>
>             +    unsigned char *date_in_rom;
>
>             +
>
>             +    p_rom = ctx->bios;
>
>             +
>
>             +    date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
>
>             +
>
>             +    ctx->date[0] = '2';
>
>             +    ctx->date[1] = '0';
>
>             +    ctx->date[2] = date_in_rom[6];
>
>             +    ctx->date[3] = date_in_rom[7];
>
>             +    ctx->date[4] = '/';
>
>             +    ctx->date[5] = date_in_rom[0];
>
>             +    ctx->date[6] = date_in_rom[1];
>
>             +    ctx->date[7] = '/';
>
>             +    ctx->date[8] = date_in_rom[3];
>
>             +    ctx->date[9] = date_in_rom[4];
>
>             +    ctx->date[10] = ' ';
>
>             +    ctx->date[11] = date_in_rom[9];
>
>             +    ctx->date[12] = date_in_rom[10];
>
>             +    ctx->date[13] = date_in_rom[11];
>
>             +    ctx->date[14] = date_in_rom[12];
>
>             +    ctx->date[15] = date_in_rom[13];
>
>             +    ctx->date[16] = '\0';
>
>             +}
>
>             +
>
>             +static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
>
>             +                                     int end, int maxlen)
>
>             +{
>
>             +    unsigned long str_off;
>
>             +    unsigned char *p_rom;
>
>             +    unsigned short str_len;
>
>             +
>
>             +    str_off = 0;
>
>             +    str_len = strnlen(str, maxlen);
>
>             +    p_rom = ctx->bios;
>
>             +
>
>             +    for (; start <= end; ++start) {
>
>             +            for (str_off = 0; str_off < str_len; ++str_off) {
>
>             +                   if (str[str_off] != *(p_rom + start + str_off))
>
>             +                        break;
>
>             +            }
>
>             +
>
>             +            if (str_off == str_len || str[str_off] == 0)
>
>             +                   return p_rom + start;
>
>             +    }
>
>             +    return NULL;
>
>             +}
>
>             +
>
>             +static void atom_get_vbios_pn(struct atom_context *ctx)
>
>             +{
>
>             +    unsigned char *p_rom;
>
>             +    unsigned short off_to_vbios_str;
>
>             +    unsigned char *vbios_str;
>
>             +    int count;
>
>             +
>
>             +    off_to_vbios_str = 0;
>
>             +    p_rom = ctx->bios;
>
>             +
>
>             +    if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
>
>             +            off_to_vbios_str =
>
>             +                   *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
>
>             +
>
>             +            vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
>
>             +    } else {
>
>             +            vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
>
>             +    }
>
>             +
>
>             +    if (*vbios_str == 0) {
>
>             +            vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
>
>             +            if (vbios_str == NULL)
>
>             +                   vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
>
>             +    }
>
>             +    if (vbios_str != NULL && *vbios_str == 0)
>
>             +            vbios_str++;
>
>             +
>
>             +    if (vbios_str != NULL) {
>
>             +            count = 0;
>
>             +            while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
>
>             +                   vbios_str[count] <= 'z') {
>
>             +                 ctx->vbios_pn[count] = vbios_str[count];
>
>             +                   count++;
>
>             +            }
>
>             +
>
>             +            ctx->vbios_pn[count] = 0;
>
>             +    }
>
>             +}
>
>             +
>
>             struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>
>             {
>
>                   int base;
>
>                   struct atom_context *ctx =
>
>                       kzalloc(sizeof(struct atom_context), GFP_KERNEL);
>
>                   char *str;
>
>             +    struct _ATOM_ROM_HEADER *atom_rom_header;
>
>             +    struct _ATOM_MASTER_DATA_TABLE *master_table;
>
>             +    struct _ATOM_FIRMWARE_INFO *atom_fw_info;
>
>                   u16 idx;
>
>               
>
>                   if (!ctx)
>
>             @@ -1353,6 +1495,22 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>
>                        strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
>
>                   }
>
>               
>
>             +    atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
>
>             +    ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
>
>             +    ctx->sub_ved_id = atom_rom_header->usSubsystemID;
>
>             +    if (atom_rom_header->usMasterDataTableOffset != 0) {
>
>             +            master_table = (struct _ATOM_MASTER_DATA_TABLE *)
>
>             +                    CSTR(atom_rom_header->usMasterDataTableOffset);
>
>             +            if (master_table->ListOfDataTables.FirmwareInfo != 0) {
>
>             +                   atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
>
>             +                           CSTR(master_table->ListOfDataTables.FirmwareInfo);
>
>             +                   ctx->version = atom_fw_info->ulFirmwareRevision;
>
>             +            }
>
>             +    }
>
>             +
>
>             +    atom_get_vbios_name(ctx);
>
>             +    atom_get_vbios_pn(ctx);
>
>             +    atom_get_vbios_date(ctx);
>
>               
>
>                   return ctx;
>
>             }
>
>             diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h
>
>             index d279759cab47..c729f7ceba4f 100644
>
>             --- a/drivers/gpu/drm/amd/amdgpu/atom.h
>
>             +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
>
>             @@ -112,6 +112,10 @@ struct drm_device;
>
>             #define ATOM_IO_SYSIO              2
>
>             #define ATOM_IO_IIO         0x80
>
>               
>
>             +#define STRLEN_NORMAL             32
>
>             +#define STRLEN_LONG        64
>
>             +#define STRLEN_VERYLONG           254
>
>             +
>
>             struct card_info {
>
>                   struct drm_device *dev;
>
>                   void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
>
>             @@ -140,6 +144,13 @@ struct atom_context {
>
>                   uint32_t *scratch;
>
>                   int scratch_size_bytes;
>
>                   char vbios_version[20];
>
>             +
>
>             +    uint8_t name[STRLEN_LONG];
>
>             +    uint8_t vbios_pn[STRLEN_LONG];
>
>             +    uint32_t version;
>
>             +    uint8_t date[STRLEN_NORMAL];
>
>             +    uint32_t sub_dev_id;
>
>             +    uint32_t sub_ved_id;
>
>             };
>
>               
>
>             extern int amdgpu_atom_debug;
>
>             diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
>
>             index c77ed38c20fb..3a8e404099b0 100644
>
>             --- a/drivers/gpu/drm/amd/include/atomfirmware.h
>
>             +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
>
>             @@ -197,6 +197,8 @@ enum atom_dp_vs_preemph_def{
>
>               DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
>
>             };
>
>               
>
>             +#define BIOS_ATOM_PREFIX   "ATOMBIOS"
>
>             +#define BIOS_STRING_LENGTH 43
>
>               
>
>             /*
>
>             enum atom_string_def{
>
>             @@ -209,12 +211,14 @@ atom_bios_string          = "ATOM"
>
>             #pragma pack(1)                          /* BIOS data must use byte aligment*/
>
>               
>
>             enum atombios_image_offset{
>
>             -OFFSET_TO_ATOM_ROM_HEADER_POINTER          =0x00000048,
>
>             -OFFSET_TO_ATOM_ROM_IMAGE_SIZE              =0x00000002,
>
>             -OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       =0x94,
>
>             -MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      =20,  /*including the terminator 0x0!*/
>
>             -OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   =0x2f,
>
>             -OFFSET_TO_GET_ATOMBIOS_STRING_START        =0x6e,
>
>             +  OFFSET_TO_ATOM_ROM_HEADER_POINTER          = 0x00000048,
>
>             +  OFFSET_TO_ATOM_ROM_IMAGE_SIZE              = 0x00000002,
>
>             +  OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       = 0x94,
>
>             +  MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
>
>             +  OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
>
>             +  OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
>
>             +  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
>
>             +  OFFSET_TO_VBIOS_DATE                       = 0x50,
>
>             };
>
>               
>
>             /****************************************************************************
>
>             diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
>
>             index 8b832f7458f2..77980445d486 100644
>
>             --- a/include/uapi/drm/amdgpu_drm.h
>
>             +++ b/include/uapi/drm/amdgpu_drm.h
>
>             @@ -758,6 +758,8 @@ struct drm_amdgpu_cs_chunk_data {
>
>                   #define AMDGPU_INFO_VBIOS_SIZE             0x1
>
>                   /* Subquery id: Query vbios image */
>
>                   #define AMDGPU_INFO_VBIOS_IMAGE            0x2
>
>             +    /* Subquery id: Query vbios info */
>
>             +    #define AMDGPU_INFO_VBIOS_INFO             0x3
>
>             /* Query UVD handles */
>
>             #define AMDGPU_INFO_NUM_HANDLES                    0x1C
>
>             /* Query sensor related information */
>
>             @@ -951,6 +953,19 @@ struct drm_amdgpu_info_firmware {
>
>                   __u32 feature;
>
>             };
>
>               
>
>             +struct drm_amdgpu_info_vbios {
>
>             +    __u8 name[64];
>
>             +    __u32 dbdf;
>
>             +    __u8 vbios_pn[64];
>
>             +    __u32 version;
>
>             +    __u8 date[32];
>
>             +    __u8 serial[16];
>
>             +    __u32 dev_id;
>
>             +    __u32 rev_id;
>
>             +    __u32 sub_dev_id;
>
>             +    __u32 sub_ved_id;
>
>             +};
>
>             +
>
>             #define AMDGPU_VRAM_TYPE_UNKNOWN 0
>
>             #define AMDGPU_VRAM_TYPE_GDDR1 1
>
>             #define AMDGPU_VRAM_TYPE_DDR2  2
>
>             -- 
>
>             2.17.1
>
>               
>
>           
>
>       
>
>     _______________________________________________
>
>     amd-gfx mailing list
>
>     amd-gfx@lists.freedesktop.org  <mailto:amd-gfx@lists.freedesktop.org>
>
>     https://lists.freedesktop.org/mailman/listinfo/amd-gfx  <https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=04%7C01%7CEmily.Deng%40amd.com%7C5e5aa67d19d34c7ee2a308d90607750b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637547451371298928%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=vl58TNW%2FAeEe2AvJVH7ayDOjKxVjLzxT58wp1724YNo%3D&reserved=0>
>


[-- Attachment #1.2: Type: text/html, Size: 35517 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-04-23  3:25       ` Gu, JiaWei (Will)
@ 2021-04-28  6:47         ` Nieto, David M
  2021-04-28  7:15           ` Christian König
  0 siblings, 1 reply; 47+ messages in thread
From: Nieto, David M @ 2021-04-28  6:47 UTC (permalink / raw)
  To: Gu, JiaWei (Will), Christian König, amd-gfx
  Cc: Deucher, Alexander, StDenis, Tom


[-- Attachment #1.1: Type: text/plain, Size: 15382 bytes --]

Besides system management, it provides parseable details on the VBIOS version and information. This is useful renderer information as the GPU behavior depends not only on the driver version but also on the firmwares running on the GPU.

The AMDGPU_INFO ioctl contains a method to get the versions of the ucode for all the IPs, but for VBIOS, only a way to dump the entire image is provided. While it Is possible to implement the whole logic of VBIOS parsing on userspace, it requires the application to have details on the header and table formats to parse the data. Moreover there is no guarantee that the format and header locations will remain constant across ASIC generations, so the maintainance cost and complexity seems unreasonable.

Providing a simple, and stable interface to the application seems to us like a sensible choice.

Thanks,
David

From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> on behalf of "Gu, JiaWei (Will)" <JiaWei.Gu@amd.com>
Date: Thursday, April 22, 2021 at 8:25 PM
To: Christian König <ckoenig.leichtzumerken@gmail.com>, "amd-gfx@lists.freedesktop.org" <amd-gfx@lists.freedesktop.org>
Cc: "Deucher, Alexander" <Alexander.Deucher@amd.com>, "StDenis, Tom" <Tom.StDenis@amd.com>, "Nieto, David M" <David.Nieto@amd.com>
Subject: RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface


[AMD Official Use Only - Internal Distribution Only]

Hi Christian,
It will be used by a user space SMI-lib for GPU status query.

Hi David, please feel free to correct my statement since I’m not sure I have a view of whole picture.

Thanks,
Jiawei

From: Christian König <ckoenig.leichtzumerken@gmail.com>
Sent: Thursday, April 22, 2021 9:27 PM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com>; amd-gfx@lists.freedesktop.org
Cc: Deucher, Alexander <Alexander.Deucher@amd.com>; StDenis, Tom <Tom.StDenis@amd.com>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

Is that useful to Vulkan/OpenGL/other clients in any way?

Christian.
Am 22.04.21 um 15:18 schrieb Gu, JiaWei (Will):



CC Tom.



On Apr 22, 2021, at 21:09, Gu, JiaWei (Will) <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com> wrote:



<[v2][umr]add-vbios-info-query.patch>

UMR patch which calls this new IOCTL attached.



Best regards,

Jiawei



On Apr 22, 2021, at 10:34, Jiawei Gu <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com> wrote:



Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.



Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com><mailto:Jiawei.Gu@amd.com>

---

drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  19 +++

drivers/gpu/drm/amd/amdgpu/atom.c          | 158 +++++++++++++++++++++

drivers/gpu/drm/amd/amdgpu/atom.h          |  11 ++

drivers/gpu/drm/amd/include/atomfirmware.h |  16 ++-

include/uapi/drm/amdgpu_drm.h              |  15 ++

5 files changed, 213 insertions(+), 6 deletions(-)



diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

index 39ee88d29cca..a20b016b05ab 100644

--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

@@ -861,6 +861,25 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)

                                       min((size_t)size, (size_t)(bios_size - bios_offset)))

                                   ? -EFAULT : 0;

             }

+            case AMDGPU_INFO_VBIOS_INFO: {

+                   struct drm_amdgpu_info_vbios vbios_info = {};

+                   struct atom_context *atom_context;

+

+                   atom_context = adev->mode_info.atom_context;

+                 memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));

+                 vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);

+                 memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));

+                 vbios_info.version = atom_context->version;

+                 memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));

+                 memcpy(vbios_info.serial, adev->serial, sizeof(adev->serial));

+                 vbios_info.dev_id = adev->pdev->device;

+                 vbios_info.rev_id = adev->pdev->revision;

+                 vbios_info.sub_dev_id = atom_context->sub_dev_id;

+                 vbios_info.sub_ved_id = atom_context->sub_ved_id;

+

+                   return copy_to_user(out, &vbios_info,

+                                  min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;

+            }

             default:

                  DRM_DEBUG_KMS("Invalid request %d\n",

                            info->vbios_info.type);

diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c

index 3dcb8b32f48b..0e2f0ea13b40 100644

--- a/drivers/gpu/drm/amd/amdgpu/atom.c

+++ b/drivers/gpu/drm/amd/amdgpu/atom.c

@@ -31,6 +31,7 @@



#define ATOM_DEBUG



+#include "atomfirmware.h"

#include "atom.h"

#include "atom-names.h"

#include "atom-bits.h"

@@ -1299,12 +1300,153 @@ static void atom_index_iio(struct atom_context *ctx, int base)

     }

}



+static void atom_get_vbios_name(struct atom_context *ctx)

+{

+    unsigned char *p_rom;

+    unsigned char str_num;

+    unsigned short off_to_vbios_str;

+    unsigned char *c_ptr;

+    int name_size;

+    int i;

+

+    const char *na = "--N/A--";

+    char *back;

+

+    p_rom = ctx->bios;

+

+    str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);

+    if (str_num != 0) {

+            off_to_vbios_str =

+                   *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);

+

+            c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);

+    } else {

+            /* do not know where to find name */

+            memcpy(ctx->name, na, 7);

+            ctx->name[7] = 0;

+            return;

+    }

+

+    /*

+     * skip the atombios strings, usually 4

+     * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type

+     */

+    for (i = 0; i < str_num; i++) {

+            while (*c_ptr != 0)

+                   c_ptr++;

+            c_ptr++;

+    }

+

+    /* skip the following 2 chars: 0x0D 0x0A */

+    c_ptr += 2;

+

+    name_size = strnlen(c_ptr, STRLEN_LONG - 1);

+    memcpy(ctx->name, c_ptr, name_size);

+    back = ctx->name + name_size;

+    while ((*--back) == ' ')

+            ;

+    *(back + 1) = '\0';

+}

+

+static void atom_get_vbios_date(struct atom_context *ctx)

+{

+    unsigned char *p_rom;

+    unsigned char *date_in_rom;

+

+    p_rom = ctx->bios;

+

+    date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;

+

+    ctx->date[0] = '2';

+    ctx->date[1] = '0';

+    ctx->date[2] = date_in_rom[6];

+    ctx->date[3] = date_in_rom[7];

+    ctx->date[4] = '/';

+    ctx->date[5] = date_in_rom[0];

+    ctx->date[6] = date_in_rom[1];

+    ctx->date[7] = '/';

+    ctx->date[8] = date_in_rom[3];

+    ctx->date[9] = date_in_rom[4];

+    ctx->date[10] = ' ';

+    ctx->date[11] = date_in_rom[9];

+    ctx->date[12] = date_in_rom[10];

+    ctx->date[13] = date_in_rom[11];

+    ctx->date[14] = date_in_rom[12];

+    ctx->date[15] = date_in_rom[13];

+    ctx->date[16] = '\0';

+}

+

+static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,

+                                     int end, int maxlen)

+{

+    unsigned long str_off;

+    unsigned char *p_rom;

+    unsigned short str_len;

+

+    str_off = 0;

+    str_len = strnlen(str, maxlen);

+    p_rom = ctx->bios;

+

+    for (; start <= end; ++start) {

+            for (str_off = 0; str_off < str_len; ++str_off) {

+                   if (str[str_off] != *(p_rom + start + str_off))

+                        break;

+            }

+

+            if (str_off == str_len || str[str_off] == 0)

+                   return p_rom + start;

+    }

+    return NULL;

+}

+

+static void atom_get_vbios_pn(struct atom_context *ctx)

+{

+    unsigned char *p_rom;

+    unsigned short off_to_vbios_str;

+    unsigned char *vbios_str;

+    int count;

+

+    off_to_vbios_str = 0;

+    p_rom = ctx->bios;

+

+    if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {

+            off_to_vbios_str =

+                   *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);

+

+            vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);

+    } else {

+            vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;

+    }

+

+    if (*vbios_str == 0) {

+            vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);

+            if (vbios_str == NULL)

+                   vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;

+    }

+    if (vbios_str != NULL && *vbios_str == 0)

+            vbios_str++;

+

+    if (vbios_str != NULL) {

+            count = 0;

+            while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&

+                   vbios_str[count] <= 'z') {

+                 ctx->vbios_pn[count] = vbios_str[count];

+                   count++;

+            }

+

+            ctx->vbios_pn[count] = 0;

+    }

+}

+

struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)

{

     int base;

     struct atom_context *ctx =

         kzalloc(sizeof(struct atom_context), GFP_KERNEL);

     char *str;

+    struct _ATOM_ROM_HEADER *atom_rom_header;

+    struct _ATOM_MASTER_DATA_TABLE *master_table;

+    struct _ATOM_FIRMWARE_INFO *atom_fw_info;

     u16 idx;



     if (!ctx)

@@ -1353,6 +1495,22 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)

          strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));

     }



+    atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);

+    ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;

+    ctx->sub_ved_id = atom_rom_header->usSubsystemID;

+    if (atom_rom_header->usMasterDataTableOffset != 0) {

+            master_table = (struct _ATOM_MASTER_DATA_TABLE *)

+                    CSTR(atom_rom_header->usMasterDataTableOffset);

+            if (master_table->ListOfDataTables.FirmwareInfo != 0) {

+                   atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)

+                           CSTR(master_table->ListOfDataTables.FirmwareInfo);

+                   ctx->version = atom_fw_info->ulFirmwareRevision;

+            }

+    }

+

+    atom_get_vbios_name(ctx);

+    atom_get_vbios_pn(ctx);

+    atom_get_vbios_date(ctx);



     return ctx;

}

diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h

index d279759cab47..c729f7ceba4f 100644

--- a/drivers/gpu/drm/amd/amdgpu/atom.h

+++ b/drivers/gpu/drm/amd/amdgpu/atom.h

@@ -112,6 +112,10 @@ struct drm_device;

#define ATOM_IO_SYSIO              2

#define ATOM_IO_IIO         0x80



+#define STRLEN_NORMAL             32

+#define STRLEN_LONG        64

+#define STRLEN_VERYLONG           254

+

struct card_info {

     struct drm_device *dev;

     void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */

@@ -140,6 +144,13 @@ struct atom_context {

     uint32_t *scratch;

     int scratch_size_bytes;

     char vbios_version[20];

+

+    uint8_t name[STRLEN_LONG];

+    uint8_t vbios_pn[STRLEN_LONG];

+    uint32_t version;

+    uint8_t date[STRLEN_NORMAL];

+    uint32_t sub_dev_id;

+    uint32_t sub_ved_id;

};



extern int amdgpu_atom_debug;

diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h

index c77ed38c20fb..3a8e404099b0 100644

--- a/drivers/gpu/drm/amd/include/atomfirmware.h

+++ b/drivers/gpu/drm/amd/include/atomfirmware.h

@@ -197,6 +197,8 @@ enum atom_dp_vs_preemph_def{

 DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,

};



+#define BIOS_ATOM_PREFIX   "ATOMBIOS"

+#define BIOS_STRING_LENGTH 43



/*

enum atom_string_def{

@@ -209,12 +211,14 @@ atom_bios_string          = "ATOM"

#pragma pack(1)                          /* BIOS data must use byte aligment*/



enum atombios_image_offset{

-OFFSET_TO_ATOM_ROM_HEADER_POINTER          =0x00000048,

-OFFSET_TO_ATOM_ROM_IMAGE_SIZE              =0x00000002,

-OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       =0x94,

-MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      =20,  /*including the terminator 0x0!*/

-OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   =0x2f,

-OFFSET_TO_GET_ATOMBIOS_STRING_START        =0x6e,

+  OFFSET_TO_ATOM_ROM_HEADER_POINTER          = 0x00000048,

+  OFFSET_TO_ATOM_ROM_IMAGE_SIZE              = 0x00000002,

+  OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       = 0x94,

+  MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/

+  OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,

+  OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,

+  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,

+  OFFSET_TO_VBIOS_DATE                       = 0x50,

};



/****************************************************************************

diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h

index 8b832f7458f2..77980445d486 100644

--- a/include/uapi/drm/amdgpu_drm.h

+++ b/include/uapi/drm/amdgpu_drm.h

@@ -758,6 +758,8 @@ struct drm_amdgpu_cs_chunk_data {

     #define AMDGPU_INFO_VBIOS_SIZE             0x1

     /* Subquery id: Query vbios image */

     #define AMDGPU_INFO_VBIOS_IMAGE            0x2

+    /* Subquery id: Query vbios info */

+    #define AMDGPU_INFO_VBIOS_INFO             0x3

/* Query UVD handles */

#define AMDGPU_INFO_NUM_HANDLES                    0x1C

/* Query sensor related information */

@@ -951,6 +953,19 @@ struct drm_amdgpu_info_firmware {

     __u32 feature;

};



+struct drm_amdgpu_info_vbios {

+    __u8 name[64];

+    __u32 dbdf;

+    __u8 vbios_pn[64];

+    __u32 version;

+    __u8 date[32];

+    __u8 serial[16];

+    __u32 dev_id;

+    __u32 rev_id;

+    __u32 sub_dev_id;

+    __u32 sub_ved_id;

+};

+

#define AMDGPU_VRAM_TYPE_UNKNOWN 0

#define AMDGPU_VRAM_TYPE_GDDR1 1

#define AMDGPU_VRAM_TYPE_DDR2  2

--

2.17.1








_______________________________________________

amd-gfx mailing list

amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>

https://lists.freedesktop.org/mailman/listinfo/amd-gfx<https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=04%7C01%7CEmily.Deng%40amd.com%7C5e5aa67d19d34c7ee2a308d90607750b%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637547451371298928%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=vl58TNW%2FAeEe2AvJVH7ayDOjKxVjLzxT58wp1724YNo%3D&reserved=0>


[-- Attachment #1.2: Type: text/html, Size: 35638 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* RE: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-04-22 13:27     ` Christian König
@ 2021-04-23  3:25       ` Gu, JiaWei (Will)
  2021-04-28  6:47         ` Nieto, David M
  0 siblings, 1 reply; 47+ messages in thread
From: Gu, JiaWei (Will) @ 2021-04-23  3:25 UTC (permalink / raw)
  To: Christian König, amd-gfx
  Cc: Deucher, Alexander, StDenis, Tom, Nieto, David M


[-- Attachment #1.1: Type: text/plain, Size: 14041 bytes --]

[AMD Official Use Only - Internal Distribution Only]

Hi Christian,
It will be used by a user space SMI-lib for GPU status query.

Hi David, please feel free to correct my statement since I'm not sure I have a view of whole picture.

Thanks,
Jiawei

From: Christian König <ckoenig.leichtzumerken@gmail.com>
Sent: Thursday, April 22, 2021 9:27 PM
To: Gu, JiaWei (Will) <JiaWei.Gu@amd.com>; amd-gfx@lists.freedesktop.org
Cc: Deucher, Alexander <Alexander.Deucher@amd.com>; StDenis, Tom <Tom.StDenis@amd.com>
Subject: Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface

Is that useful to Vulkan/OpenGL/other clients in any way?

Christian.
Am 22.04.21 um 15:18 schrieb Gu, JiaWei (Will):



CC Tom.



On Apr 22, 2021, at 21:09, Gu, JiaWei (Will) <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com> wrote:



<[v2][umr]add-vbios-info-query.patch>

UMR patch which calls this new IOCTL attached.



Best regards,

Jiawei



On Apr 22, 2021, at 10:34, Jiawei Gu <JiaWei.Gu@amd.com><mailto:JiaWei.Gu@amd.com> wrote:



Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.



Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com><mailto:Jiawei.Gu@amd.com>

---

drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  19 +++

drivers/gpu/drm/amd/amdgpu/atom.c          | 158 +++++++++++++++++++++

drivers/gpu/drm/amd/amdgpu/atom.h          |  11 ++

drivers/gpu/drm/amd/include/atomfirmware.h |  16 ++-

include/uapi/drm/amdgpu_drm.h              |  15 ++

5 files changed, 213 insertions(+), 6 deletions(-)



diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

index 39ee88d29cca..a20b016b05ab 100644

--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

@@ -861,6 +861,25 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)

                                       min((size_t)size, (size_t)(bios_size - bios_offset)))

                                   ? -EFAULT : 0;

             }

+            case AMDGPU_INFO_VBIOS_INFO: {

+                   struct drm_amdgpu_info_vbios vbios_info = {};

+                   struct atom_context *atom_context;

+

+                   atom_context = adev->mode_info.atom_context;

+                 memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));

+                 vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);

+                 memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));

+                 vbios_info.version = atom_context->version;

+                 memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));

+                 memcpy(vbios_info.serial, adev->serial, sizeof(adev->serial));

+                 vbios_info.dev_id = adev->pdev->device;

+                 vbios_info.rev_id = adev->pdev->revision;

+                 vbios_info.sub_dev_id = atom_context->sub_dev_id;

+                 vbios_info.sub_ved_id = atom_context->sub_ved_id;

+

+                   return copy_to_user(out, &vbios_info,

+                                  min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;

+            }

             default:

                  DRM_DEBUG_KMS("Invalid request %d\n",

                            info->vbios_info.type);

diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c

index 3dcb8b32f48b..0e2f0ea13b40 100644

--- a/drivers/gpu/drm/amd/amdgpu/atom.c

+++ b/drivers/gpu/drm/amd/amdgpu/atom.c

@@ -31,6 +31,7 @@



#define ATOM_DEBUG



+#include "atomfirmware.h"

#include "atom.h"

#include "atom-names.h"

#include "atom-bits.h"

@@ -1299,12 +1300,153 @@ static void atom_index_iio(struct atom_context *ctx, int base)

     }

}



+static void atom_get_vbios_name(struct atom_context *ctx)

+{

+    unsigned char *p_rom;

+    unsigned char str_num;

+    unsigned short off_to_vbios_str;

+    unsigned char *c_ptr;

+    int name_size;

+    int i;

+

+    const char *na = "--N/A--";

+    char *back;

+

+    p_rom = ctx->bios;

+

+    str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);

+    if (str_num != 0) {

+            off_to_vbios_str =

+                   *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);

+

+            c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);

+    } else {

+            /* do not know where to find name */

+            memcpy(ctx->name, na, 7);

+            ctx->name[7] = 0;

+            return;

+    }

+

+    /*

+     * skip the atombios strings, usually 4

+     * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type

+     */

+    for (i = 0; i < str_num; i++) {

+            while (*c_ptr != 0)

+                   c_ptr++;

+            c_ptr++;

+    }

+

+    /* skip the following 2 chars: 0x0D 0x0A */

+    c_ptr += 2;

+

+    name_size = strnlen(c_ptr, STRLEN_LONG - 1);

+    memcpy(ctx->name, c_ptr, name_size);

+    back = ctx->name + name_size;

+    while ((*--back) == ' ')

+            ;

+    *(back + 1) = '\0';

+}

+

+static void atom_get_vbios_date(struct atom_context *ctx)

+{

+    unsigned char *p_rom;

+    unsigned char *date_in_rom;

+

+    p_rom = ctx->bios;

+

+    date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;

+

+    ctx->date[0] = '2';

+    ctx->date[1] = '0';

+    ctx->date[2] = date_in_rom[6];

+    ctx->date[3] = date_in_rom[7];

+    ctx->date[4] = '/';

+    ctx->date[5] = date_in_rom[0];

+    ctx->date[6] = date_in_rom[1];

+    ctx->date[7] = '/';

+    ctx->date[8] = date_in_rom[3];

+    ctx->date[9] = date_in_rom[4];

+    ctx->date[10] = ' ';

+    ctx->date[11] = date_in_rom[9];

+    ctx->date[12] = date_in_rom[10];

+    ctx->date[13] = date_in_rom[11];

+    ctx->date[14] = date_in_rom[12];

+    ctx->date[15] = date_in_rom[13];

+    ctx->date[16] = '\0';

+}

+

+static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,

+                                     int end, int maxlen)

+{

+    unsigned long str_off;

+    unsigned char *p_rom;

+    unsigned short str_len;

+

+    str_off = 0;

+    str_len = strnlen(str, maxlen);

+    p_rom = ctx->bios;

+

+    for (; start <= end; ++start) {

+            for (str_off = 0; str_off < str_len; ++str_off) {

+                   if (str[str_off] != *(p_rom + start + str_off))

+                        break;

+            }

+

+            if (str_off == str_len || str[str_off] == 0)

+                   return p_rom + start;

+    }

+    return NULL;

+}

+

+static void atom_get_vbios_pn(struct atom_context *ctx)

+{

+    unsigned char *p_rom;

+    unsigned short off_to_vbios_str;

+    unsigned char *vbios_str;

+    int count;

+

+    off_to_vbios_str = 0;

+    p_rom = ctx->bios;

+

+    if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {

+            off_to_vbios_str =

+                   *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);

+

+            vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);

+    } else {

+            vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;

+    }

+

+    if (*vbios_str == 0) {

+            vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);

+            if (vbios_str == NULL)

+                   vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;

+    }

+    if (vbios_str != NULL && *vbios_str == 0)

+            vbios_str++;

+

+    if (vbios_str != NULL) {

+            count = 0;

+            while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&

+                   vbios_str[count] <= 'z') {

+                 ctx->vbios_pn[count] = vbios_str[count];

+                   count++;

+            }

+

+            ctx->vbios_pn[count] = 0;

+    }

+}

+

struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)

{

     int base;

     struct atom_context *ctx =

         kzalloc(sizeof(struct atom_context), GFP_KERNEL);

     char *str;

+    struct _ATOM_ROM_HEADER *atom_rom_header;

+    struct _ATOM_MASTER_DATA_TABLE *master_table;

+    struct _ATOM_FIRMWARE_INFO *atom_fw_info;

     u16 idx;



     if (!ctx)

@@ -1353,6 +1495,22 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)

          strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));

     }



+    atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);

+    ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;

+    ctx->sub_ved_id = atom_rom_header->usSubsystemID;

+    if (atom_rom_header->usMasterDataTableOffset != 0) {

+            master_table = (struct _ATOM_MASTER_DATA_TABLE *)

+                    CSTR(atom_rom_header->usMasterDataTableOffset);

+            if (master_table->ListOfDataTables.FirmwareInfo != 0) {

+                   atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)

+                           CSTR(master_table->ListOfDataTables.FirmwareInfo);

+                   ctx->version = atom_fw_info->ulFirmwareRevision;

+            }

+    }

+

+    atom_get_vbios_name(ctx);

+    atom_get_vbios_pn(ctx);

+    atom_get_vbios_date(ctx);



     return ctx;

}

diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h

index d279759cab47..c729f7ceba4f 100644

--- a/drivers/gpu/drm/amd/amdgpu/atom.h

+++ b/drivers/gpu/drm/amd/amdgpu/atom.h

@@ -112,6 +112,10 @@ struct drm_device;

#define ATOM_IO_SYSIO              2

#define ATOM_IO_IIO         0x80



+#define STRLEN_NORMAL             32

+#define STRLEN_LONG        64

+#define STRLEN_VERYLONG           254

+

struct card_info {

     struct drm_device *dev;

     void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */

@@ -140,6 +144,13 @@ struct atom_context {

     uint32_t *scratch;

     int scratch_size_bytes;

     char vbios_version[20];

+

+    uint8_t name[STRLEN_LONG];

+    uint8_t vbios_pn[STRLEN_LONG];

+    uint32_t version;

+    uint8_t date[STRLEN_NORMAL];

+    uint32_t sub_dev_id;

+    uint32_t sub_ved_id;

};



extern int amdgpu_atom_debug;

diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h

index c77ed38c20fb..3a8e404099b0 100644

--- a/drivers/gpu/drm/amd/include/atomfirmware.h

+++ b/drivers/gpu/drm/amd/include/atomfirmware.h

@@ -197,6 +197,8 @@ enum atom_dp_vs_preemph_def{

 DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,

};



+#define BIOS_ATOM_PREFIX   "ATOMBIOS"

+#define BIOS_STRING_LENGTH 43



/*

enum atom_string_def{

@@ -209,12 +211,14 @@ atom_bios_string          = "ATOM"

#pragma pack(1)                          /* BIOS data must use byte aligment*/



enum atombios_image_offset{

-OFFSET_TO_ATOM_ROM_HEADER_POINTER          =0x00000048,

-OFFSET_TO_ATOM_ROM_IMAGE_SIZE              =0x00000002,

-OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       =0x94,

-MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      =20,  /*including the terminator 0x0!*/

-OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   =0x2f,

-OFFSET_TO_GET_ATOMBIOS_STRING_START        =0x6e,

+  OFFSET_TO_ATOM_ROM_HEADER_POINTER          = 0x00000048,

+  OFFSET_TO_ATOM_ROM_IMAGE_SIZE              = 0x00000002,

+  OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       = 0x94,

+  MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/

+  OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,

+  OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,

+  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,

+  OFFSET_TO_VBIOS_DATE                       = 0x50,

};



/****************************************************************************

diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h

index 8b832f7458f2..77980445d486 100644

--- a/include/uapi/drm/amdgpu_drm.h

+++ b/include/uapi/drm/amdgpu_drm.h

@@ -758,6 +758,8 @@ struct drm_amdgpu_cs_chunk_data {

     #define AMDGPU_INFO_VBIOS_SIZE             0x1

     /* Subquery id: Query vbios image */

     #define AMDGPU_INFO_VBIOS_IMAGE            0x2

+    /* Subquery id: Query vbios info */

+    #define AMDGPU_INFO_VBIOS_INFO             0x3

/* Query UVD handles */

#define AMDGPU_INFO_NUM_HANDLES                    0x1C

/* Query sensor related information */

@@ -951,6 +953,19 @@ struct drm_amdgpu_info_firmware {

     __u32 feature;

};



+struct drm_amdgpu_info_vbios {

+    __u8 name[64];

+    __u32 dbdf;

+    __u8 vbios_pn[64];

+    __u32 version;

+    __u8 date[32];

+    __u8 serial[16];

+    __u32 dev_id;

+    __u32 rev_id;

+    __u32 sub_dev_id;

+    __u32 sub_ved_id;

+};

+

#define AMDGPU_VRAM_TYPE_UNKNOWN 0

#define AMDGPU_VRAM_TYPE_GDDR1 1

#define AMDGPU_VRAM_TYPE_DDR2  2

--

2.17.1








_______________________________________________

amd-gfx mailing list

amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>

https://lists.freedesktop.org/mailman/listinfo/amd-gfx<https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=04%7C01%7CJiaWei.Gu%40amd.com%7C3a545001ba9c49e73f3f08d9059258ee%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637546948385151358%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=CWFUfGGihKzjGaW%2F0w6nV6R4VM8BvSKI1oMPGtKQ7hc%3D&reserved=0>


[-- Attachment #1.2: Type: text/html, Size: 33475 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-04-22 13:18   ` Gu, JiaWei (Will)
@ 2021-04-22 13:27     ` Christian König
  2021-04-23  3:25       ` Gu, JiaWei (Will)
  0 siblings, 1 reply; 47+ messages in thread
From: Christian König @ 2021-04-22 13:27 UTC (permalink / raw)
  To: Gu, JiaWei (Will), amd-gfx; +Cc: Deucher, Alexander, StDenis, Tom


[-- Attachment #1.1: Type: text/plain, Size: 11862 bytes --]

Is that useful to Vulkan/OpenGL/other clients in any way?

Christian.

Am 22.04.21 um 15:18 schrieb Gu, JiaWei (Will):
> CC Tom.
>
>> On Apr 22, 2021, at 21:09, Gu, JiaWei (Will) <JiaWei.Gu@amd.com> wrote:
>>
>> <[v2][umr]add-vbios-info-query.patch>
>> UMR patch which calls this new IOCTL attached.
>>
>> Best regards,
>> Jiawei
>>
>>> On Apr 22, 2021, at 10:34, Jiawei Gu <JiaWei.Gu@amd.com> wrote:
>>>
>>> Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.
>>>
>>> Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com>
>>> ---
>>> drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  19 +++
>>> drivers/gpu/drm/amd/amdgpu/atom.c          | 158 +++++++++++++++++++++
>>> drivers/gpu/drm/amd/amdgpu/atom.h          |  11 ++
>>> drivers/gpu/drm/amd/include/atomfirmware.h |  16 ++-
>>> include/uapi/drm/amdgpu_drm.h              |  15 ++
>>> 5 files changed, 213 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>>> index 39ee88d29cca..a20b016b05ab 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>>> @@ -861,6 +861,25 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
>>> 					    min((size_t)size, (size_t)(bios_size - bios_offset)))
>>> 					? -EFAULT : 0;
>>> 		}
>>> +		case AMDGPU_INFO_VBIOS_INFO: {
>>> +			struct drm_amdgpu_info_vbios vbios_info = {};
>>> +			struct atom_context *atom_context;
>>> +
>>> +			atom_context = adev->mode_info.atom_context;
>>> +			memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
>>> +			vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
>>> +			memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
>>> +			vbios_info.version = atom_context->version;
>>> +			memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
>>> +			memcpy(vbios_info.serial, adev->serial, sizeof(adev->serial));
>>> +			vbios_info.dev_id = adev->pdev->device;
>>> +			vbios_info.rev_id = adev->pdev->revision;
>>> +			vbios_info.sub_dev_id = atom_context->sub_dev_id;
>>> +			vbios_info.sub_ved_id = atom_context->sub_ved_id;
>>> +
>>> +			return copy_to_user(out, &vbios_info,
>>> +						min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
>>> +		}
>>> 		default:
>>> 			DRM_DEBUG_KMS("Invalid request %d\n",
>>> 					info->vbios_info.type);
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c
>>> index 3dcb8b32f48b..0e2f0ea13b40 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/atom.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
>>> @@ -31,6 +31,7 @@
>>>
>>> #define ATOM_DEBUG
>>>
>>> +#include "atomfirmware.h"
>>> #include "atom.h"
>>> #include "atom-names.h"
>>> #include "atom-bits.h"
>>> @@ -1299,12 +1300,153 @@ static void atom_index_iio(struct atom_context *ctx, int base)
>>> 	}
>>> }
>>>
>>> +static void atom_get_vbios_name(struct atom_context *ctx)
>>> +{
>>> +	unsigned char *p_rom;
>>> +	unsigned char str_num;
>>> +	unsigned short off_to_vbios_str;
>>> +	unsigned char *c_ptr;
>>> +	int name_size;
>>> +	int i;
>>> +
>>> +	const char *na = "--N/A--";
>>> +	char *back;
>>> +
>>> +	p_rom = ctx->bios;
>>> +
>>> +	str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
>>> +	if (str_num != 0) {
>>> +		off_to_vbios_str =
>>> +			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
>>> +
>>> +		c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
>>> +	} else {
>>> +		/* do not know where to find name */
>>> +		memcpy(ctx->name, na, 7);
>>> +		ctx->name[7] = 0;
>>> +		return;
>>> +	}
>>> +
>>> +	/*
>>> +	 * skip the atombios strings, usually 4
>>> +	 * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
>>> +	 */
>>> +	for (i = 0; i < str_num; i++) {
>>> +		while (*c_ptr != 0)
>>> +			c_ptr++;
>>> +		c_ptr++;
>>> +	}
>>> +
>>> +	/* skip the following 2 chars: 0x0D 0x0A */
>>> +	c_ptr += 2;
>>> +
>>> +	name_size = strnlen(c_ptr, STRLEN_LONG - 1);
>>> +	memcpy(ctx->name, c_ptr, name_size);
>>> +	back = ctx->name + name_size;
>>> +	while ((*--back) == ' ')
>>> +		;
>>> +	*(back + 1) = '\0';
>>> +}
>>> +
>>> +static void atom_get_vbios_date(struct atom_context *ctx)
>>> +{
>>> +	unsigned char *p_rom;
>>> +	unsigned char *date_in_rom;
>>> +
>>> +	p_rom = ctx->bios;
>>> +
>>> +	date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
>>> +
>>> +	ctx->date[0] = '2';
>>> +	ctx->date[1] = '0';
>>> +	ctx->date[2] = date_in_rom[6];
>>> +	ctx->date[3] = date_in_rom[7];
>>> +	ctx->date[4] = '/';
>>> +	ctx->date[5] = date_in_rom[0];
>>> +	ctx->date[6] = date_in_rom[1];
>>> +	ctx->date[7] = '/';
>>> +	ctx->date[8] = date_in_rom[3];
>>> +	ctx->date[9] = date_in_rom[4];
>>> +	ctx->date[10] = ' ';
>>> +	ctx->date[11] = date_in_rom[9];
>>> +	ctx->date[12] = date_in_rom[10];
>>> +	ctx->date[13] = date_in_rom[11];
>>> +	ctx->date[14] = date_in_rom[12];
>>> +	ctx->date[15] = date_in_rom[13];
>>> +	ctx->date[16] = '\0';
>>> +}
>>> +
>>> +static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
>>> +					   int end, int maxlen)
>>> +{
>>> +	unsigned long str_off;
>>> +	unsigned char *p_rom;
>>> +	unsigned short str_len;
>>> +
>>> +	str_off = 0;
>>> +	str_len = strnlen(str, maxlen);
>>> +	p_rom = ctx->bios;
>>> +
>>> +	for (; start <= end; ++start) {
>>> +		for (str_off = 0; str_off < str_len; ++str_off) {
>>> +			if (str[str_off] != *(p_rom + start + str_off))
>>> +				break;
>>> +		}
>>> +
>>> +		if (str_off == str_len || str[str_off] == 0)
>>> +			return p_rom + start;
>>> +	}
>>> +	return NULL;
>>> +}
>>> +
>>> +static void atom_get_vbios_pn(struct atom_context *ctx)
>>> +{
>>> +	unsigned char *p_rom;
>>> +	unsigned short off_to_vbios_str;
>>> +	unsigned char *vbios_str;
>>> +	int count;
>>> +
>>> +	off_to_vbios_str = 0;
>>> +	p_rom = ctx->bios;
>>> +
>>> +	if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
>>> +		off_to_vbios_str =
>>> +			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
>>> +
>>> +		vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
>>> +	} else {
>>> +		vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
>>> +	}
>>> +
>>> +	if (*vbios_str == 0) {
>>> +		vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
>>> +		if (vbios_str == NULL)
>>> +			vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
>>> +	}
>>> +	if (vbios_str != NULL && *vbios_str == 0)
>>> +		vbios_str++;
>>> +
>>> +	if (vbios_str != NULL) {
>>> +		count = 0;
>>> +		while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
>>> +		       vbios_str[count] <= 'z') {
>>> +			ctx->vbios_pn[count] = vbios_str[count];
>>> +			count++;
>>> +		}
>>> +
>>> +		ctx->vbios_pn[count] = 0;
>>> +	}
>>> +}
>>> +
>>> struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>>> {
>>> 	int base;
>>> 	struct atom_context *ctx =
>>> 	    kzalloc(sizeof(struct atom_context), GFP_KERNEL);
>>> 	char *str;
>>> +	struct _ATOM_ROM_HEADER *atom_rom_header;
>>> +	struct _ATOM_MASTER_DATA_TABLE *master_table;
>>> +	struct _ATOM_FIRMWARE_INFO *atom_fw_info;
>>> 	u16 idx;
>>>
>>> 	if (!ctx)
>>> @@ -1353,6 +1495,22 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>>> 		strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
>>> 	}
>>>
>>> +	atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
>>> +	ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
>>> +	ctx->sub_ved_id = atom_rom_header->usSubsystemID;
>>> +	if (atom_rom_header->usMasterDataTableOffset != 0) {
>>> +		master_table = (struct _ATOM_MASTER_DATA_TABLE *)
>>> +				CSTR(atom_rom_header->usMasterDataTableOffset);
>>> +		if (master_table->ListOfDataTables.FirmwareInfo != 0) {
>>> +			atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
>>> +					CSTR(master_table->ListOfDataTables.FirmwareInfo);
>>> +			ctx->version = atom_fw_info->ulFirmwareRevision;
>>> +		}
>>> +	}
>>> +
>>> +	atom_get_vbios_name(ctx);
>>> +	atom_get_vbios_pn(ctx);
>>> +	atom_get_vbios_date(ctx);
>>>
>>> 	return ctx;
>>> }
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h
>>> index d279759cab47..c729f7ceba4f 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/atom.h
>>> +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
>>> @@ -112,6 +112,10 @@ struct drm_device;
>>> #define ATOM_IO_SYSIO		2
>>> #define ATOM_IO_IIO		0x80
>>>
>>> +#define STRLEN_NORMAL		32
>>> +#define STRLEN_LONG		64
>>> +#define STRLEN_VERYLONG		254
>>> +
>>> struct card_info {
>>> 	struct drm_device *dev;
>>> 	void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
>>> @@ -140,6 +144,13 @@ struct atom_context {
>>> 	uint32_t *scratch;
>>> 	int scratch_size_bytes;
>>> 	char vbios_version[20];
>>> +
>>> +	uint8_t name[STRLEN_LONG];
>>> +	uint8_t vbios_pn[STRLEN_LONG];
>>> +	uint32_t version;
>>> +	uint8_t date[STRLEN_NORMAL];
>>> +	uint32_t sub_dev_id;
>>> +	uint32_t sub_ved_id;
>>> };
>>>
>>> extern int amdgpu_atom_debug;
>>> diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
>>> index c77ed38c20fb..3a8e404099b0 100644
>>> --- a/drivers/gpu/drm/amd/include/atomfirmware.h
>>> +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
>>> @@ -197,6 +197,8 @@ enum atom_dp_vs_preemph_def{
>>>   DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
>>> };
>>>
>>> +#define BIOS_ATOM_PREFIX   "ATOMBIOS"
>>> +#define BIOS_STRING_LENGTH 43
>>>
>>> /*
>>> enum atom_string_def{
>>> @@ -209,12 +211,14 @@ atom_bios_string          = "ATOM"
>>> #pragma pack(1)                          /* BIOS data must use byte aligment*/
>>>
>>> enum atombios_image_offset{
>>> -OFFSET_TO_ATOM_ROM_HEADER_POINTER          =0x00000048,
>>> -OFFSET_TO_ATOM_ROM_IMAGE_SIZE              =0x00000002,
>>> -OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       =0x94,
>>> -MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      =20,  /*including the terminator 0x0!*/
>>> -OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   =0x2f,
>>> -OFFSET_TO_GET_ATOMBIOS_STRING_START        =0x6e,
>>> +  OFFSET_TO_ATOM_ROM_HEADER_POINTER          = 0x00000048,
>>> +  OFFSET_TO_ATOM_ROM_IMAGE_SIZE              = 0x00000002,
>>> +  OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       = 0x94,
>>> +  MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
>>> +  OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
>>> +  OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
>>> +  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
>>> +  OFFSET_TO_VBIOS_DATE                       = 0x50,
>>> };
>>>
>>> /****************************************************************************
>>> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
>>> index 8b832f7458f2..77980445d486 100644
>>> --- a/include/uapi/drm/amdgpu_drm.h
>>> +++ b/include/uapi/drm/amdgpu_drm.h
>>> @@ -758,6 +758,8 @@ struct drm_amdgpu_cs_chunk_data {
>>> 	#define AMDGPU_INFO_VBIOS_SIZE		0x1
>>> 	/* Subquery id: Query vbios image */
>>> 	#define AMDGPU_INFO_VBIOS_IMAGE		0x2
>>> +	/* Subquery id: Query vbios info */
>>> +	#define AMDGPU_INFO_VBIOS_INFO		0x3
>>> /* Query UVD handles */
>>> #define AMDGPU_INFO_NUM_HANDLES			0x1C
>>> /* Query sensor related information */
>>> @@ -951,6 +953,19 @@ struct drm_amdgpu_info_firmware {
>>> 	__u32 feature;
>>> };
>>>
>>> +struct drm_amdgpu_info_vbios {
>>> +	__u8 name[64];
>>> +	__u32 dbdf;
>>> +	__u8 vbios_pn[64];
>>> +	__u32 version;
>>> +	__u8 date[32];
>>> +	__u8 serial[16];
>>> +	__u32 dev_id;
>>> +	__u32 rev_id;
>>> +	__u32 sub_dev_id;
>>> +	__u32 sub_ved_id;
>>> +};
>>> +
>>> #define AMDGPU_VRAM_TYPE_UNKNOWN 0
>>> #define AMDGPU_VRAM_TYPE_GDDR1 1
>>> #define AMDGPU_VRAM_TYPE_DDR2  2
>>> -- 
>>> 2.17.1
>>>
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx


[-- Attachment #1.2: Type: text/html, Size: 11980 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-04-22 13:09 ` Gu, JiaWei (Will)
@ 2021-04-22 13:18   ` Gu, JiaWei (Will)
  2021-04-22 13:27     ` Christian König
  0 siblings, 1 reply; 47+ messages in thread
From: Gu, JiaWei (Will) @ 2021-04-22 13:18 UTC (permalink / raw)
  To: amd-gfx; +Cc: Deucher, Alexander, StDenis, Tom

[-- Attachment #1: Type: text/plain, Size: 11607 bytes --]


CC Tom.

> On Apr 22, 2021, at 21:09, Gu, JiaWei (Will) <JiaWei.Gu@amd.com> wrote:
> 
> <[v2][umr]add-vbios-info-query.patch>
> UMR patch which calls this new IOCTL attached.
> 
> Best regards,
> Jiawei
> 
>> On Apr 22, 2021, at 10:34, Jiawei Gu <JiaWei.Gu@amd.com> wrote:
>> 
>> Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.
>> 
>> Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com>
>> ---
>> drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  19 +++
>> drivers/gpu/drm/amd/amdgpu/atom.c          | 158 +++++++++++++++++++++
>> drivers/gpu/drm/amd/amdgpu/atom.h          |  11 ++
>> drivers/gpu/drm/amd/include/atomfirmware.h |  16 ++-
>> include/uapi/drm/amdgpu_drm.h              |  15 ++
>> 5 files changed, 213 insertions(+), 6 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>> index 39ee88d29cca..a20b016b05ab 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
>> @@ -861,6 +861,25 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
>> 					    min((size_t)size, (size_t)(bios_size - bios_offset)))
>> 					? -EFAULT : 0;
>> 		}
>> +		case AMDGPU_INFO_VBIOS_INFO: {
>> +			struct drm_amdgpu_info_vbios vbios_info = {};
>> +			struct atom_context *atom_context;
>> +
>> +			atom_context = adev->mode_info.atom_context;
>> +			memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
>> +			vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
>> +			memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
>> +			vbios_info.version = atom_context->version;
>> +			memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
>> +			memcpy(vbios_info.serial, adev->serial, sizeof(adev->serial));
>> +			vbios_info.dev_id = adev->pdev->device;
>> +			vbios_info.rev_id = adev->pdev->revision;
>> +			vbios_info.sub_dev_id = atom_context->sub_dev_id;
>> +			vbios_info.sub_ved_id = atom_context->sub_ved_id;
>> +
>> +			return copy_to_user(out, &vbios_info,
>> +						min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
>> +		}
>> 		default:
>> 			DRM_DEBUG_KMS("Invalid request %d\n",
>> 					info->vbios_info.type);
>> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c
>> index 3dcb8b32f48b..0e2f0ea13b40 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/atom.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
>> @@ -31,6 +31,7 @@
>> 
>> #define ATOM_DEBUG
>> 
>> +#include "atomfirmware.h"
>> #include "atom.h"
>> #include "atom-names.h"
>> #include "atom-bits.h"
>> @@ -1299,12 +1300,153 @@ static void atom_index_iio(struct atom_context *ctx, int base)
>> 	}
>> }
>> 
>> +static void atom_get_vbios_name(struct atom_context *ctx)
>> +{
>> +	unsigned char *p_rom;
>> +	unsigned char str_num;
>> +	unsigned short off_to_vbios_str;
>> +	unsigned char *c_ptr;
>> +	int name_size;
>> +	int i;
>> +
>> +	const char *na = "--N/A--";
>> +	char *back;
>> +
>> +	p_rom = ctx->bios;
>> +
>> +	str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
>> +	if (str_num != 0) {
>> +		off_to_vbios_str =
>> +			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
>> +
>> +		c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
>> +	} else {
>> +		/* do not know where to find name */
>> +		memcpy(ctx->name, na, 7);
>> +		ctx->name[7] = 0;
>> +		return;
>> +	}
>> +
>> +	/*
>> +	 * skip the atombios strings, usually 4
>> +	 * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
>> +	 */
>> +	for (i = 0; i < str_num; i++) {
>> +		while (*c_ptr != 0)
>> +			c_ptr++;
>> +		c_ptr++;
>> +	}
>> +
>> +	/* skip the following 2 chars: 0x0D 0x0A */
>> +	c_ptr += 2;
>> +
>> +	name_size = strnlen(c_ptr, STRLEN_LONG - 1);
>> +	memcpy(ctx->name, c_ptr, name_size);
>> +	back = ctx->name + name_size;
>> +	while ((*--back) == ' ')
>> +		;
>> +	*(back + 1) = '\0';
>> +}
>> +
>> +static void atom_get_vbios_date(struct atom_context *ctx)
>> +{
>> +	unsigned char *p_rom;
>> +	unsigned char *date_in_rom;
>> +
>> +	p_rom = ctx->bios;
>> +
>> +	date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
>> +
>> +	ctx->date[0] = '2';
>> +	ctx->date[1] = '0';
>> +	ctx->date[2] = date_in_rom[6];
>> +	ctx->date[3] = date_in_rom[7];
>> +	ctx->date[4] = '/';
>> +	ctx->date[5] = date_in_rom[0];
>> +	ctx->date[6] = date_in_rom[1];
>> +	ctx->date[7] = '/';
>> +	ctx->date[8] = date_in_rom[3];
>> +	ctx->date[9] = date_in_rom[4];
>> +	ctx->date[10] = ' ';
>> +	ctx->date[11] = date_in_rom[9];
>> +	ctx->date[12] = date_in_rom[10];
>> +	ctx->date[13] = date_in_rom[11];
>> +	ctx->date[14] = date_in_rom[12];
>> +	ctx->date[15] = date_in_rom[13];
>> +	ctx->date[16] = '\0';
>> +}
>> +
>> +static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
>> +					   int end, int maxlen)
>> +{
>> +	unsigned long str_off;
>> +	unsigned char *p_rom;
>> +	unsigned short str_len;
>> +
>> +	str_off = 0;
>> +	str_len = strnlen(str, maxlen);
>> +	p_rom = ctx->bios;
>> +
>> +	for (; start <= end; ++start) {
>> +		for (str_off = 0; str_off < str_len; ++str_off) {
>> +			if (str[str_off] != *(p_rom + start + str_off))
>> +				break;
>> +		}
>> +
>> +		if (str_off == str_len || str[str_off] == 0)
>> +			return p_rom + start;
>> +	}
>> +	return NULL;
>> +}
>> +
>> +static void atom_get_vbios_pn(struct atom_context *ctx)
>> +{
>> +	unsigned char *p_rom;
>> +	unsigned short off_to_vbios_str;
>> +	unsigned char *vbios_str;
>> +	int count;
>> +
>> +	off_to_vbios_str = 0;
>> +	p_rom = ctx->bios;
>> +
>> +	if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
>> +		off_to_vbios_str =
>> +			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
>> +
>> +		vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
>> +	} else {
>> +		vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
>> +	}
>> +
>> +	if (*vbios_str == 0) {
>> +		vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
>> +		if (vbios_str == NULL)
>> +			vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
>> +	}
>> +	if (vbios_str != NULL && *vbios_str == 0)
>> +		vbios_str++;
>> +
>> +	if (vbios_str != NULL) {
>> +		count = 0;
>> +		while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
>> +		       vbios_str[count] <= 'z') {
>> +			ctx->vbios_pn[count] = vbios_str[count];
>> +			count++;
>> +		}
>> +
>> +		ctx->vbios_pn[count] = 0;
>> +	}
>> +}
>> +
>> struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>> {
>> 	int base;
>> 	struct atom_context *ctx =
>> 	    kzalloc(sizeof(struct atom_context), GFP_KERNEL);
>> 	char *str;
>> +	struct _ATOM_ROM_HEADER *atom_rom_header;
>> +	struct _ATOM_MASTER_DATA_TABLE *master_table;
>> +	struct _ATOM_FIRMWARE_INFO *atom_fw_info;
>> 	u16 idx;
>> 
>> 	if (!ctx)
>> @@ -1353,6 +1495,22 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>> 		strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
>> 	}
>> 
>> +	atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
>> +	ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
>> +	ctx->sub_ved_id = atom_rom_header->usSubsystemID;
>> +	if (atom_rom_header->usMasterDataTableOffset != 0) {
>> +		master_table = (struct _ATOM_MASTER_DATA_TABLE *)
>> +				CSTR(atom_rom_header->usMasterDataTableOffset);
>> +		if (master_table->ListOfDataTables.FirmwareInfo != 0) {
>> +			atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
>> +					CSTR(master_table->ListOfDataTables.FirmwareInfo);
>> +			ctx->version = atom_fw_info->ulFirmwareRevision;
>> +		}
>> +	}
>> +
>> +	atom_get_vbios_name(ctx);
>> +	atom_get_vbios_pn(ctx);
>> +	atom_get_vbios_date(ctx);
>> 
>> 	return ctx;
>> }
>> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h
>> index d279759cab47..c729f7ceba4f 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/atom.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
>> @@ -112,6 +112,10 @@ struct drm_device;
>> #define ATOM_IO_SYSIO		2
>> #define ATOM_IO_IIO		0x80
>> 
>> +#define STRLEN_NORMAL		32
>> +#define STRLEN_LONG		64
>> +#define STRLEN_VERYLONG		254
>> +
>> struct card_info {
>> 	struct drm_device *dev;
>> 	void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
>> @@ -140,6 +144,13 @@ struct atom_context {
>> 	uint32_t *scratch;
>> 	int scratch_size_bytes;
>> 	char vbios_version[20];
>> +
>> +	uint8_t name[STRLEN_LONG];
>> +	uint8_t vbios_pn[STRLEN_LONG];
>> +	uint32_t version;
>> +	uint8_t date[STRLEN_NORMAL];
>> +	uint32_t sub_dev_id;
>> +	uint32_t sub_ved_id;
>> };
>> 
>> extern int amdgpu_atom_debug;
>> diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
>> index c77ed38c20fb..3a8e404099b0 100644
>> --- a/drivers/gpu/drm/amd/include/atomfirmware.h
>> +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
>> @@ -197,6 +197,8 @@ enum atom_dp_vs_preemph_def{
>>  DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
>> };
>> 
>> +#define BIOS_ATOM_PREFIX   "ATOMBIOS"
>> +#define BIOS_STRING_LENGTH 43
>> 
>> /*
>> enum atom_string_def{
>> @@ -209,12 +211,14 @@ atom_bios_string          = "ATOM"
>> #pragma pack(1)                          /* BIOS data must use byte aligment*/
>> 
>> enum atombios_image_offset{
>> -OFFSET_TO_ATOM_ROM_HEADER_POINTER          =0x00000048,
>> -OFFSET_TO_ATOM_ROM_IMAGE_SIZE              =0x00000002,
>> -OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       =0x94,
>> -MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      =20,  /*including the terminator 0x0!*/
>> -OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   =0x2f,
>> -OFFSET_TO_GET_ATOMBIOS_STRING_START        =0x6e,
>> +  OFFSET_TO_ATOM_ROM_HEADER_POINTER          = 0x00000048,
>> +  OFFSET_TO_ATOM_ROM_IMAGE_SIZE              = 0x00000002,
>> +  OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       = 0x94,
>> +  MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
>> +  OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
>> +  OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
>> +  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
>> +  OFFSET_TO_VBIOS_DATE                       = 0x50,
>> };
>> 
>> /****************************************************************************   
>> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
>> index 8b832f7458f2..77980445d486 100644
>> --- a/include/uapi/drm/amdgpu_drm.h
>> +++ b/include/uapi/drm/amdgpu_drm.h
>> @@ -758,6 +758,8 @@ struct drm_amdgpu_cs_chunk_data {
>> 	#define AMDGPU_INFO_VBIOS_SIZE		0x1
>> 	/* Subquery id: Query vbios image */
>> 	#define AMDGPU_INFO_VBIOS_IMAGE		0x2
>> +	/* Subquery id: Query vbios info */
>> +	#define AMDGPU_INFO_VBIOS_INFO		0x3
>> /* Query UVD handles */
>> #define AMDGPU_INFO_NUM_HANDLES			0x1C
>> /* Query sensor related information */
>> @@ -951,6 +953,19 @@ struct drm_amdgpu_info_firmware {
>> 	__u32 feature;
>> };
>> 
>> +struct drm_amdgpu_info_vbios {
>> +	__u8 name[64];
>> +	__u32 dbdf;
>> +	__u8 vbios_pn[64];
>> +	__u32 version;
>> +	__u8 date[32];
>> +	__u8 serial[16];
>> +	__u32 dev_id;
>> +	__u32 rev_id;
>> +	__u32 sub_dev_id;
>> +	__u32 sub_ved_id;
>> +};
>> +
>> #define AMDGPU_VRAM_TYPE_UNKNOWN 0
>> #define AMDGPU_VRAM_TYPE_GDDR1 1
>> #define AMDGPU_VRAM_TYPE_DDR2  2
>> -- 
>> 2.17.1
>> 
> 


[-- Attachment #2: [v2][umr]add-vbios-info-query.patch --]
[-- Type: application/octet-stream, Size: 6968 bytes --]

From ca5f9c21869317ac8c8df752b8c8e17d15ebb803 Mon Sep 17 00:00:00 2001
From: Jiawei Gu <Jiawei.Gu@amd.com>
Date: Tue, 20 Apr 2021 16:39:42 +0800
Subject: [PATCH] add vbios info query

Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com>
---
 src/app/CMakeLists.txt             |  1 +
 src/app/main.c                     |  8 +++++
 src/app/vbios.c                    | 58 ++++++++++++++++++++++++++++++
 src/lib/lowlevel/linux/query_drm.c | 11 ++++++
 src/umr.h                          | 15 ++++++++
 src/umrapp.h                       |  1 +
 6 files changed, 94 insertions(+)
 create mode 100644 src/app/vbios.c

diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt
index ca7d46b..462e4fc 100644
--- a/src/app/CMakeLists.txt
+++ b/src/app/CMakeLists.txt
@@ -35,6 +35,7 @@ add_library(umrapp STATIC
   pp_table.c
   navi10_ppt.c
   read_metrics.c
+  vbios.c
   ${GUI_SOURCE}
 )
 
diff --git a/src/app/main.c b/src/app/main.c
index 5692f6a..86c4d67 100644
--- a/src/app/main.c
+++ b/src/app/main.c
@@ -825,6 +825,11 @@ int main(int argc, char **argv)
 				asic = get_asic();
 			ih_self_test(asic);
 #endif
+		} else if (!strcmp(argv[i], "--vbios_info") || !strcmp(argv[i], "-vi")) {
+			if (!asic)
+				asic = get_asic();
+			if (umr_print_vbios_info(asic) != 0)
+				fprintf(stderr, "[ERROR]: Cannot print vbios info.\n");
 		} else if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) {
 			printf("User Mode Register debugger v%s for AMDGPU devices (build: %s [%s]), Copyright (c) 2021, AMD Inc.\n"
 "\n*** Device Selection ***\n"
@@ -951,6 +956,9 @@ printf(
 	"\n\t\tPrint the GPU metrics table for the device."
 "\n\t--power, -p \n\t\tRead the conetent of clocks, temperature, gpu loading at runtime"
 	"\n\t\toptions 'use_colour' to colourize output \n");
+printf(
+"\n*** Video BIOS Information ***\n"
+"\n\t--vbios_info, -vi \n\t\tPrint Video BIOS information\n");
 
 #if UMR_GUI
 printf(
diff --git a/src/app/vbios.c b/src/app/vbios.c
new file mode 100644
index 0000000..b2e65e4
--- /dev/null
+++ b/src/app/vbios.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Tom St Denis <tom.stdenis@amd.com>
+ *
+ */
+#include "umrapp.h"
+
+#define AMDGPU_INFO_VBIOS			0x1B
+#define AMDGPU_INFO_VBIOS_INFO			0x3
+int umr_print_vbios_info(struct umr_asic *asic)
+{
+	char fname[64];
+	int r;
+	struct umr_vbios_info vbios_info;
+
+	if (asic->fd.drm < 0) {
+		snprintf(fname, sizeof(fname)-1, "/dev/dri/card%d", asic->instance);
+		asic->fd.drm = open(fname, O_RDWR);
+	}
+
+	r = umr_query_drm_vbios(asic, AMDGPU_INFO_VBIOS, AMDGPU_INFO_VBIOS_INFO,
+			&vbios_info, sizeof(vbios_info));
+	if (r)
+		return r;
+
+	printf("vbios name          : %s\n", vbios_info.name);
+	printf("vbios dbdf          : 0x%x\n", vbios_info.dbdf);
+	printf("vbios pn            : %s\n", vbios_info.vbios_pn);
+	printf("vbios version       : %d\n", vbios_info.version);
+	printf("vbios date          : %s\n", vbios_info.date);
+	printf("vbios serial        : %s\n", vbios_info.serial);
+	printf("vbios dev_id        : 0x%x\n", vbios_info.dev_id);
+	printf("vbios rev_id        : 0x%x\n", vbios_info.rev_id);
+	printf("vbios sub_dev_id    : 0x%x\n", vbios_info.sub_dev_id);
+	printf("vbios sub_ved_id    : 0x%x\n", vbios_info.sub_ved_id);
+
+	close(asic->fd.drm);
+	return 0;
+}
\ No newline at end of file
diff --git a/src/lib/lowlevel/linux/query_drm.c b/src/lib/lowlevel/linux/query_drm.c
index d0c82d4..f4ab709 100644
--- a/src/lib/lowlevel/linux/query_drm.c
+++ b/src/lib/lowlevel/linux/query_drm.c
@@ -49,7 +49,18 @@ int umr_query_drm(struct umr_asic *asic, int field, void *ret, int size)
 	inf.return_size = size;
 	inf.query = field;
 	return ioctl(asic->fd.drm, DRM_IOC(DRM_IOC_WRITE, DRM_IOCTL_BASE, DRM_COMMAND_BASE + DRM_AMDGPU_INFO, sizeof(inf)), &inf);
+}
 
+int umr_query_drm_vbios(struct umr_asic *asic, int field, int type, void *ret, int size)
+{
+	struct drm_amdgpu_info inf;
+
+	memset(&inf, 0, sizeof inf);
+	inf.return_pointer = (uintptr_t)ret;
+	inf.return_size = size;
+	inf.query = field;
+	inf.vbios_info.type = type;
+	return ioctl(asic->fd.drm, DRM_IOC(DRM_IOC_WRITE, DRM_IOCTL_BASE, DRM_COMMAND_BASE + DRM_AMDGPU_INFO, sizeof(inf)), &inf);
 }
 
 #else
diff --git a/src/umr.h b/src/umr.h
index 026f466..625f93e 100644
--- a/src/umr.h
+++ b/src/umr.h
@@ -973,6 +973,7 @@ void umr_free_asic(struct umr_asic *asic);
 void umr_free_maps(struct umr_asic *asic);
 void umr_close_asic(struct umr_asic *asic); // call this to close a fully open asic
 int umr_query_drm(struct umr_asic *asic, int field, void *ret, int size);
+int umr_query_drm_vbios(struct umr_asic *asic, int field, int type, void *ret, int size);
 void umr_enumerate_devices(void);
 int umr_update(struct umr_asic *asic, char *script);
 int umr_update_string(struct umr_asic *asic, char *sdata);
@@ -1337,6 +1338,20 @@ struct umr_soc15_database {
 	struct umr_soc15_database *next;
 };
 
+// vbios
+struct umr_vbios_info {
+	uint8_t name[64];
+	uint32_t dbdf;
+	uint8_t vbios_pn[64];
+	uint32_t version;
+	uint8_t date[32];
+	uint8_t serial[16];
+	uint32_t dev_id;
+	uint32_t rev_id;
+	uint32_t sub_dev_id;
+	uint32_t sub_ved_id;
+};
+
 FILE *umr_database_open(char *path, char *filename);
 struct umr_soc15_database *umr_database_read_soc15(char *path, char *filename);
 void umr_database_free_soc15(struct umr_soc15_database *soc15);
diff --git a/src/umrapp.h b/src/umrapp.h
index 14457fe..1336e07 100644
--- a/src/umrapp.h
+++ b/src/umrapp.h
@@ -57,5 +57,6 @@ void umr_clock_scan(struct umr_asic *asic, const char* clock_name);
 void umr_clock_manual(struct umr_asic *asic, const char* clock_name, void* value);
 int umr_print_pp_table(struct umr_asic *asic, const char* param);
 int umr_print_gpu_metrics(struct umr_asic *asic);
+int umr_print_vbios_info(struct umr_asic *asic);
 
 void run_server_loop(const char *url, struct umr_asic * asic);
-- 
2.17.1


[-- Attachment #3: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-04-22  2:34 Jiawei Gu
@ 2021-04-22 13:09 ` Gu, JiaWei (Will)
  2021-04-22 13:18   ` Gu, JiaWei (Will)
  2021-05-08  4:28   ` Kees Cook
  1 sibling, 1 reply; 47+ messages in thread
From: Gu, JiaWei (Will) @ 2021-04-22 13:09 UTC (permalink / raw)
  To: amd-gfx; +Cc: Deucher, Alexander

[-- Attachment #1: Type: text/plain, Size: 11132 bytes --]


UMR patch which calls this new IOCTL attached.

Best regards,
Jiawei

> On Apr 22, 2021, at 10:34, Jiawei Gu <JiaWei.Gu@amd.com> wrote:
> 
> Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.
> 
> Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  19 +++
> drivers/gpu/drm/amd/amdgpu/atom.c          | 158 +++++++++++++++++++++
> drivers/gpu/drm/amd/amdgpu/atom.h          |  11 ++
> drivers/gpu/drm/amd/include/atomfirmware.h |  16 ++-
> include/uapi/drm/amdgpu_drm.h              |  15 ++
> 5 files changed, 213 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index 39ee88d29cca..a20b016b05ab 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -861,6 +861,25 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
> 					    min((size_t)size, (size_t)(bios_size - bios_offset)))
> 					? -EFAULT : 0;
> 		}
> +		case AMDGPU_INFO_VBIOS_INFO: {
> +			struct drm_amdgpu_info_vbios vbios_info = {};
> +			struct atom_context *atom_context;
> +
> +			atom_context = adev->mode_info.atom_context;
> +			memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
> +			vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
> +			memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
> +			vbios_info.version = atom_context->version;
> +			memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
> +			memcpy(vbios_info.serial, adev->serial, sizeof(adev->serial));
> +			vbios_info.dev_id = adev->pdev->device;
> +			vbios_info.rev_id = adev->pdev->revision;
> +			vbios_info.sub_dev_id = atom_context->sub_dev_id;
> +			vbios_info.sub_ved_id = atom_context->sub_ved_id;
> +
> +			return copy_to_user(out, &vbios_info,
> +						min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
> +		}
> 		default:
> 			DRM_DEBUG_KMS("Invalid request %d\n",
> 					info->vbios_info.type);
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c
> index 3dcb8b32f48b..0e2f0ea13b40 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.c
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
> @@ -31,6 +31,7 @@
> 
> #define ATOM_DEBUG
> 
> +#include "atomfirmware.h"
> #include "atom.h"
> #include "atom-names.h"
> #include "atom-bits.h"
> @@ -1299,12 +1300,153 @@ static void atom_index_iio(struct atom_context *ctx, int base)
> 	}
> }
> 
> +static void atom_get_vbios_name(struct atom_context *ctx)
> +{
> +	unsigned char *p_rom;
> +	unsigned char str_num;
> +	unsigned short off_to_vbios_str;
> +	unsigned char *c_ptr;
> +	int name_size;
> +	int i;
> +
> +	const char *na = "--N/A--";
> +	char *back;
> +
> +	p_rom = ctx->bios;
> +
> +	str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
> +	if (str_num != 0) {
> +		off_to_vbios_str =
> +			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +		c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
> +	} else {
> +		/* do not know where to find name */
> +		memcpy(ctx->name, na, 7);
> +		ctx->name[7] = 0;
> +		return;
> +	}
> +
> +	/*
> +	 * skip the atombios strings, usually 4
> +	 * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
> +	 */
> +	for (i = 0; i < str_num; i++) {
> +		while (*c_ptr != 0)
> +			c_ptr++;
> +		c_ptr++;
> +	}
> +
> +	/* skip the following 2 chars: 0x0D 0x0A */
> +	c_ptr += 2;
> +
> +	name_size = strnlen(c_ptr, STRLEN_LONG - 1);
> +	memcpy(ctx->name, c_ptr, name_size);
> +	back = ctx->name + name_size;
> +	while ((*--back) == ' ')
> +		;
> +	*(back + 1) = '\0';
> +}
> +
> +static void atom_get_vbios_date(struct atom_context *ctx)
> +{
> +	unsigned char *p_rom;
> +	unsigned char *date_in_rom;
> +
> +	p_rom = ctx->bios;
> +
> +	date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
> +
> +	ctx->date[0] = '2';
> +	ctx->date[1] = '0';
> +	ctx->date[2] = date_in_rom[6];
> +	ctx->date[3] = date_in_rom[7];
> +	ctx->date[4] = '/';
> +	ctx->date[5] = date_in_rom[0];
> +	ctx->date[6] = date_in_rom[1];
> +	ctx->date[7] = '/';
> +	ctx->date[8] = date_in_rom[3];
> +	ctx->date[9] = date_in_rom[4];
> +	ctx->date[10] = ' ';
> +	ctx->date[11] = date_in_rom[9];
> +	ctx->date[12] = date_in_rom[10];
> +	ctx->date[13] = date_in_rom[11];
> +	ctx->date[14] = date_in_rom[12];
> +	ctx->date[15] = date_in_rom[13];
> +	ctx->date[16] = '\0';
> +}
> +
> +static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
> +					   int end, int maxlen)
> +{
> +	unsigned long str_off;
> +	unsigned char *p_rom;
> +	unsigned short str_len;
> +
> +	str_off = 0;
> +	str_len = strnlen(str, maxlen);
> +	p_rom = ctx->bios;
> +
> +	for (; start <= end; ++start) {
> +		for (str_off = 0; str_off < str_len; ++str_off) {
> +			if (str[str_off] != *(p_rom + start + str_off))
> +				break;
> +		}
> +
> +		if (str_off == str_len || str[str_off] == 0)
> +			return p_rom + start;
> +	}
> +	return NULL;
> +}
> +
> +static void atom_get_vbios_pn(struct atom_context *ctx)
> +{
> +	unsigned char *p_rom;
> +	unsigned short off_to_vbios_str;
> +	unsigned char *vbios_str;
> +	int count;
> +
> +	off_to_vbios_str = 0;
> +	p_rom = ctx->bios;
> +
> +	if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
> +		off_to_vbios_str =
> +			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +		vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
> +	} else {
> +		vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
> +	}
> +
> +	if (*vbios_str == 0) {
> +		vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
> +		if (vbios_str == NULL)
> +			vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
> +	}
> +	if (vbios_str != NULL && *vbios_str == 0)
> +		vbios_str++;
> +
> +	if (vbios_str != NULL) {
> +		count = 0;
> +		while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
> +		       vbios_str[count] <= 'z') {
> +			ctx->vbios_pn[count] = vbios_str[count];
> +			count++;
> +		}
> +
> +		ctx->vbios_pn[count] = 0;
> +	}
> +}
> +
> struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
> {
> 	int base;
> 	struct atom_context *ctx =
> 	    kzalloc(sizeof(struct atom_context), GFP_KERNEL);
> 	char *str;
> +	struct _ATOM_ROM_HEADER *atom_rom_header;
> +	struct _ATOM_MASTER_DATA_TABLE *master_table;
> +	struct _ATOM_FIRMWARE_INFO *atom_fw_info;
> 	u16 idx;
> 
> 	if (!ctx)
> @@ -1353,6 +1495,22 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
> 		strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
> 	}
> 
> +	atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
> +	ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
> +	ctx->sub_ved_id = atom_rom_header->usSubsystemID;
> +	if (atom_rom_header->usMasterDataTableOffset != 0) {
> +		master_table = (struct _ATOM_MASTER_DATA_TABLE *)
> +				CSTR(atom_rom_header->usMasterDataTableOffset);
> +		if (master_table->ListOfDataTables.FirmwareInfo != 0) {
> +			atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
> +					CSTR(master_table->ListOfDataTables.FirmwareInfo);
> +			ctx->version = atom_fw_info->ulFirmwareRevision;
> +		}
> +	}
> +
> +	atom_get_vbios_name(ctx);
> +	atom_get_vbios_pn(ctx);
> +	atom_get_vbios_date(ctx);
> 
> 	return ctx;
> }
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h
> index d279759cab47..c729f7ceba4f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.h
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
> @@ -112,6 +112,10 @@ struct drm_device;
> #define ATOM_IO_SYSIO		2
> #define ATOM_IO_IIO		0x80
> 
> +#define STRLEN_NORMAL		32
> +#define STRLEN_LONG		64
> +#define STRLEN_VERYLONG		254
> +
> struct card_info {
> 	struct drm_device *dev;
> 	void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
> @@ -140,6 +144,13 @@ struct atom_context {
> 	uint32_t *scratch;
> 	int scratch_size_bytes;
> 	char vbios_version[20];
> +
> +	uint8_t name[STRLEN_LONG];
> +	uint8_t vbios_pn[STRLEN_LONG];
> +	uint32_t version;
> +	uint8_t date[STRLEN_NORMAL];
> +	uint32_t sub_dev_id;
> +	uint32_t sub_ved_id;
> };
> 
> extern int amdgpu_atom_debug;
> diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
> index c77ed38c20fb..3a8e404099b0 100644
> --- a/drivers/gpu/drm/amd/include/atomfirmware.h
> +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
> @@ -197,6 +197,8 @@ enum atom_dp_vs_preemph_def{
>   DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
> };
> 
> +#define BIOS_ATOM_PREFIX   "ATOMBIOS"
> +#define BIOS_STRING_LENGTH 43
> 
> /*
> enum atom_string_def{
> @@ -209,12 +211,14 @@ atom_bios_string          = "ATOM"
> #pragma pack(1)                          /* BIOS data must use byte aligment*/
> 
> enum atombios_image_offset{
> -OFFSET_TO_ATOM_ROM_HEADER_POINTER          =0x00000048,
> -OFFSET_TO_ATOM_ROM_IMAGE_SIZE              =0x00000002,
> -OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       =0x94,
> -MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      =20,  /*including the terminator 0x0!*/
> -OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   =0x2f,
> -OFFSET_TO_GET_ATOMBIOS_STRING_START        =0x6e,
> +  OFFSET_TO_ATOM_ROM_HEADER_POINTER          = 0x00000048,
> +  OFFSET_TO_ATOM_ROM_IMAGE_SIZE              = 0x00000002,
> +  OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       = 0x94,
> +  MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
> +  OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
> +  OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
> +  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
> +  OFFSET_TO_VBIOS_DATE                       = 0x50,
> };
> 
> /****************************************************************************   
> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
> index 8b832f7458f2..77980445d486 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -758,6 +758,8 @@ struct drm_amdgpu_cs_chunk_data {
> 	#define AMDGPU_INFO_VBIOS_SIZE		0x1
> 	/* Subquery id: Query vbios image */
> 	#define AMDGPU_INFO_VBIOS_IMAGE		0x2
> +	/* Subquery id: Query vbios info */
> +	#define AMDGPU_INFO_VBIOS_INFO		0x3
> /* Query UVD handles */
> #define AMDGPU_INFO_NUM_HANDLES			0x1C
> /* Query sensor related information */
> @@ -951,6 +953,19 @@ struct drm_amdgpu_info_firmware {
> 	__u32 feature;
> };
> 
> +struct drm_amdgpu_info_vbios {
> +	__u8 name[64];
> +	__u32 dbdf;
> +	__u8 vbios_pn[64];
> +	__u32 version;
> +	__u8 date[32];
> +	__u8 serial[16];
> +	__u32 dev_id;
> +	__u32 rev_id;
> +	__u32 sub_dev_id;
> +	__u32 sub_ved_id;
> +};
> +
> #define AMDGPU_VRAM_TYPE_UNKNOWN 0
> #define AMDGPU_VRAM_TYPE_GDDR1 1
> #define AMDGPU_VRAM_TYPE_DDR2  2
> -- 
> 2.17.1
> 


[-- Attachment #2: [v2][umr]add-vbios-info-query.patch --]
[-- Type: application/octet-stream, Size: 6968 bytes --]

From ca5f9c21869317ac8c8df752b8c8e17d15ebb803 Mon Sep 17 00:00:00 2001
From: Jiawei Gu <Jiawei.Gu@amd.com>
Date: Tue, 20 Apr 2021 16:39:42 +0800
Subject: [PATCH] add vbios info query

Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com>
---
 src/app/CMakeLists.txt             |  1 +
 src/app/main.c                     |  8 +++++
 src/app/vbios.c                    | 58 ++++++++++++++++++++++++++++++
 src/lib/lowlevel/linux/query_drm.c | 11 ++++++
 src/umr.h                          | 15 ++++++++
 src/umrapp.h                       |  1 +
 6 files changed, 94 insertions(+)
 create mode 100644 src/app/vbios.c

diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt
index ca7d46b..462e4fc 100644
--- a/src/app/CMakeLists.txt
+++ b/src/app/CMakeLists.txt
@@ -35,6 +35,7 @@ add_library(umrapp STATIC
   pp_table.c
   navi10_ppt.c
   read_metrics.c
+  vbios.c
   ${GUI_SOURCE}
 )
 
diff --git a/src/app/main.c b/src/app/main.c
index 5692f6a..86c4d67 100644
--- a/src/app/main.c
+++ b/src/app/main.c
@@ -825,6 +825,11 @@ int main(int argc, char **argv)
 				asic = get_asic();
 			ih_self_test(asic);
 #endif
+		} else if (!strcmp(argv[i], "--vbios_info") || !strcmp(argv[i], "-vi")) {
+			if (!asic)
+				asic = get_asic();
+			if (umr_print_vbios_info(asic) != 0)
+				fprintf(stderr, "[ERROR]: Cannot print vbios info.\n");
 		} else if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) {
 			printf("User Mode Register debugger v%s for AMDGPU devices (build: %s [%s]), Copyright (c) 2021, AMD Inc.\n"
 "\n*** Device Selection ***\n"
@@ -951,6 +956,9 @@ printf(
 	"\n\t\tPrint the GPU metrics table for the device."
 "\n\t--power, -p \n\t\tRead the conetent of clocks, temperature, gpu loading at runtime"
 	"\n\t\toptions 'use_colour' to colourize output \n");
+printf(
+"\n*** Video BIOS Information ***\n"
+"\n\t--vbios_info, -vi \n\t\tPrint Video BIOS information\n");
 
 #if UMR_GUI
 printf(
diff --git a/src/app/vbios.c b/src/app/vbios.c
new file mode 100644
index 0000000..b2e65e4
--- /dev/null
+++ b/src/app/vbios.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2021 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Tom St Denis <tom.stdenis@amd.com>
+ *
+ */
+#include "umrapp.h"
+
+#define AMDGPU_INFO_VBIOS			0x1B
+#define AMDGPU_INFO_VBIOS_INFO			0x3
+int umr_print_vbios_info(struct umr_asic *asic)
+{
+	char fname[64];
+	int r;
+	struct umr_vbios_info vbios_info;
+
+	if (asic->fd.drm < 0) {
+		snprintf(fname, sizeof(fname)-1, "/dev/dri/card%d", asic->instance);
+		asic->fd.drm = open(fname, O_RDWR);
+	}
+
+	r = umr_query_drm_vbios(asic, AMDGPU_INFO_VBIOS, AMDGPU_INFO_VBIOS_INFO,
+			&vbios_info, sizeof(vbios_info));
+	if (r)
+		return r;
+
+	printf("vbios name          : %s\n", vbios_info.name);
+	printf("vbios dbdf          : 0x%x\n", vbios_info.dbdf);
+	printf("vbios pn            : %s\n", vbios_info.vbios_pn);
+	printf("vbios version       : %d\n", vbios_info.version);
+	printf("vbios date          : %s\n", vbios_info.date);
+	printf("vbios serial        : %s\n", vbios_info.serial);
+	printf("vbios dev_id        : 0x%x\n", vbios_info.dev_id);
+	printf("vbios rev_id        : 0x%x\n", vbios_info.rev_id);
+	printf("vbios sub_dev_id    : 0x%x\n", vbios_info.sub_dev_id);
+	printf("vbios sub_ved_id    : 0x%x\n", vbios_info.sub_ved_id);
+
+	close(asic->fd.drm);
+	return 0;
+}
\ No newline at end of file
diff --git a/src/lib/lowlevel/linux/query_drm.c b/src/lib/lowlevel/linux/query_drm.c
index d0c82d4..f4ab709 100644
--- a/src/lib/lowlevel/linux/query_drm.c
+++ b/src/lib/lowlevel/linux/query_drm.c
@@ -49,7 +49,18 @@ int umr_query_drm(struct umr_asic *asic, int field, void *ret, int size)
 	inf.return_size = size;
 	inf.query = field;
 	return ioctl(asic->fd.drm, DRM_IOC(DRM_IOC_WRITE, DRM_IOCTL_BASE, DRM_COMMAND_BASE + DRM_AMDGPU_INFO, sizeof(inf)), &inf);
+}
 
+int umr_query_drm_vbios(struct umr_asic *asic, int field, int type, void *ret, int size)
+{
+	struct drm_amdgpu_info inf;
+
+	memset(&inf, 0, sizeof inf);
+	inf.return_pointer = (uintptr_t)ret;
+	inf.return_size = size;
+	inf.query = field;
+	inf.vbios_info.type = type;
+	return ioctl(asic->fd.drm, DRM_IOC(DRM_IOC_WRITE, DRM_IOCTL_BASE, DRM_COMMAND_BASE + DRM_AMDGPU_INFO, sizeof(inf)), &inf);
 }
 
 #else
diff --git a/src/umr.h b/src/umr.h
index 026f466..625f93e 100644
--- a/src/umr.h
+++ b/src/umr.h
@@ -973,6 +973,7 @@ void umr_free_asic(struct umr_asic *asic);
 void umr_free_maps(struct umr_asic *asic);
 void umr_close_asic(struct umr_asic *asic); // call this to close a fully open asic
 int umr_query_drm(struct umr_asic *asic, int field, void *ret, int size);
+int umr_query_drm_vbios(struct umr_asic *asic, int field, int type, void *ret, int size);
 void umr_enumerate_devices(void);
 int umr_update(struct umr_asic *asic, char *script);
 int umr_update_string(struct umr_asic *asic, char *sdata);
@@ -1337,6 +1338,20 @@ struct umr_soc15_database {
 	struct umr_soc15_database *next;
 };
 
+// vbios
+struct umr_vbios_info {
+	uint8_t name[64];
+	uint32_t dbdf;
+	uint8_t vbios_pn[64];
+	uint32_t version;
+	uint8_t date[32];
+	uint8_t serial[16];
+	uint32_t dev_id;
+	uint32_t rev_id;
+	uint32_t sub_dev_id;
+	uint32_t sub_ved_id;
+};
+
 FILE *umr_database_open(char *path, char *filename);
 struct umr_soc15_database *umr_database_read_soc15(char *path, char *filename);
 void umr_database_free_soc15(struct umr_soc15_database *soc15);
diff --git a/src/umrapp.h b/src/umrapp.h
index 14457fe..1336e07 100644
--- a/src/umrapp.h
+++ b/src/umrapp.h
@@ -57,5 +57,6 @@ void umr_clock_scan(struct umr_asic *asic, const char* clock_name);
 void umr_clock_manual(struct umr_asic *asic, const char* clock_name, void* value);
 int umr_print_pp_table(struct umr_asic *asic, const char* param);
 int umr_print_gpu_metrics(struct umr_asic *asic);
+int umr_print_vbios_info(struct umr_asic *asic);
 
 void run_server_loop(const char *url, struct umr_asic * asic);
-- 
2.17.1


[-- Attachment #3: Type: text/plain, Size: 154 bytes --]

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH] drm/amdgpu: Add vbios info ioctl interface
@ 2021-04-22  2:34 Jiawei Gu
  2021-04-22 13:09 ` Gu, JiaWei (Will)
  2021-05-08  4:28   ` Kees Cook
  0 siblings, 2 replies; 47+ messages in thread
From: Jiawei Gu @ 2021-04-22  2:34 UTC (permalink / raw)
  To: amd-gfx; +Cc: Jiawei Gu

Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.

Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  19 +++
 drivers/gpu/drm/amd/amdgpu/atom.c          | 158 +++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/atom.h          |  11 ++
 drivers/gpu/drm/amd/include/atomfirmware.h |  16 ++-
 include/uapi/drm/amdgpu_drm.h              |  15 ++
 5 files changed, 213 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 39ee88d29cca..a20b016b05ab 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -861,6 +861,25 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
 					    min((size_t)size, (size_t)(bios_size - bios_offset)))
 					? -EFAULT : 0;
 		}
+		case AMDGPU_INFO_VBIOS_INFO: {
+			struct drm_amdgpu_info_vbios vbios_info = {};
+			struct atom_context *atom_context;
+
+			atom_context = adev->mode_info.atom_context;
+			memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
+			vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
+			memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
+			vbios_info.version = atom_context->version;
+			memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
+			memcpy(vbios_info.serial, adev->serial, sizeof(adev->serial));
+			vbios_info.dev_id = adev->pdev->device;
+			vbios_info.rev_id = adev->pdev->revision;
+			vbios_info.sub_dev_id = atom_context->sub_dev_id;
+			vbios_info.sub_ved_id = atom_context->sub_ved_id;
+
+			return copy_to_user(out, &vbios_info,
+						min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
+		}
 		default:
 			DRM_DEBUG_KMS("Invalid request %d\n",
 					info->vbios_info.type);
diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c
index 3dcb8b32f48b..0e2f0ea13b40 100644
--- a/drivers/gpu/drm/amd/amdgpu/atom.c
+++ b/drivers/gpu/drm/amd/amdgpu/atom.c
@@ -31,6 +31,7 @@
 
 #define ATOM_DEBUG
 
+#include "atomfirmware.h"
 #include "atom.h"
 #include "atom-names.h"
 #include "atom-bits.h"
@@ -1299,12 +1300,153 @@ static void atom_index_iio(struct atom_context *ctx, int base)
 	}
 }
 
+static void atom_get_vbios_name(struct atom_context *ctx)
+{
+	unsigned char *p_rom;
+	unsigned char str_num;
+	unsigned short off_to_vbios_str;
+	unsigned char *c_ptr;
+	int name_size;
+	int i;
+
+	const char *na = "--N/A--";
+	char *back;
+
+	p_rom = ctx->bios;
+
+	str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
+	if (str_num != 0) {
+		off_to_vbios_str =
+			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
+
+		c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
+	} else {
+		/* do not know where to find name */
+		memcpy(ctx->name, na, 7);
+		ctx->name[7] = 0;
+		return;
+	}
+
+	/*
+	 * skip the atombios strings, usually 4
+	 * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
+	 */
+	for (i = 0; i < str_num; i++) {
+		while (*c_ptr != 0)
+			c_ptr++;
+		c_ptr++;
+	}
+
+	/* skip the following 2 chars: 0x0D 0x0A */
+	c_ptr += 2;
+
+	name_size = strnlen(c_ptr, STRLEN_LONG - 1);
+	memcpy(ctx->name, c_ptr, name_size);
+	back = ctx->name + name_size;
+	while ((*--back) == ' ')
+		;
+	*(back + 1) = '\0';
+}
+
+static void atom_get_vbios_date(struct atom_context *ctx)
+{
+	unsigned char *p_rom;
+	unsigned char *date_in_rom;
+
+	p_rom = ctx->bios;
+
+	date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
+
+	ctx->date[0] = '2';
+	ctx->date[1] = '0';
+	ctx->date[2] = date_in_rom[6];
+	ctx->date[3] = date_in_rom[7];
+	ctx->date[4] = '/';
+	ctx->date[5] = date_in_rom[0];
+	ctx->date[6] = date_in_rom[1];
+	ctx->date[7] = '/';
+	ctx->date[8] = date_in_rom[3];
+	ctx->date[9] = date_in_rom[4];
+	ctx->date[10] = ' ';
+	ctx->date[11] = date_in_rom[9];
+	ctx->date[12] = date_in_rom[10];
+	ctx->date[13] = date_in_rom[11];
+	ctx->date[14] = date_in_rom[12];
+	ctx->date[15] = date_in_rom[13];
+	ctx->date[16] = '\0';
+}
+
+static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
+					   int end, int maxlen)
+{
+	unsigned long str_off;
+	unsigned char *p_rom;
+	unsigned short str_len;
+
+	str_off = 0;
+	str_len = strnlen(str, maxlen);
+	p_rom = ctx->bios;
+
+	for (; start <= end; ++start) {
+		for (str_off = 0; str_off < str_len; ++str_off) {
+			if (str[str_off] != *(p_rom + start + str_off))
+				break;
+		}
+
+		if (str_off == str_len || str[str_off] == 0)
+			return p_rom + start;
+	}
+	return NULL;
+}
+
+static void atom_get_vbios_pn(struct atom_context *ctx)
+{
+	unsigned char *p_rom;
+	unsigned short off_to_vbios_str;
+	unsigned char *vbios_str;
+	int count;
+
+	off_to_vbios_str = 0;
+	p_rom = ctx->bios;
+
+	if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
+		off_to_vbios_str =
+			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
+
+		vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
+	} else {
+		vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
+	}
+
+	if (*vbios_str == 0) {
+		vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
+		if (vbios_str == NULL)
+			vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
+	}
+	if (vbios_str != NULL && *vbios_str == 0)
+		vbios_str++;
+
+	if (vbios_str != NULL) {
+		count = 0;
+		while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
+		       vbios_str[count] <= 'z') {
+			ctx->vbios_pn[count] = vbios_str[count];
+			count++;
+		}
+
+		ctx->vbios_pn[count] = 0;
+	}
+}
+
 struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
 {
 	int base;
 	struct atom_context *ctx =
 	    kzalloc(sizeof(struct atom_context), GFP_KERNEL);
 	char *str;
+	struct _ATOM_ROM_HEADER *atom_rom_header;
+	struct _ATOM_MASTER_DATA_TABLE *master_table;
+	struct _ATOM_FIRMWARE_INFO *atom_fw_info;
 	u16 idx;
 
 	if (!ctx)
@@ -1353,6 +1495,22 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
 		strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
 	}
 
+	atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
+	ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
+	ctx->sub_ved_id = atom_rom_header->usSubsystemID;
+	if (atom_rom_header->usMasterDataTableOffset != 0) {
+		master_table = (struct _ATOM_MASTER_DATA_TABLE *)
+				CSTR(atom_rom_header->usMasterDataTableOffset);
+		if (master_table->ListOfDataTables.FirmwareInfo != 0) {
+			atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
+					CSTR(master_table->ListOfDataTables.FirmwareInfo);
+			ctx->version = atom_fw_info->ulFirmwareRevision;
+		}
+	}
+
+	atom_get_vbios_name(ctx);
+	atom_get_vbios_pn(ctx);
+	atom_get_vbios_date(ctx);
 
 	return ctx;
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h
index d279759cab47..c729f7ceba4f 100644
--- a/drivers/gpu/drm/amd/amdgpu/atom.h
+++ b/drivers/gpu/drm/amd/amdgpu/atom.h
@@ -112,6 +112,10 @@ struct drm_device;
 #define ATOM_IO_SYSIO		2
 #define ATOM_IO_IIO		0x80
 
+#define STRLEN_NORMAL		32
+#define STRLEN_LONG		64
+#define STRLEN_VERYLONG		254
+
 struct card_info {
 	struct drm_device *dev;
 	void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
@@ -140,6 +144,13 @@ struct atom_context {
 	uint32_t *scratch;
 	int scratch_size_bytes;
 	char vbios_version[20];
+
+	uint8_t name[STRLEN_LONG];
+	uint8_t vbios_pn[STRLEN_LONG];
+	uint32_t version;
+	uint8_t date[STRLEN_NORMAL];
+	uint32_t sub_dev_id;
+	uint32_t sub_ved_id;
 };
 
 extern int amdgpu_atom_debug;
diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
index c77ed38c20fb..3a8e404099b0 100644
--- a/drivers/gpu/drm/amd/include/atomfirmware.h
+++ b/drivers/gpu/drm/amd/include/atomfirmware.h
@@ -197,6 +197,8 @@ enum atom_dp_vs_preemph_def{
   DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
 };
 
+#define BIOS_ATOM_PREFIX   "ATOMBIOS"
+#define BIOS_STRING_LENGTH 43
 
 /*
 enum atom_string_def{
@@ -209,12 +211,14 @@ atom_bios_string          = "ATOM"
 #pragma pack(1)                          /* BIOS data must use byte aligment*/
 
 enum atombios_image_offset{
-OFFSET_TO_ATOM_ROM_HEADER_POINTER          =0x00000048,
-OFFSET_TO_ATOM_ROM_IMAGE_SIZE              =0x00000002,
-OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       =0x94,
-MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      =20,  /*including the terminator 0x0!*/
-OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   =0x2f,
-OFFSET_TO_GET_ATOMBIOS_STRING_START        =0x6e,
+  OFFSET_TO_ATOM_ROM_HEADER_POINTER          = 0x00000048,
+  OFFSET_TO_ATOM_ROM_IMAGE_SIZE              = 0x00000002,
+  OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       = 0x94,
+  MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
+  OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
+  OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
+  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
+  OFFSET_TO_VBIOS_DATE                       = 0x50,
 };
 
 /****************************************************************************   
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index 8b832f7458f2..77980445d486 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -758,6 +758,8 @@ struct drm_amdgpu_cs_chunk_data {
 	#define AMDGPU_INFO_VBIOS_SIZE		0x1
 	/* Subquery id: Query vbios image */
 	#define AMDGPU_INFO_VBIOS_IMAGE		0x2
+	/* Subquery id: Query vbios info */
+	#define AMDGPU_INFO_VBIOS_INFO		0x3
 /* Query UVD handles */
 #define AMDGPU_INFO_NUM_HANDLES			0x1C
 /* Query sensor related information */
@@ -951,6 +953,19 @@ struct drm_amdgpu_info_firmware {
 	__u32 feature;
 };
 
+struct drm_amdgpu_info_vbios {
+	__u8 name[64];
+	__u32 dbdf;
+	__u8 vbios_pn[64];
+	__u32 version;
+	__u8 date[32];
+	__u8 serial[16];
+	__u32 dev_id;
+	__u32 rev_id;
+	__u32 sub_dev_id;
+	__u32 sub_ved_id;
+};
+
 #define AMDGPU_VRAM_TYPE_UNKNOWN 0
 #define AMDGPU_VRAM_TYPE_GDDR1 1
 #define AMDGPU_VRAM_TYPE_DDR2  2
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 47+ messages in thread

* Re: [PATCH] drm/amdgpu: Add vbios info ioctl interface
  2021-04-14  9:08 Jiawei Gu
@ 2021-04-14 13:01 ` Alex Deucher
  0 siblings, 0 replies; 47+ messages in thread
From: Alex Deucher @ 2021-04-14 13:01 UTC (permalink / raw)
  To: Jiawei Gu; +Cc: Emily Deng, Roy Sun, amd-gfx list

On Wed, Apr 14, 2021 at 5:09 AM Jiawei Gu <Jiawei.Gu@amd.com> wrote:
>
> Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.

Please provide a link to patches for an open source tool which uses
this new query.

>
> Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  19 +++
>  drivers/gpu/drm/amd/amdgpu/atom.c          | 158 +++++++++++++++++++++
>  drivers/gpu/drm/amd/amdgpu/atom.h          |  11 ++
>  drivers/gpu/drm/amd/include/atomfirmware.h |  16 ++-
>  include/uapi/drm/amdgpu_drm.h              |  15 ++
>  5 files changed, 213 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index 39ee88d29cca..a20b016b05ab 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -861,6 +861,25 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
>                                             min((size_t)size, (size_t)(bios_size - bios_offset)))
>                                         ? -EFAULT : 0;
>                 }
> +               case AMDGPU_INFO_VBIOS_INFO: {
> +                       struct drm_amdgpu_info_vbios vbios_info = {};
> +                       struct atom_context *atom_context;
> +
> +                       atom_context = adev->mode_info.atom_context;
> +                       memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
> +                       vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
> +                       memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
> +                       vbios_info.version = atom_context->version;
> +                       memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
> +                       memcpy(vbios_info.serial, adev->serial, sizeof(adev->serial));
> +                       vbios_info.dev_id = adev->pdev->device;
> +                       vbios_info.rev_id = adev->pdev->revision;
> +                       vbios_info.sub_dev_id = atom_context->sub_dev_id;
> +                       vbios_info.sub_ved_id = atom_context->sub_ved_id;
> +
> +                       return copy_to_user(out, &vbios_info,
> +                                               min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
> +               }
>                 default:
>                         DRM_DEBUG_KMS("Invalid request %d\n",
>                                         info->vbios_info.type);
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c
> index 3dcb8b32f48b..0e2f0ea13b40 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.c
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.c
> @@ -31,6 +31,7 @@
>
>  #define ATOM_DEBUG
>
> +#include "atomfirmware.h"
>  #include "atom.h"
>  #include "atom-names.h"
>  #include "atom-bits.h"
> @@ -1299,12 +1300,153 @@ static void atom_index_iio(struct atom_context *ctx, int base)
>         }
>  }
>
> +static void atom_get_vbios_name(struct atom_context *ctx)
> +{
> +       unsigned char *p_rom;
> +       unsigned char str_num;
> +       unsigned short off_to_vbios_str;
> +       unsigned char *c_ptr;
> +       int name_size;
> +       int i;
> +
> +       const char *na = "--N/A--";
> +       char *back;
> +
> +       p_rom = ctx->bios;
> +
> +       str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
> +       if (str_num != 0) {
> +               off_to_vbios_str =
> +                       *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +               c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
> +       } else {
> +               /* do not know where to find name */
> +               memcpy(ctx->name, na, 7);
> +               ctx->name[7] = 0;
> +               return;
> +       }
> +
> +       /*
> +        * skip the atombios strings, usually 4
> +        * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
> +        */
> +       for (i = 0; i < str_num; i++) {
> +               while (*c_ptr != 0)
> +                       c_ptr++;
> +               c_ptr++;
> +       }
> +
> +       /* skip the following 2 chars: 0x0D 0x0A */
> +       c_ptr += 2;
> +
> +       name_size = strnlen(c_ptr, STRLEN_LONG - 1);
> +       memcpy(ctx->name, c_ptr, name_size);
> +       back = ctx->name + name_size;
> +       while ((*--back) == ' ')
> +               ;
> +       *(back + 1) = '\0';
> +}
> +
> +static void atom_get_vbios_date(struct atom_context *ctx)
> +{
> +       unsigned char *p_rom;
> +       unsigned char *date_in_rom;
> +
> +       p_rom = ctx->bios;
> +
> +       date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
> +
> +       ctx->date[0] = '2';
> +       ctx->date[1] = '0';
> +       ctx->date[2] = date_in_rom[6];
> +       ctx->date[3] = date_in_rom[7];
> +       ctx->date[4] = '/';
> +       ctx->date[5] = date_in_rom[0];
> +       ctx->date[6] = date_in_rom[1];
> +       ctx->date[7] = '/';
> +       ctx->date[8] = date_in_rom[3];
> +       ctx->date[9] = date_in_rom[4];
> +       ctx->date[10] = ' ';
> +       ctx->date[11] = date_in_rom[9];
> +       ctx->date[12] = date_in_rom[10];
> +       ctx->date[13] = date_in_rom[11];
> +       ctx->date[14] = date_in_rom[12];
> +       ctx->date[15] = date_in_rom[13];
> +       ctx->date[16] = '\0';
> +}
> +
> +static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
> +                                          int end, int maxlen)
> +{
> +       unsigned long str_off;
> +       unsigned char *p_rom;
> +       unsigned short str_len;
> +
> +       str_off = 0;
> +       str_len = strnlen(str, maxlen);
> +       p_rom = ctx->bios;
> +
> +       for (; start <= end; ++start) {
> +               for (str_off = 0; str_off < str_len; ++str_off) {
> +                       if (str[str_off] != *(p_rom + start + str_off))
> +                               break;
> +               }
> +
> +               if (str_off == str_len || str[str_off] == 0)
> +                       return p_rom + start;
> +       }
> +       return NULL;
> +}
> +
> +static void atom_get_vbios_pn(struct atom_context *ctx)
> +{
> +       unsigned char *p_rom;
> +       unsigned short off_to_vbios_str;
> +       unsigned char *vbios_str;
> +       int count;
> +
> +       off_to_vbios_str = 0;
> +       p_rom = ctx->bios;
> +
> +       if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
> +               off_to_vbios_str =
> +                       *(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
> +
> +               vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
> +       } else {
> +               vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
> +       }
> +
> +       if (*vbios_str == 0) {
> +               vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
> +               if (vbios_str == NULL)
> +                       vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
> +       }
> +       if (vbios_str != NULL && *vbios_str == 0)
> +               vbios_str++;
> +
> +       if (vbios_str != NULL) {
> +               count = 0;
> +               while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
> +                      vbios_str[count] <= 'z') {
> +                       ctx->vbios_pn[count] = vbios_str[count];
> +                       count++;
> +               }
> +
> +               ctx->vbios_pn[count] = 0;
> +       }
> +}
> +
>  struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>  {
>         int base;
>         struct atom_context *ctx =
>             kzalloc(sizeof(struct atom_context), GFP_KERNEL);
>         char *str;
> +       struct _ATOM_ROM_HEADER *atom_rom_header;
> +       struct _ATOM_MASTER_DATA_TABLE *master_table;
> +       struct _ATOM_FIRMWARE_INFO *atom_fw_info;
>         u16 idx;
>
>         if (!ctx)
> @@ -1353,6 +1495,22 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
>                 strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
>         }
>
> +       atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
> +       ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
> +       ctx->sub_ved_id = atom_rom_header->usSubsystemID;
> +       if (atom_rom_header->usMasterDataTableOffset != 0) {
> +               master_table = (struct _ATOM_MASTER_DATA_TABLE *)
> +                               CSTR(atom_rom_header->usMasterDataTableOffset);
> +               if (master_table->ListOfDataTables.FirmwareInfo != 0) {
> +                       atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
> +                                       CSTR(master_table->ListOfDataTables.FirmwareInfo);
> +                       ctx->version = atom_fw_info->ulFirmwareRevision;
> +               }
> +       }
> +
> +       atom_get_vbios_name(ctx);
> +       atom_get_vbios_pn(ctx);
> +       atom_get_vbios_date(ctx);
>
>         return ctx;
>  }
> diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h
> index d279759cab47..c729f7ceba4f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atom.h
> +++ b/drivers/gpu/drm/amd/amdgpu/atom.h
> @@ -112,6 +112,10 @@ struct drm_device;
>  #define ATOM_IO_SYSIO          2
>  #define ATOM_IO_IIO            0x80
>
> +#define STRLEN_NORMAL          32
> +#define STRLEN_LONG            64
> +#define STRLEN_VERYLONG                254
> +
>  struct card_info {
>         struct drm_device *dev;
>         void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
> @@ -140,6 +144,13 @@ struct atom_context {
>         uint32_t *scratch;
>         int scratch_size_bytes;
>         char vbios_version[20];
> +
> +       uint8_t name[STRLEN_LONG];
> +       uint8_t vbios_pn[STRLEN_LONG];
> +       uint32_t version;
> +       uint8_t date[STRLEN_NORMAL];
> +       uint32_t sub_dev_id;
> +       uint32_t sub_ved_id;
>  };
>
>  extern int amdgpu_atom_debug;
> diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
> index c77ed38c20fb..3a8e404099b0 100644
> --- a/drivers/gpu/drm/amd/include/atomfirmware.h
> +++ b/drivers/gpu/drm/amd/include/atomfirmware.h
> @@ -197,6 +197,8 @@ enum atom_dp_vs_preemph_def{
>    DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
>  };
>
> +#define BIOS_ATOM_PREFIX   "ATOMBIOS"
> +#define BIOS_STRING_LENGTH 43
>
>  /*
>  enum atom_string_def{
> @@ -209,12 +211,14 @@ atom_bios_string          = "ATOM"
>  #pragma pack(1)                          /* BIOS data must use byte aligment*/
>
>  enum atombios_image_offset{
> -OFFSET_TO_ATOM_ROM_HEADER_POINTER          =0x00000048,
> -OFFSET_TO_ATOM_ROM_IMAGE_SIZE              =0x00000002,
> -OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       =0x94,
> -MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      =20,  /*including the terminator 0x0!*/
> -OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   =0x2f,
> -OFFSET_TO_GET_ATOMBIOS_STRING_START        =0x6e,
> +  OFFSET_TO_ATOM_ROM_HEADER_POINTER          = 0x00000048,
> +  OFFSET_TO_ATOM_ROM_IMAGE_SIZE              = 0x00000002,
> +  OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       = 0x94,
> +  MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
> +  OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
> +  OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
> +  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
> +  OFFSET_TO_VBIOS_DATE                       = 0x50,
>  };
>
>  /****************************************************************************
> diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
> index 8b832f7458f2..77980445d486 100644
> --- a/include/uapi/drm/amdgpu_drm.h
> +++ b/include/uapi/drm/amdgpu_drm.h
> @@ -758,6 +758,8 @@ struct drm_amdgpu_cs_chunk_data {
>         #define AMDGPU_INFO_VBIOS_SIZE          0x1
>         /* Subquery id: Query vbios image */
>         #define AMDGPU_INFO_VBIOS_IMAGE         0x2
> +       /* Subquery id: Query vbios info */
> +       #define AMDGPU_INFO_VBIOS_INFO          0x3
>  /* Query UVD handles */
>  #define AMDGPU_INFO_NUM_HANDLES                        0x1C
>  /* Query sensor related information */
> @@ -951,6 +953,19 @@ struct drm_amdgpu_info_firmware {
>         __u32 feature;
>  };
>
> +struct drm_amdgpu_info_vbios {
> +       __u8 name[64];
> +       __u32 dbdf;
> +       __u8 vbios_pn[64];
> +       __u32 version;
> +       __u8 date[32];
> +       __u8 serial[16];
> +       __u32 dev_id;
> +       __u32 rev_id;
> +       __u32 sub_dev_id;
> +       __u32 sub_ved_id;
> +};

Please make sure this structure is 64 bit aligned.

Alex

> +
>  #define AMDGPU_VRAM_TYPE_UNKNOWN 0
>  #define AMDGPU_VRAM_TYPE_GDDR1 1
>  #define AMDGPU_VRAM_TYPE_DDR2  2
> --
> 2.17.1
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH] drm/amdgpu: Add vbios info ioctl interface
@ 2021-04-14  9:08 Jiawei Gu
  2021-04-14 13:01 ` Alex Deucher
  0 siblings, 1 reply; 47+ messages in thread
From: Jiawei Gu @ 2021-04-14  9:08 UTC (permalink / raw)
  To: amd-gfx; +Cc: emily.deng, Jiawei Gu, roy.sun

Add AMDGPU_INFO_VBIOS_INFO subquery id for detailed vbios info.

Signed-off-by: Jiawei Gu <Jiawei.Gu@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c    |  19 +++
 drivers/gpu/drm/amd/amdgpu/atom.c          | 158 +++++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/atom.h          |  11 ++
 drivers/gpu/drm/amd/include/atomfirmware.h |  16 ++-
 include/uapi/drm/amdgpu_drm.h              |  15 ++
 5 files changed, 213 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 39ee88d29cca..a20b016b05ab 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -861,6 +861,25 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
 					    min((size_t)size, (size_t)(bios_size - bios_offset)))
 					? -EFAULT : 0;
 		}
+		case AMDGPU_INFO_VBIOS_INFO: {
+			struct drm_amdgpu_info_vbios vbios_info = {};
+			struct atom_context *atom_context;
+
+			atom_context = adev->mode_info.atom_context;
+			memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name));
+			vbios_info.dbdf = PCI_DEVID(adev->pdev->bus->number, adev->pdev->devfn);
+			memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn));
+			vbios_info.version = atom_context->version;
+			memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date));
+			memcpy(vbios_info.serial, adev->serial, sizeof(adev->serial));
+			vbios_info.dev_id = adev->pdev->device;
+			vbios_info.rev_id = adev->pdev->revision;
+			vbios_info.sub_dev_id = atom_context->sub_dev_id;
+			vbios_info.sub_ved_id = atom_context->sub_ved_id;
+
+			return copy_to_user(out, &vbios_info,
+						min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0;
+		}
 		default:
 			DRM_DEBUG_KMS("Invalid request %d\n",
 					info->vbios_info.type);
diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c
index 3dcb8b32f48b..0e2f0ea13b40 100644
--- a/drivers/gpu/drm/amd/amdgpu/atom.c
+++ b/drivers/gpu/drm/amd/amdgpu/atom.c
@@ -31,6 +31,7 @@
 
 #define ATOM_DEBUG
 
+#include "atomfirmware.h"
 #include "atom.h"
 #include "atom-names.h"
 #include "atom-bits.h"
@@ -1299,12 +1300,153 @@ static void atom_index_iio(struct atom_context *ctx, int base)
 	}
 }
 
+static void atom_get_vbios_name(struct atom_context *ctx)
+{
+	unsigned char *p_rom;
+	unsigned char str_num;
+	unsigned short off_to_vbios_str;
+	unsigned char *c_ptr;
+	int name_size;
+	int i;
+
+	const char *na = "--N/A--";
+	char *back;
+
+	p_rom = ctx->bios;
+
+	str_num = *(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS);
+	if (str_num != 0) {
+		off_to_vbios_str =
+			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
+
+		c_ptr = (unsigned char *)(p_rom + off_to_vbios_str);
+	} else {
+		/* do not know where to find name */
+		memcpy(ctx->name, na, 7);
+		ctx->name[7] = 0;
+		return;
+	}
+
+	/*
+	 * skip the atombios strings, usually 4
+	 * 1st is P/N, 2nd is ASIC, 3rd is PCI type, 4th is Memory type
+	 */
+	for (i = 0; i < str_num; i++) {
+		while (*c_ptr != 0)
+			c_ptr++;
+		c_ptr++;
+	}
+
+	/* skip the following 2 chars: 0x0D 0x0A */
+	c_ptr += 2;
+
+	name_size = strnlen(c_ptr, STRLEN_LONG - 1);
+	memcpy(ctx->name, c_ptr, name_size);
+	back = ctx->name + name_size;
+	while ((*--back) == ' ')
+		;
+	*(back + 1) = '\0';
+}
+
+static void atom_get_vbios_date(struct atom_context *ctx)
+{
+	unsigned char *p_rom;
+	unsigned char *date_in_rom;
+
+	p_rom = ctx->bios;
+
+	date_in_rom = p_rom + OFFSET_TO_VBIOS_DATE;
+
+	ctx->date[0] = '2';
+	ctx->date[1] = '0';
+	ctx->date[2] = date_in_rom[6];
+	ctx->date[3] = date_in_rom[7];
+	ctx->date[4] = '/';
+	ctx->date[5] = date_in_rom[0];
+	ctx->date[6] = date_in_rom[1];
+	ctx->date[7] = '/';
+	ctx->date[8] = date_in_rom[3];
+	ctx->date[9] = date_in_rom[4];
+	ctx->date[10] = ' ';
+	ctx->date[11] = date_in_rom[9];
+	ctx->date[12] = date_in_rom[10];
+	ctx->date[13] = date_in_rom[11];
+	ctx->date[14] = date_in_rom[12];
+	ctx->date[15] = date_in_rom[13];
+	ctx->date[16] = '\0';
+}
+
+static unsigned char *atom_find_str_in_rom(struct atom_context *ctx, char *str, int start,
+					   int end, int maxlen)
+{
+	unsigned long str_off;
+	unsigned char *p_rom;
+	unsigned short str_len;
+
+	str_off = 0;
+	str_len = strnlen(str, maxlen);
+	p_rom = ctx->bios;
+
+	for (; start <= end; ++start) {
+		for (str_off = 0; str_off < str_len; ++str_off) {
+			if (str[str_off] != *(p_rom + start + str_off))
+				break;
+		}
+
+		if (str_off == str_len || str[str_off] == 0)
+			return p_rom + start;
+	}
+	return NULL;
+}
+
+static void atom_get_vbios_pn(struct atom_context *ctx)
+{
+	unsigned char *p_rom;
+	unsigned short off_to_vbios_str;
+	unsigned char *vbios_str;
+	int count;
+
+	off_to_vbios_str = 0;
+	p_rom = ctx->bios;
+
+	if (*(p_rom + OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS) != 0) {
+		off_to_vbios_str =
+			*(unsigned short *)(p_rom + OFFSET_TO_GET_ATOMBIOS_STRING_START);
+
+		vbios_str = (unsigned char *)(p_rom + off_to_vbios_str);
+	} else {
+		vbios_str = p_rom + OFFSET_TO_VBIOS_PART_NUMBER;
+	}
+
+	if (*vbios_str == 0) {
+		vbios_str = atom_find_str_in_rom(ctx, BIOS_ATOM_PREFIX, 3, 1024, 64);
+		if (vbios_str == NULL)
+			vbios_str += sizeof(BIOS_ATOM_PREFIX) - 1;
+	}
+	if (vbios_str != NULL && *vbios_str == 0)
+		vbios_str++;
+
+	if (vbios_str != NULL) {
+		count = 0;
+		while ((count < BIOS_STRING_LENGTH) && vbios_str[count] >= ' ' &&
+		       vbios_str[count] <= 'z') {
+			ctx->vbios_pn[count] = vbios_str[count];
+			count++;
+		}
+
+		ctx->vbios_pn[count] = 0;
+	}
+}
+
 struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
 {
 	int base;
 	struct atom_context *ctx =
 	    kzalloc(sizeof(struct atom_context), GFP_KERNEL);
 	char *str;
+	struct _ATOM_ROM_HEADER *atom_rom_header;
+	struct _ATOM_MASTER_DATA_TABLE *master_table;
+	struct _ATOM_FIRMWARE_INFO *atom_fw_info;
 	u16 idx;
 
 	if (!ctx)
@@ -1353,6 +1495,22 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios)
 		strlcpy(ctx->vbios_version, str, sizeof(ctx->vbios_version));
 	}
 
+	atom_rom_header = (struct _ATOM_ROM_HEADER *)CSTR(base);
+	ctx->sub_dev_id = atom_rom_header->usSubsystemVendorID;
+	ctx->sub_ved_id = atom_rom_header->usSubsystemID;
+	if (atom_rom_header->usMasterDataTableOffset != 0) {
+		master_table = (struct _ATOM_MASTER_DATA_TABLE *)
+				CSTR(atom_rom_header->usMasterDataTableOffset);
+		if (master_table->ListOfDataTables.FirmwareInfo != 0) {
+			atom_fw_info = (struct _ATOM_FIRMWARE_INFO *)
+					CSTR(master_table->ListOfDataTables.FirmwareInfo);
+			ctx->version = atom_fw_info->ulFirmwareRevision;
+		}
+	}
+
+	atom_get_vbios_name(ctx);
+	atom_get_vbios_pn(ctx);
+	atom_get_vbios_date(ctx);
 
 	return ctx;
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/atom.h b/drivers/gpu/drm/amd/amdgpu/atom.h
index d279759cab47..c729f7ceba4f 100644
--- a/drivers/gpu/drm/amd/amdgpu/atom.h
+++ b/drivers/gpu/drm/amd/amdgpu/atom.h
@@ -112,6 +112,10 @@ struct drm_device;
 #define ATOM_IO_SYSIO		2
 #define ATOM_IO_IIO		0x80
 
+#define STRLEN_NORMAL		32
+#define STRLEN_LONG		64
+#define STRLEN_VERYLONG		254
+
 struct card_info {
 	struct drm_device *dev;
 	void (* reg_write)(struct card_info *, uint32_t, uint32_t);   /*  filled by driver */
@@ -140,6 +144,13 @@ struct atom_context {
 	uint32_t *scratch;
 	int scratch_size_bytes;
 	char vbios_version[20];
+
+	uint8_t name[STRLEN_LONG];
+	uint8_t vbios_pn[STRLEN_LONG];
+	uint32_t version;
+	uint8_t date[STRLEN_NORMAL];
+	uint32_t sub_dev_id;
+	uint32_t sub_ved_id;
 };
 
 extern int amdgpu_atom_debug;
diff --git a/drivers/gpu/drm/amd/include/atomfirmware.h b/drivers/gpu/drm/amd/include/atomfirmware.h
index c77ed38c20fb..3a8e404099b0 100644
--- a/drivers/gpu/drm/amd/include/atomfirmware.h
+++ b/drivers/gpu/drm/amd/include/atomfirmware.h
@@ -197,6 +197,8 @@ enum atom_dp_vs_preemph_def{
   DP_VS_LEVEL0_PREEMPH_LEVEL3 = 0x18,
 };
 
+#define BIOS_ATOM_PREFIX   "ATOMBIOS"
+#define BIOS_STRING_LENGTH 43
 
 /*
 enum atom_string_def{
@@ -209,12 +211,14 @@ atom_bios_string          = "ATOM"
 #pragma pack(1)                          /* BIOS data must use byte aligment*/
 
 enum atombios_image_offset{
-OFFSET_TO_ATOM_ROM_HEADER_POINTER          =0x00000048,
-OFFSET_TO_ATOM_ROM_IMAGE_SIZE              =0x00000002,
-OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       =0x94,
-MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      =20,  /*including the terminator 0x0!*/
-OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   =0x2f,
-OFFSET_TO_GET_ATOMBIOS_STRING_START        =0x6e,
+  OFFSET_TO_ATOM_ROM_HEADER_POINTER          = 0x00000048,
+  OFFSET_TO_ATOM_ROM_IMAGE_SIZE              = 0x00000002,
+  OFFSET_TO_ATOMBIOS_ASIC_BUS_MEM_TYPE       = 0x94,
+  MAXSIZE_OF_ATOMBIOS_ASIC_BUS_MEM_TYPE      = 20,  /*including the terminator 0x0!*/
+  OFFSET_TO_GET_ATOMBIOS_NUMBER_OF_STRINGS   = 0x2f,
+  OFFSET_TO_GET_ATOMBIOS_STRING_START        = 0x6e,
+  OFFSET_TO_VBIOS_PART_NUMBER                = 0x80,
+  OFFSET_TO_VBIOS_DATE                       = 0x50,
 };
 
 /****************************************************************************   
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index 8b832f7458f2..77980445d486 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -758,6 +758,8 @@ struct drm_amdgpu_cs_chunk_data {
 	#define AMDGPU_INFO_VBIOS_SIZE		0x1
 	/* Subquery id: Query vbios image */
 	#define AMDGPU_INFO_VBIOS_IMAGE		0x2
+	/* Subquery id: Query vbios info */
+	#define AMDGPU_INFO_VBIOS_INFO		0x3
 /* Query UVD handles */
 #define AMDGPU_INFO_NUM_HANDLES			0x1C
 /* Query sensor related information */
@@ -951,6 +953,19 @@ struct drm_amdgpu_info_firmware {
 	__u32 feature;
 };
 
+struct drm_amdgpu_info_vbios {
+	__u8 name[64];
+	__u32 dbdf;
+	__u8 vbios_pn[64];
+	__u32 version;
+	__u8 date[32];
+	__u8 serial[16];
+	__u32 dev_id;
+	__u32 rev_id;
+	__u32 sub_dev_id;
+	__u32 sub_ved_id;
+};
+
 #define AMDGPU_VRAM_TYPE_UNKNOWN 0
 #define AMDGPU_VRAM_TYPE_GDDR1 1
 #define AMDGPU_VRAM_TYPE_DDR2  2
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply related	[flat|nested] 47+ messages in thread

end of thread, other threads:[~2021-05-20 10:58 UTC | newest]

Thread overview: 47+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-18 12:16 [PATCH] drm/amdgpu: Add vbios info ioctl interface Jiawei Gu
2021-05-18 12:19 ` Gu, JiaWei (Will)
2021-05-18 13:17   ` Christian König
2021-05-18 13:25     ` StDenis, Tom
2021-05-19  2:41       ` Gu, JiaWei (Will)
2021-05-19  3:10         ` Marek Olšák
  -- strict thread matches above, loose matches on Subject: below --
2021-05-20  2:58 Jiawei Gu
2021-05-20  3:24 ` Alex Deucher
2021-05-17 12:08 Jiawei Gu
2021-05-17 12:17 ` Gu, JiaWei (Will)
2021-05-17 12:25   ` Christian König
2021-05-18  2:11     ` Gu, JiaWei (Will)
2021-05-18  2:44       ` Nieto, David M
2021-05-18  3:07         ` Gu, JiaWei (Will)
2021-05-18  4:40           ` Nieto, David M
2021-05-18  5:58             ` Gu, JiaWei (Will)
2021-05-18  7:23               ` Nieto, David M
2021-05-18 10:50               ` Lazar, Lijo
2021-05-19  3:17                 ` Nieto, David M
2021-05-19 13:09               ` Deucher, Alexander
2021-05-19 13:23                 ` Christian König
2021-05-20  1:30                   ` Gu, JiaWei (Will)
2021-05-20 10:58                     ` Christian König
2021-04-28  8:18 Jiawei Gu
2021-04-22  2:34 Jiawei Gu
2021-04-22 13:09 ` Gu, JiaWei (Will)
2021-04-22 13:18   ` Gu, JiaWei (Will)
2021-04-22 13:27     ` Christian König
2021-04-23  3:25       ` Gu, JiaWei (Will)
2021-04-28  6:47         ` Nieto, David M
2021-04-28  7:15           ` Christian König
2021-04-28  7:25             ` Nieto, David M
2021-04-28  7:42               ` Christian König
2021-04-28  8:21                 ` Gu, JiaWei (Will)
2021-04-28 10:38                   ` Gu, JiaWei (Will)
2021-04-28 11:30                     ` StDenis, Tom
2021-04-28 20:53                       ` Alex Deucher
2021-04-28 21:18                         ` StDenis, Tom
2021-05-08  4:28 ` Kees Cook
2021-05-08  4:28   ` Kees Cook
2021-05-08  6:01   ` Gu, JiaWei (Will)
2021-05-08  6:01     ` Gu, JiaWei (Will)
2021-05-08  9:51     ` Kees Cook
2021-05-08  9:51       ` Kees Cook
2021-05-09  5:35       ` Nieto, David M
2021-04-14  9:08 Jiawei Gu
2021-04-14 13:01 ` Alex Deucher

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.