Linux Hardware Monitor development
 help / color / mirror / Atom feed
From: Yazen Ghannam <yazen.ghannam@amd.com>
To: <linux-edac@vger.kernel.org>
Cc: <linux-kernel@vger.kernel.org>, <tony.luck@intel.com>,
	<x86@kernel.org>, <avadhut.naik@amd.com>, <john.allen@amd.com>,
	<mario.limonciello@amd.com>, <bhelgaas@google.com>,
	<Shyam-sundar.S-k@amd.com>, <richard.gong@amd.com>,
	<jdelvare@suse.com>, <linux@roeck-us.net>, <clemens@ladisch.de>,
	<hdegoede@redhat.com>, <ilpo.jarvinen@linux.intel.com>,
	<linux-pci@vger.kernel.org>, <linux-hwmon@vger.kernel.org>,
	<platform-driver-x86@vger.kernel.org>,
	<naveenkrishna.chatradhi@amd.com>,
	<carlos.bilbao.osdev@gmail.com>,
	Yazen Ghannam <yazen.ghannam@amd.com>
Subject: [PATCH 06/16] x86/amd_nb: Simplify root device search
Date: Wed, 23 Oct 2024 17:21:40 +0000	[thread overview]
Message-ID: <20241023172150.659002-7-yazen.ghannam@amd.com> (raw)
In-Reply-To: <20241023172150.659002-1-yazen.ghannam@amd.com>

The "root" device search was introduced to support SMN access for Zen
systems. This device represents a PCIe root complex. It is not the
same as the "CPU/node" devices found at slots 0x18-0x1F.

There may be multiple PCIe root complexes within an AMD node. Such is
the case with server or HEDT systems, etc. Therefore it is not enough to
assume "root <-> AMD node" is a 1-to-1 association.

Currently, this is handled by skipping "extra" root complexes during the
search. However, the hardware provides the PCI bus number of an AMD
node's root device.

Use the hardware info to get the root device's bus and drop the extra
search code and PCI IDs.

Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
---
 arch/x86/include/asm/amd_node.h |  1 +
 arch/x86/kernel/amd_nb.c        | 80 ++-------------------------------
 arch/x86/kernel/amd_node.c      | 57 +++++++++++++++++++++++
 3 files changed, 62 insertions(+), 76 deletions(-)

diff --git a/arch/x86/include/asm/amd_node.h b/arch/x86/include/asm/amd_node.h
index 622bd3038eeb..3f097dd479f8 100644
--- a/arch/x86/include/asm/amd_node.h
+++ b/arch/x86/include/asm/amd_node.h
@@ -23,5 +23,6 @@
 #define AMD_NODE0_PCI_SLOT	0x18
 
 struct pci_dev *amd_node_get_func(u16 node, u8 func);
+struct pci_dev *amd_node_get_root(u16 node);
 
 #endif /*_ASM_X86_AMD_NODE_H_*/
diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c
index 34c06b25782d..135ecc0a0166 100644
--- a/arch/x86/kernel/amd_nb.c
+++ b/arch/x86/kernel/amd_nb.c
@@ -15,44 +15,11 @@
 #include <linux/pci_ids.h>
 #include <asm/amd_nb.h>
 
-#define PCI_DEVICE_ID_AMD_17H_ROOT		0x1450
-#define PCI_DEVICE_ID_AMD_17H_M10H_ROOT		0x15d0
-#define PCI_DEVICE_ID_AMD_17H_M30H_ROOT		0x1480
-#define PCI_DEVICE_ID_AMD_17H_M60H_ROOT		0x1630
-#define PCI_DEVICE_ID_AMD_17H_MA0H_ROOT		0x14b5
-#define PCI_DEVICE_ID_AMD_19H_M10H_ROOT		0x14a4
-#define PCI_DEVICE_ID_AMD_19H_M40H_ROOT		0x14b5
-#define PCI_DEVICE_ID_AMD_19H_M60H_ROOT		0x14d8
-#define PCI_DEVICE_ID_AMD_19H_M70H_ROOT		0x14e8
-#define PCI_DEVICE_ID_AMD_1AH_M00H_ROOT		0x153a
-#define PCI_DEVICE_ID_AMD_1AH_M20H_ROOT		0x1507
-#define PCI_DEVICE_ID_AMD_1AH_M60H_ROOT		0x1122
-#define PCI_DEVICE_ID_AMD_MI200_ROOT		0x14bb
-#define PCI_DEVICE_ID_AMD_MI300_ROOT		0x14f8
-
 /* Protect the PCI config register pairs used for SMN. */
 static DEFINE_MUTEX(smn_mutex);
 
 static u32 *flush_words;
 
