diff options
author | Yinghai Lu <Yinghai.Lu@Sun.COM> | 2008-02-19 06:15:08 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-04-26 17:41:04 -0400 |
commit | 35ddd068fb94b187e94a3fc497ccecf27bdda9ae (patch) | |
tree | cac56f1558910b9943f4126241285eda7aa4afe1 /arch | |
parent | 871d5f8dd0f7647f03facd4cb79485938d1b61ab (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')
-rw-r--r-- | arch/x86/pci/k8-bus_64.c | 88 |
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 | ||
121 | out: | ||
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 | } |