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_node.h>
12
13 /*
14 * AMD Nodes are a physical collection of I/O devices within an SoC. There can be one
15 * or more nodes per package.
16 *
17 * The nodes are software-visible through PCI config space. All nodes are enumerated
18 * on segment 0 bus 0. The device (slot) numbers range from 0x18 to 0x1F (maximum 8
19 * nodes) with 0x18 corresponding to node 0, 0x19 to node 1, etc. Each node can be a
20 * multi-function device.
21 *
22 * On legacy systems, these node devices represent integrated Northbridge functionality.
23 * On Zen-based systems, these node devices represent Data Fabric functionality.
24 *
25 * See "Configuration Space Accesses" section in BKDGs or
26 * "Processor x86 Core" -> "Configuration Space" section in PPRs.
27 */
amd_node_get_func(u16 node,u8 func)28 struct pci_dev *amd_node_get_func(u16 node, u8 func)
29 {
30 if (node >= MAX_AMD_NUM_NODES)
31 return NULL;
32
33 return pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(AMD_NODE0_PCI_SLOT + node, func));
34 }
35
36 #define DF_BLK_INST_CNT 0x040
37 #define DF_CFG_ADDR_CNTL_LEGACY 0x084
38 #define DF_CFG_ADDR_CNTL_DF4 0xC04
39
40 #define DF_MAJOR_REVISION GENMASK(27, 24)
41
get_cfg_addr_cntl_offset(struct pci_dev * df_f0)42 static u16 get_cfg_addr_cntl_offset(struct pci_dev *df_f0)
43 {
44 u32 reg;
45
46 /*
47 * Revision fields added for DF4 and later.
48 *
49 * Major revision of '0' is found pre-DF4. Field is Read-as-Zero.
50 */
51 if (pci_read_config_dword(df_f0, DF_BLK_INST_CNT, ®))
52 return 0;
53
54 if (reg & DF_MAJOR_REVISION)
55 return DF_CFG_ADDR_CNTL_DF4;
56
57 return DF_CFG_ADDR_CNTL_LEGACY;
58 }
59
amd_node_get_root(u16 node)60 struct pci_dev *amd_node_get_root(u16 node)
61 {
62 struct pci_dev *root;
63 u16 cntl_off;
64 u8 bus;
65
66 if (!cpu_feature_enabled(X86_FEATURE_ZEN))
67 return NULL;
68
69 /*
70 * D18F0xXXX [Config Address Control] (DF::CfgAddressCntl)
71 * Bits [7:0] (SecBusNum) holds the bus number of the root device for
72 * this Data Fabric instance. The segment, device, and function will be 0.
73 */
74 struct pci_dev *df_f0 __free(pci_dev_put) = amd_node_get_func(node, 0);
75 if (!df_f0)
76 return NULL;
77
78 cntl_off = get_cfg_addr_cntl_offset(df_f0);
79 if (!cntl_off)
80 return NULL;
81
82 if (pci_read_config_byte(df_f0, cntl_off, &bus))
83 return NULL;
84
85 /* Grab the pointer for the actual root device instance. */
86 root = pci_get_domain_bus_and_slot(0, bus, 0);
87
88 pci_dbg(root, "is root for AMD node %u\n", node);
89 return root;
90 }
91
92 static struct pci_dev **amd_roots;
93
94 /* Protect the PCI config register pairs used for SMN. */
95 static DEFINE_MUTEX(smn_mutex);
96
97 #define SMN_INDEX_OFFSET 0x60
98 #define SMN_DATA_OFFSET 0x64
99
100 /*
101 * SMN accesses may fail in ways that are difficult to detect here in the called
102 * functions amd_smn_read() and amd_smn_write(). Therefore, callers must do
103 * their own checking based on what behavior they expect.
104 *
105 * For SMN reads, the returned value may be zero if the register is Read-as-Zero.
106 * Or it may be a "PCI Error Response", e.g. all 0xFFs. The "PCI Error Response"
107 * can be checked here, and a proper error code can be returned.
108 *
109 * But the Read-as-Zero response cannot be verified here. A value of 0 may be
110 * correct in some cases, so callers must check that this correct is for the
111 * register/fields they need.
112 *
113 * For SMN writes, success can be determined through a "write and read back"
114 * However, this is not robust when done here.
115 *
116 * Possible issues:
117 *
118 * 1) Bits that are "Write-1-to-Clear". In this case, the read value should
119 * *not* match the write value.
120 *
121 * 2) Bits that are "Read-as-Zero"/"Writes-Ignored". This information cannot be
122 * known here.
123 *
124 * 3) Bits that are "Reserved / Set to 1". Ditto above.
125 *
126 * Callers of amd_smn_write() should do the "write and read back" check
127 * themselves, if needed.
128 *
129 * For #1, they can see if their target bits got cleared.
130 *
131 * For #2 and #3, they can check if their target bits got set as intended.
132 *
133 * This matches what is done for RDMSR/WRMSR. As long as there's no #GP, then
134 * the operation is considered a success, and the caller does their own
135 * checking.
136 */
__amd_smn_rw(u8 i_off,u8 d_off,u16 node,u32 address,u32 * value,bool write)137 static int __amd_smn_rw(u8 i_off, u8 d_off, u16 node, u32 address, u32 *value, bool write)
138 {
139 struct pci_dev *root;
140 int err = -ENODEV;
141
142 if (node >= amd_num_nodes())
143 return err;
144
145 root = amd_roots[node];
146 if (!root)
147 return err;
148
149 guard(mutex)(&smn_mutex);
150
151 err = pci_write_config_dword(root, i_off, address);
152 if (err) {
153 pr_warn("Error programming SMN address 0x%x.\n", address);
154 return pcibios_err_to_errno(err);
155 }
156
157 err = (write ? pci_write_config_dword(root, d_off, *value)
158 : pci_read_config_dword(root, d_off, value));
159
160 return pcibios_err_to_errno(err);
161 }
162
amd_smn_read(u16 node,u32 address,u32 * value)163 int __must_check amd_smn_read(u16 node, u32 address, u32 *value)
164 {
165 int err = __amd_smn_rw(SMN_INDEX_OFFSET, SMN_DATA_OFFSET, 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
amd_smn_write(u16 node,u32 address,u32 value)176 int __must_check amd_smn_write(u16 node, u32 address, u32 value)
177 {
178 return __amd_smn_rw(SMN_INDEX_OFFSET, SMN_DATA_OFFSET, node, address, &value, true);
179 }
180 EXPORT_SYMBOL_GPL(amd_smn_write);
181
amd_cache_roots(void)182 static int amd_cache_roots(void)
183 {
184 u16 node, num_nodes = amd_num_nodes();
185
186 amd_roots = kcalloc(num_nodes, sizeof(*amd_roots), GFP_KERNEL);
187 if (!amd_roots)
188 return -ENOMEM;
189
190 for (node = 0; node < num_nodes; node++)
191 amd_roots[node] = amd_node_get_root(node);
192
193 return 0;
194 }
195
amd_smn_init(void)196 static int __init amd_smn_init(void)
197 {
198 int err;
199
200 if (!cpu_feature_enabled(X86_FEATURE_ZEN))
201 return 0;
202
203 guard(mutex)(&smn_mutex);
204
205 if (amd_roots)
206 return 0;
207
208 err = amd_cache_roots();
209 if (err)
210 return err;
211
212 return 0;
213 }
214
215 fs_initcall(amd_smn_init);
216