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, ®)) 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