-static const struct pci_device_id amd_root_ids[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_ROOT) },
-	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M10H_ROOT) },
-	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M30H_ROOT) },
-	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M60H_ROOT) },
-	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_MA0H_ROOT) },
-	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M10H_ROOT) },
-	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M40H_ROOT) },
-	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M60H_ROOT) },
-	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M70H_ROOT) },
-	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M00H_ROOT) },
-	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M20H_ROOT) },
-	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M60H_ROOT) },
-	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI200_ROOT) },
-	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI300_ROOT) },
-	{}
-};
-
 static const struct pci_device_id amd_nb_misc_ids[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) },
@@ -85,11 +52,6 @@ static const struct pci_device_id amd_nb_misc_ids[] = {
 	{}
 };
 
-static const struct pci_device_id hygon_root_ids[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_17H_ROOT) },
-	{}
-};
-
 static const struct pci_device_id hygon_nb_misc_ids[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_17H_DF_F3) },
 	{}
@@ -222,19 +184,15 @@ EXPORT_SYMBOL_GPL(amd_smn_write);
 static int amd_cache_northbridges(void)
 {
 	const struct pci_device_id *misc_ids = amd_nb_misc_ids;
-	const struct pci_device_id *root_ids = amd_root_ids;
-	struct pci_dev *root, *misc;
+	struct pci_dev *misc;
 	struct amd_northbridge *nb;
-	u16 roots_per_misc = 0;
 	u16 misc_count = 0;
-	u16 root_count = 0;
-	u16 i, j;
+	u16 i;
 
 	if (amd_northbridges.num)
 		return 0;
 
 	if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) {
-		root_ids = hygon_root_ids;
 		misc_ids = hygon_nb_misc_ids;
 	}
 
@@ -245,23 +203,6 @@ static int amd_cache_northbridges(void)
 	if (!misc_count)
 		return -ENODEV;
 
-	root = NULL;
-	while ((root = next_northbridge(root, root_ids)))
-		root_count++;
-
-	if (root_count) {
-		roots_per_misc = root_count / misc_count;
-
-		/*
-		 * There should be _exactly_ N roots for each DF/SMN
-		 * interface.
-		 */
-		if (!roots_per_misc || (root_count % roots_per_misc)) {
-			pr_info("Unsupported AMD DF/PCI configuration found\n");
-			return -ENODEV;
-		}
-	}
-
 	nb = kcalloc(misc_count, sizeof(struct amd_northbridge), GFP_KERNEL);
 	if (!nb)
 		return -ENOMEM;
@@ -269,25 +210,12 @@ static int amd_cache_northbridges(void)
 	amd_northbridges.nb = nb;
 	amd_northbridges.num = misc_count;
 
-	misc = root = NULL;
+	misc = NULL;
 	for (i = 0; i < amd_northbridges.num; i++) {
-		node_to_amd_nb(i)->root = root =
-			next_northbridge(root, root_ids);
+		node_to_amd_nb(i)->root = amd_node_get_root(i);
 		node_to_amd_nb(i)->misc = misc =
 			next_northbridge(misc, misc_ids);
 		node_to_amd_nb(i)->link = amd_node_get_func(i, 4);
-
-		/*
-		 * If there are more PCI root devices than data fabric/
-		 * system management network interfaces, then the (N)
-		 * PCI roots per DF/SMN interface are functionally the
-		 * same (for DF/SMN access) and N-1 are redundant.  N-1
-		 * PCI roots should be skipped per DF/SMN interface so
-		 * the following DF/SMN interfaces get mapped to
-		 * correct PCI roots.
-		 */
-		for (j = 1; j < roots_per_misc; j++)
-			root = next_northbridge(root, root_ids);
 	}
 
 	if (amd_gart_present())
diff --git a/arch/x86/kernel/amd_node.c b/arch/x86/kernel/amd_node.c
index e825cd4426b9..3aaf7c81f0fa 100644
--- a/arch/x86/kernel/amd_node.c
+++ b/arch/x86/kernel/amd_node.c
@@ -32,3 +32,60 @@ struct pci_dev *amd_node_get_func(u16 node, u8 func)
 
 	return pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(AMD_NODE0_PCI_SLOT + node, func));
 }
