xref: /linux-6.15/arch/x86/kernel/amd_node.c (revision d6caeafa)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * AMD Node helper functions and common defines
4  *
5  * Copyright (c) 2024, Advanced Micro Devices, Inc.
6  * All Rights Reserved.
7  *
8  * Author: Yazen Ghannam <[email protected]>
9  */
10 
11 #include <asm/amd_nb.h>
12 #include <asm/amd_node.h>
13 
14 /*
15  * AMD Nodes are a physical collection of I/O devices within an SoC. There can be one
16  * or more nodes per package.
17  *
18  * The nodes are software-visible through PCI config space. All nodes are enumerated
19  * on segment 0 bus 0. The device (slot) numbers range from 0x18 to 0x1F (maximum 8
20  * nodes) with 0x18 corresponding to node 0, 0x19 to node 1, etc. Each node can be a
21  * multi-function device.
22  *
23  * On legacy systems, these node devices represent integrated Northbridge functionality.
24  * On Zen-based systems, these node devices represent Data Fabric functionality.
25  *
26  * See "Configuration Space Accesses" section in BKDGs or
27  * "Processor x86 Core" -> "Configuration Space" section in PPRs.
28  */
29 struct pci_dev *amd_node_get_func(u16 node, u8 func)
30 {
31 	if (node >= MAX_AMD_NUM_NODES)
32 		return NULL;
33 
34 	return pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(AMD_NODE0_PCI_SLOT + node, func));
35 }
36 
37 #define DF_BLK_INST_CNT		0x040
38 #define	DF_CFG_ADDR_CNTL_LEGACY	0x084
39 #define	DF_CFG_ADDR_CNTL_DF4	0xC04
40 
41 #define DF_MAJOR_REVISION	GENMASK(27, 24)
42 
43 static u16 get_cfg_addr_cntl_offset(struct pci_dev *df_f0)
44 {
45 	u32 reg;
46 
47 	/*
48 	 * Revision fields added for DF4 and later.
49 	 *
50 	 * Major revision of '0' is found pre-DF4. Field is Read-as-Zero.
51 	 */
52 	if (pci_read_config_dword(df_f0, DF_BLK_INST_CNT, &reg))
53 		return 0;
54 
55 	if (reg & DF_MAJOR_REVISION)
56 		return DF_CFG_ADDR_CNTL_DF4;
57 
58 	return DF_CFG_ADDR_CNTL_LEGACY;
59 }
60 
61 struct pci_dev *amd_node_get_root(u16 node)
62 {
63 	struct pci_dev *root;
64 	u16 cntl_off;
65 	u8 bus;
66 
67 	if (!cpu_feature_enabled(X86_FEATURE_ZEN))
68 		return NULL;
69 
70 	/*
71 	 * D18F0xXXX [Config Address Control] (DF::CfgAddressCntl)
72 	 * Bits [7:0] (SecBusNum) holds the bus number of the root device for
73 	 * this Data Fabric instance. The segment, device, and function will be 0.
74 	 */
75 	struct pci_dev *df_f0 __free(pci_dev_put) = amd_node_get_func(node, 0);
76 	if (!df_f0)
77 		return NULL;
78 
79 	cntl_off = get_cfg_addr_cntl_offset(df_f0);
80 	if (!cntl_off)
81 		return NULL;
82 
83 	if (pci_read_config_byte(df_f0, cntl_off, &bus))
84 		return NULL;
85 
86 	/* Grab the pointer for the actual root device instance. */
87 	root = pci_get_domain_bus_and_slot(0, bus, 0);
88 
89 	pci_dbg(root, "is root for AMD node %u\n", node);
90 	return root;
91 }
92 
93 /* Protect the PCI config register pairs used for SMN. */
94 static DEFINE_MUTEX(smn_mutex);
95 
96 /*
97  * SMN accesses may fail in ways that are difficult to detect here in the called
98  * functions amd_smn_read() and amd_smn_write(). Therefore, callers must do
99  * their own checking based on what behavior they expect.
100  *
101  * For SMN reads, the returned value may be zero if the register is Read-as-Zero.
102  * Or it may be a "PCI Error Response", e.g. all 0xFFs. The "PCI Error Response"
103  * can be checked here, and a proper error code can be returned.
104  *
105  * But the Read-as-Zero response cannot be verified here. A value of 0 may be
106  * correct in some cases, so callers must check that this correct is for the
107  * register/fields they need.
108  *
109  * For SMN writes, success can be determined through a "write and read back"
110  * However, this is not robust when done here.
111  *
112  * Possible issues:
113  *
114  * 1) Bits that are "Write-1-to-Clear". In this case, the read value should
115  *    *not* match the write value.
116  *
117  * 2) Bits that are "Read-as-Zero"/"Writes-Ignored". This information cannot be
118  *    known here.
119  *
120  * 3) Bits that are "Reserved / Set to 1". Ditto above.
121  *
122  * Callers of amd_smn_write() should do the "write and read back" check
123  * themselves, if needed.
124  *
125  * For #1, they can see if their target bits got cleared.
126  *
127  * For #2 and #3, they can check if their target bits got set as intended.
128  *
129  * This matches what is done for RDMSR/WRMSR. As long as there's no #GP, then
130  * the operation is considered a success, and the caller does their own
131  * checking.
132  */
133 static int __amd_smn_rw(u16 node, u32 address, u32 *value, bool write)
134 {
135 	struct pci_dev *root;
136 	int err = -ENODEV;
137 
138 	if (node >= amd_nb_num())
139 		goto out;
140 
141 	root = node_to_amd_nb(node)->root;
142 	if (!root)
143 		goto out;
144 
145 	mutex_lock(&smn_mutex);
146 
147 	err = pci_write_config_dword(root, 0x60, address);
148 	if (err) {
149 		pr_warn("Error programming SMN address 0x%x.\n", address);
150 		goto out_unlock;
151 	}
152 
153 	err = (write ? pci_write_config_dword(root, 0x64, *value)
154 		     : pci_read_config_dword(root, 0x64, value));
155 
156 out_unlock:
157 	mutex_unlock(&smn_mutex);
158 
159 out:
160 	return err;
161 }
162 
163 int __must_check amd_smn_read(u16 node, u32 address, u32 *value)
164 {
165 	int err = __amd_smn_rw(node, address, value, false);
166 
167 	if (PCI_POSSIBLE_ERROR(*value)) {
168 		err = -ENODEV;
169 		*value = 0;
170 	}
171 
172 	return err;
173 }
174 EXPORT_SYMBOL_GPL(amd_smn_read);
175 
176 int __must_check amd_smn_write(u16 node, u32 address, u32 value)
177 {
178 	return __amd_smn_rw(node, address, &value, true);
179 }
180 EXPORT_SYMBOL_GPL(amd_smn_write);
181