]> nv-tegra.nvidia Code Review - linux-3.10.git/blob - arch/x86_64/pci/k8-bus.c
Linux-2.6.12-rc2
[linux-3.10.git] / arch / x86_64 / pci / k8-bus.c
1 #include <linux/init.h>
2 #include <linux/pci.h>
3 #include <asm/mpspec.h>
4 #include <linux/cpumask.h>
5
6 /*
7  * This discovers the pcibus <-> node mapping on AMD K8.
8  *
9  * RED-PEN need to call this again on PCI hotplug
10  * RED-PEN empty cpus get reported wrong
11  */
12
13 #define NODE_ID_REGISTER 0x60
14 #define NODE_ID(dword) (dword & 0x07)
15 #define LDT_BUS_NUMBER_REGISTER_0 0x94
16 #define LDT_BUS_NUMBER_REGISTER_1 0xB4
17 #define LDT_BUS_NUMBER_REGISTER_2 0xD4
18 #define NR_LDT_BUS_NUMBER_REGISTERS 3
19 #define SECONDARY_LDT_BUS_NUMBER(dword) ((dword >> 8) & 0xFF)
20 #define SUBORDINATE_LDT_BUS_NUMBER(dword) ((dword >> 16) & 0xFF)
21 #define PCI_DEVICE_ID_K8HTCONFIG 0x1100
22
23 /**
24  * fill_mp_bus_to_cpumask()
25  * fills the mp_bus_to_cpumask array based according to the LDT Bus Number
26  * Registers found in the K8 northbridge
27  */
28 __init static int
29 fill_mp_bus_to_cpumask(void)
30 {
31         struct pci_dev *nb_dev = NULL;
32         int i, j, printed;
33         u32 ldtbus, nid;
34         static int lbnr[3] = {
35                 LDT_BUS_NUMBER_REGISTER_0,
36                 LDT_BUS_NUMBER_REGISTER_1,
37                 LDT_BUS_NUMBER_REGISTER_2
38         };
39
40         while ((nb_dev = pci_get_device(PCI_VENDOR_ID_AMD,
41                         PCI_DEVICE_ID_K8HTCONFIG, nb_dev))) {
42                 pci_read_config_dword(nb_dev, NODE_ID_REGISTER, &nid);
43
44                 for (i = 0; i < NR_LDT_BUS_NUMBER_REGISTERS; i++) {
45                         pci_read_config_dword(nb_dev, lbnr[i], &ldtbus);
46                         /*
47                          * if there are no busses hanging off of the current
48                          * ldt link then both the secondary and subordinate
49                          * bus number fields are set to 0.
50                          */
51                         if (!(SECONDARY_LDT_BUS_NUMBER(ldtbus) == 0
52                                 && SUBORDINATE_LDT_BUS_NUMBER(ldtbus) == 0)) {
53                                 for (j = SECONDARY_LDT_BUS_NUMBER(ldtbus);
54                                      j <= SUBORDINATE_LDT_BUS_NUMBER(ldtbus);
55                                      j++)
56                                         pci_bus_to_cpumask[j] =
57                                                 node_to_cpumask(NODE_ID(nid));
58                         }
59                 }
60         }
61
62         /* quick sanity check */
63         printed = 0;
64         for (i = 0; i < 256; i++) {
65                 if (cpus_empty(pci_bus_to_cpumask[i])) {
66                         pci_bus_to_cpumask[i] = CPU_MASK_ALL;
67                         if (printed)
68                                 continue;
69                         printk(KERN_ERR
70                                "k8-bus.c: some busses have empty cpu mask\n");
71                         printed = 1;
72                 }
73         }
74
75         return 0;
76 }
77
78 fs_initcall(fill_mp_bus_to_cpumask);