+
+#define DF_BLK_INST_CNT		0x040
+#define	DF_CFG_ADDR_CNTL_LEGACY	0x084
+#define	DF_CFG_ADDR_CNTL_DF4	0xC04
+
+#define DF_MAJOR_REVISION	GENMASK(27, 24)
+
+static u16 get_cfg_addr_cntl_offset(struct pci_dev *df_f0)
+{
+	u32 reg;
+
+	/*
+	 * Revision fields added for DF4 and later.
+	 *
+	 * Major revision of '0' is found pre-DF4. Field is Read-as-Zero.
+	 */
+	if (pci_read_config_dword(df_f0, DF_BLK_INST_CNT, &reg))
+		return 0;
+
+	if (reg & DF_MAJOR_REVISION)
+		return DF_CFG_ADDR_CNTL_DF4;
+
+	return DF_CFG_ADDR_CNTL_LEGACY;
+}
+
+struct pci_dev *amd_node_get_root(u16 node)
+{
+	struct pci_dev *df_f0 __free(pci_dev_put) = NULL;
+	struct pci_dev *root;
+	u16 cntl_off;
+	u8 bus;
+
+	if (!boot_cpu_has(X86_FEATURE_ZEN))
+		return NULL;
+
+	/*
+	 * D18F0xXXX [Config Address Control] (DF::CfgAddressCntl)
+	 * Bits [7:0] (SecBusNum) holds the bus number of the root device for
+	 * this Data Fabric instance. The segment, device, and function will be 0.
+	 */
+	df_f0 = amd_node_get_func(node, 0);
+	if (!df_f0)
+		return NULL;
+
+	cntl_off = get_cfg_addr_cntl_offset(df_f0);
+	if (!cntl_off)
+		return NULL;
+
+	if (pci_read_config_byte(df_f0, cntl_off, &bus))
+		return NULL;
+
+	/* Grab the pointer for the actual root device instance. */
+	root = pci_get_domain_bus_and_slot(0, bus, 0);
+
+	pci_dbg(root, "is root for AMD node %u\n", node);
+	return root;
+}
-- 
2.43.0


  parent reply	other threads:[~2024-10-23 17:22 UTC|newest]

