/* * AMD Nodes are a physical collection of I/O devices within an SoC. There can be one * or more nodes per package. * * The nodes are software-visible through PCI config space. All nodes are enumerated * on segment 0 bus 0. The device (slot) numbers range from 0x18 to 0x1F (maximum 8 * nodes) with 0x18 corresponding to node 0, 0x19 to node 1, etc. Each node can be a * multi-function device. * * On legacy systems, these node devices represent integrated Northbridge functionality. * On Zen-based systems, these node devices represent Data Fabric functionality. * * See "Configuration Space Accesses" section in BKDGs or * "Processor x86 Core" -> "Configuration Space" section in PPRs.
*/ struct pci_dev *amd_node_get_func(u16 node, u8 func)
{ if (node >= MAX_AMD_NUM_NODES) return NULL;
/* * SMN accesses may fail in ways that are difficult to detect here in the called * functions amd_smn_read() and amd_smn_write(). Therefore, callers must do * their own checking based on what behavior they expect. * * For SMN reads, the returned value may be zero if the register is Read-as-Zero. * Or it may be a "PCI Error Response", e.g. all 0xFFs. The "PCI Error Response" * can be checked here, and a proper error code can be returned. * * But the Read-as-Zero response cannot be verified here. A value of 0 may be * correct in some cases, so callers must check that this correct is for the * register/fields they need. * * For SMN writes, success can be determined through a "write and read back" * However, this is not robust when done here. * * Possible issues: * * 1) Bits that are "Write-1-to-Clear". In this case, the read value should * *not* match the write value. * * 2) Bits that are "Read-as-Zero"/"Writes-Ignored". This information cannot be * known here. * * 3) Bits that are "Reserved / Set to 1". Ditto above. * * Callers of amd_smn_write() should do the "write and read back" check * themselves, if needed. * * For #1, they can see if their target bits got cleared. * * For #2 and #3, they can check if their target bits got set as intended. * * This matches what is done for RDMSR/WRMSR. As long as there's no #GP, then * the operation is considered a success, and the caller does their own * checking.
*/ staticint __amd_smn_rw(u8 i_off, u8 d_off, u16 node, u32 address, u32 *value, bool write)
{ struct pci_dev *root; int err = -ENODEV;
/* * There are a few SMN index/data pairs and other registers * that shouldn't be accessed by user space. So reserve the * entire PCI config space for simplicity rather than covering * specific registers piecemeal.
*/ if (!pci_request_config_region_exclusive(root, 0, PCI_CFG_SPACE_SIZE, NULL)) {
pci_err(root, "Failed to reserve config space\n"); return -EEXIST;
}
count = 0;
node = 0;
root = NULL; while (node < num_nodes && (root = get_next_root(root))) { /* Use one root for each node and skip the rest. */ if (count++ % roots_per_node) continue;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.