1 #include <linux/init.h>
3 #include <asm/pci-direct.h>
4 #include <asm/mpspec.h>
5 #include <linux/cpumask.h>
6 #include <linux/topology.h>
9 * This discovers the pcibus <-> node mapping on AMD K8.
11 * RED-PEN need to call this again on PCI hotplug
12 * RED-PEN empty cpus get reported wrong
15 #define NODE_ID(dword) ((dword>>4) & 0x07)
16 #define LDT_BUS_NUMBER_REGISTER_0 0xE0
17 #define LDT_BUS_NUMBER_REGISTER_1 0xE4
18 #define LDT_BUS_NUMBER_REGISTER_2 0xE8
19 #define LDT_BUS_NUMBER_REGISTER_3 0xEC
20 #define NR_LDT_BUS_NUMBER_REGISTERS 4
21 #define SECONDARY_LDT_BUS_NUMBER(dword) ((dword >> 16) & 0xFF)
22 #define SUBORDINATE_LDT_BUS_NUMBER(dword) ((dword >> 24) & 0xFF)
24 #define PCI_DEVICE_ID_K8HTCONFIG 0x1100
25 #define PCI_DEVICE_ID_K8_10H_HTCONFIG 0x1200
26 #define PCI_DEVICE_ID_K8_11H_HTCONFIG 0x1300
32 static int mp_bus_to_node[BUS_NR];
34 void set_mp_bus_to_node(int busnum, int node)
36 if (busnum >= 0 && busnum < BUS_NR)
37 mp_bus_to_node[busnum] = node;
40 int get_mp_bus_to_node(int busnum)
44 if (busnum < 0 || busnum > (BUS_NR - 1))
47 node = mp_bus_to_node[busnum];
50 * let numa_node_id to decide it later in dma_alloc_pages
51 * if there is no ram on that node
53 if (node != -1 && !node_online(node))
62 * early_fill_mp_bus_to_node()
63 * called before pcibios_scan_root and pci_scan_bus
64 * fills the mp_bus_to_cpumask array based according to the LDT Bus Number
65 * Registers found in the K8 northbridge
68 early_fill_mp_bus_to_node(void)
81 static int lbnr[NR_LDT_BUS_NUMBER_REGISTERS] = {
82 LDT_BUS_NUMBER_REGISTER_0,
83 LDT_BUS_NUMBER_REGISTER_1,
84 LDT_BUS_NUMBER_REGISTER_2,
85 LDT_BUS_NUMBER_REGISTER_3
88 for (i = 0; i < BUS_NR; i++)
89 mp_bus_to_node[i] = -1;
91 if (!early_pci_allowed())
95 id = read_pci_config(0, slot, 0, PCI_VENDOR_ID);
97 vendorid = id & 0xffff;
98 if (vendorid != PCI_VENDOR_ID_AMD)
101 deviceid = (id>>16) & 0xffff;
102 if ((deviceid != PCI_DEVICE_ID_K8HTCONFIG) &&
103 (deviceid != PCI_DEVICE_ID_K8_10H_HTCONFIG) &&
104 (deviceid != PCI_DEVICE_ID_K8_11H_HTCONFIG))
107 for (i = 0; i < NR_LDT_BUS_NUMBER_REGISTERS; i++) {
108 ldtbus = read_pci_config(0, slot, 1, lbnr[i]);
110 /* Check if that register is enabled for bus range */
111 if ((ldtbus & 7) != 3)
114 min_bus = SECONDARY_LDT_BUS_NUMBER(ldtbus);
115 max_bus = SUBORDINATE_LDT_BUS_NUMBER(ldtbus);
116 node = NODE_ID(ldtbus);
117 for (j = min_bus; j <= max_bus; j++)
118 mp_bus_to_node[j] = (unsigned char) node;
122 for (i = 0; i < BUS_NR; i++) {
123 node = mp_bus_to_node[i];
125 printk(KERN_DEBUG "bus: %02x to node: %02x\n", i, node);
131 postcore_initcall(early_fill_mp_bus_to_node);