Thread overview: 65+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-23 17:21 [PATCH 00/16] AMD NB and SMN rework Yazen Ghannam
2024-10-23 17:21 ` [PATCH 01/16] x86/mce/amd: Remove shared threshold bank plumbing Yazen Ghannam
2024-10-23 17:21 ` [PATCH 02/16] x86/amd_nb: Restrict init function to AMD-based systems Yazen Ghannam
2024-10-31  8:09   ` Zhuo, Qiuxu
2024-10-31 10:36     ` Borislav Petkov
2024-10-31 11:50       ` Zhuo, Qiuxu
2024-10-31 13:11         ` Borislav Petkov
2024-10-23 17:21 ` [PATCH 03/16] x86/amd_nb: Clean up early_is_amd_nb() Yazen Ghannam
2024-10-25 15:58   ` Borislav Petkov
2024-10-29 14:39     ` Yazen Ghannam
2024-10-29 15:08       ` Borislav Petkov
2024-10-29 16:15         ` Luck, Tony
2024-10-30 14:21           ` Yazen Ghannam
2024-10-31  0:53             ` Sohil Mehta
2024-10-31 10:34               ` [PATCH] x86/cpufeature: Document cpu_feature_enabled() as the default to use Borislav Petkov
2024-10-31 18:26                 ` Sohil Mehta
2024-10-31 19:15                   ` Borislav Petkov
2024-11-05 19:59                 ` Dave Hansen
2024-10-31 10:24             ` [PATCH 03/16] x86/amd_nb: Clean up early_is_amd_nb() Borislav Petkov
2024-10-23 17:21 ` [PATCH 04/16] x86: Start moving AMD Node functionality out of AMD_NB Yazen Ghannam
2024-10-23 17:21 ` [PATCH 05/16] x86/amd_nb: Simplify function 4 search Yazen Ghannam
2024-10-31 11:15   ` Borislav Petkov
2024-10-23 17:21 ` Yazen Ghannam [this message]
2024-10-31  7:52   ` [PATCH 06/16] x86/amd_nb: Simplify root device search Zhuo, Qiuxu
2024-10-31 10:08     ` Ilpo Järvinen
2024-10-31 13:10       ` Zhuo, Qiuxu
2024-10-31 15:34       ` Yazen Ghannam
2024-10-31 15:42         ` Ilpo Järvinen
2024-10-31 15:45           ` Yazen Ghannam
2024-10-31 11:20   ` Borislav Petkov
2024-10-31 15:29     ` Yazen Ghannam
2024-10-23 17:21 ` [PATCH 07/16] x86/amd_nb: Use topology info to get AMD node count Yazen Ghannam
2024-10-23 17:21 ` [PATCH 08/16] x86/amd_nb: Simplify function 3 search Yazen Ghannam
2024-10-23 17:21 ` [PATCH 09/16] x86/amd_nb, x86/amd_node: Simplify amd_pci_dev_to_node_id() Yazen Ghannam
2024-11-04 14:23   ` Borislav Petkov
2024-11-05 14:54     ` Yazen Ghannam
2024-10-23 17:21 ` [PATCH 10/16] x86/amd_nb: Move SMN access code to a new amd_smn driver Yazen Ghannam
2024-11-04 14:29   ` Borislav Petkov
2024-11-05 14:58     ` Yazen Ghannam
2024-11-05 19:42       ` Borislav Petkov
2024-10-23 17:21 ` [PATCH 11/16] x86/amd_smn: Fixup __amd_smn_rw() Yazen Ghannam
2024-11-04 14:32   ` Borislav Petkov
2024-11-05 14:59     ` Yazen Ghannam
2024-10-23 17:21 ` [PATCH 12/16] x86/amd_smn: Remove dependency on AMD_NB Yazen Ghannam
2024-10-23 17:21 ` [PATCH 13/16] x86/amd_smn: Use defines for register offsets Yazen Ghannam
2024-10-23 17:21 ` [PATCH 14/16] x86/amd_smn, platform/x86/amd/hsmp: Have HSMP use SMN Yazen Ghannam
2024-10-24 13:23   ` Ilpo Järvinen
2024-10-24 16:06     ` Yazen Ghannam
2024-10-25 13:39       ` Ilpo Järvinen
2024-10-23 17:21 ` [PATCH 15/16] x86/amd_smn: Add SMN offsets to exclusive region access Yazen Ghannam
2024-10-23 17:21 ` [PATCH 16/16] x86/amd_smn: Add support for debugfs access to SMN registers Yazen Ghannam
2024-11-05 19:21   ` Borislav Petkov
2024-11-05 19:46     ` Mario Limonciello
2024-11-05 19:53       ` Borislav Petkov
2024-11-05 19:56         ` Mario Limonciello
2024-11-05 19:59           ` Borislav Petkov
2024-11-05 20:53             ` Mario Limonciello
2024-10-23 17:59 ` [PATCH 00/16] AMD NB and SMN rework Bjorn Helgaas
2024-10-24 16:01   ` Yazen Ghannam
2024-10-24 17:46     ` Bjorn Helgaas
2024-10-24 20:08       ` Mario Limonciello
2024-10-24 21:06         ` Bjorn Helgaas
2024-10-24 21:20           ` Mario Limonciello
2024-10-24 21:47             ` Bjorn Helgaas
2024-10-31 16:22               ` Yazen Ghannam

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=20241023172150.659002-7-yazen.ghannam@amd.com \
    --to=yazen.ghannam@amd.com \
    --cc=Shyam-sundar.S-k@amd.com \
    --cc=avadhut.naik@amd.com \
    --cc=bhelgaas@google.com \
    --cc=carlos.bilbao.osdev@gmail.com \
    --cc=clemens@ladisch.de \
    --cc=hdegoede@redhat.com \
    --cc=ilpo.jarvinen@linux.intel.com \
    --cc=jdelvare@suse.com \
    --cc=john.allen@amd.com \
    --cc=linux-edac@vger.kernel.org \
    --cc=linux-hwmon@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux@roeck-us.net \
    --cc=mario.limonciello@amd.com \
    --cc=naveenkrishna.chatradhi@amd.com \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=richard.gong@amd.com \
    --cc=tony.luck@intel.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

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

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