aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/pci
diff options
context:
space:
mode:
authorYinghai Lu <Yinghai.Lu@Sun.COM>2008-02-19 06:15:08 -0500
committerIngo Molnar <mingo@elte.hu>2008-04-26 17:41:04 -0400
commit35ddd068fb94b187e94a3fc497ccecf27bdda9ae (patch)
treecac56f1558910b9943f4126241285eda7aa4afe1 /arch/x86/pci
parent871d5f8dd0f7647f03facd4cb79485938d1b61ab (diff)
x86: use bus conf in NB conf fun1 to get bus range on, on 64-bit
... so we use the same code with Quad core cpu as old opteron. This patch is useful when acpi=off or _PXM is not there in DSDT. Signed-off-by: Yinghai Lu <yinghai.lu@sun.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/pci')
-rw-r--r--arch/x86/pci/k8-bus_64.c88
1 files changed, 48 insertions, 40 deletions
diff --git a/arch/x86/pci/k8-bus_64.c b/arch/x86/pci/k8-bus_64.c
index 3903efbca535..dab38310ee97 100644
--- a/arch/x86/pci/k8-bus_64.c
+++ b/arch/x86/pci/k8-bus_64.c
@@ -12,15 +12,18 @@
12 * RED-PEN empty cpus get reported wrong 12 * RED-PEN empty cpus get reported wrong
13 */ 13 */
14 14
15#define NODE_ID_REGISTER 0x60 15#define NODE_ID(dword) ((dword>>4) & 0x07)
16#define NODE_ID(dword) (dword & 0x07) 16#define LDT_BUS_NUMBER_REGISTER_0 0xE0
17#define LDT_BUS_NUMBER_REGISTER_0 0x94 17#define LDT_BUS_NUMBER_REGISTER_1 0xE4
18#define LDT_BUS_NUMBER_REGISTER_1 0xB4 18#define LDT_BUS_NUMBER_REGISTER_2 0xE8
19#define LDT_BUS_NUMBER_REGISTER_2 0xD4 19#define LDT_BUS_NUMBER_REGISTER_3 0xEC
20#define NR_LDT_BUS_NUMBER_REGISTERS 3 20#define NR_LDT_BUS_NUMBER_REGISTERS 4
21#define SECONDARY_LDT_BUS_NUMBER(dword) ((dword >> 8) & 0xFF) 21#define SECONDARY_LDT_BUS_NUMBER(dword) ((dword >> 16) & 0xFF)
22#define SUBORDINATE_LDT_BUS_NUMBER(dword) ((dword >> 16) & 0xFF) 22#define SUBORDINATE_LDT_BUS_NUMBER(dword) ((dword >> 24) & 0xFF)
23
23#define PCI_DEVICE_ID_K8HTCONFIG 0x1100 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
24 27
25#ifdef CONFIG_NUMA 28#ifdef CONFIG_NUMA
26 29
@@ -67,12 +70,19 @@ early_fill_mp_bus_to_node(void)
67#ifdef CONFIG_NUMA 70#ifdef CONFIG_NUMA
68 int i, j; 71 int i, j;
69 unsigned slot; 72 unsigned slot;
70 u32 ldtbus, nid; 73 u32 ldtbus;
71 u32 id; 74 u32 id;
72 static int lbnr[3] = { 75 int node;
76 u16 deviceid;
77 u16 vendorid;
78 int min_bus;
79 int max_bus;
80
81 static int lbnr[NR_LDT_BUS_NUMBER_REGISTERS] = {
73 LDT_BUS_NUMBER_REGISTER_0, 82 LDT_BUS_NUMBER_REGISTER_0,
74 LDT_BUS_NUMBER_REGISTER_1, 83 LDT_BUS_NUMBER_REGISTER_1,
75 LDT_BUS_NUMBER_REGISTER_2 84 LDT_BUS_NUMBER_REGISTER_2,
85 LDT_BUS_NUMBER_REGISTER_3
76 }; 86 };
77 87
78 for (i = 0; i < BUS_NR; i++) 88 for (i = 0; i < BUS_NR; i++)
@@ -81,38 +91,36 @@ early_fill_mp_bus_to_node(void)
81 if (!early_pci_allowed()) 91 if (!early_pci_allowed())
82 return -1; 92 return -1;
83 93
84 for (slot = 0x18; slot < 0x20; slot++) { 94 slot = 0x18;
85 id = read_pci_config(0, slot, 0, PCI_VENDOR_ID); 95 id = read_pci_config(0, slot, 0, PCI_VENDOR_ID);
86 if (id != (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_K8HTCONFIG<<16))) 96
87 break; 97 vendorid = id & 0xffff;
88 nid = read_pci_config(0, slot, 0, NODE_ID_REGISTER); 98 if (vendorid != PCI_VENDOR_ID_AMD)
89 99 goto out;
90 for (i = 0; i < NR_LDT_BUS_NUMBER_REGISTERS; i++) { 100
91 ldtbus = read_pci_config(0, slot, 0, lbnr[i]); 101 deviceid = (id>>16) & 0xffff;
92 /* 102 if ((deviceid != PCI_DEVICE_ID_K8HTCONFIG) &&
93 * if there are no busses hanging off of the current 103 (deviceid != PCI_DEVICE_ID_K8_10H_HTCONFIG) &&
94 * ldt link then both the secondary and subordinate 104 (deviceid != PCI_DEVICE_ID_K8_11H_HTCONFIG))
95 * bus number fields are set to 0. 105 goto out;
96 * 106
97 * RED-PEN 107 for (i = 0; i < NR_LDT_BUS_NUMBER_REGISTERS; i++) {
98 * This is slightly broken because it assumes 108 ldtbus = read_pci_config(0, slot, 1, lbnr[i]);
99 * HT node IDs == Linux node ids, which is not always 109
100 * true. However it is probably mostly true. 110 /* Check if that register is enabled for bus range */
101 */ 111 if ((ldtbus & 7) != 3)
102 if (!(SECONDARY_LDT_BUS_NUMBER(ldtbus) == 0 112 continue;
103 && SUBORDINATE_LDT_BUS_NUMBER(ldtbus) == 0)) { 113
104 for (j = SECONDARY_LDT_BUS_NUMBER(ldtbus); 114 min_bus = SECONDARY_LDT_BUS_NUMBER(ldtbus);
105 j <= SUBORDINATE_LDT_BUS_NUMBER(ldtbus); 115 max_bus = SUBORDINATE_LDT_BUS_NUMBER(ldtbus);
106 j++) { 116 node = NODE_ID(ldtbus);
107 int node = NODE_ID(nid); 117 for (j = min_bus; j <= max_bus; j++)
108 mp_bus_to_node[j] = (unsigned char)node; 118 mp_bus_to_node[j] = (unsigned char) node;
109 }
110 }
111 }
112 } 119 }
113 120
121out:
114 for (i = 0; i < BUS_NR; i++) { 122 for (i = 0; i < BUS_NR; i++) {
115 int node = mp_bus_to_node[i]; 123 node = mp_bus_to_node[i];
116 if (node >= 0) 124 if (node >= 0)
117 printk(KERN_DEBUG "bus: %02x to node: %02x\n", i, node); 125 printk(KERN_DEBUG "bus: %02x to node: %02x\n", i, node);
118 } 126 }