1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31#include <mainboard.h>
32#include <config.h>
33#include <console.h>
34#include <lib.h>
35#include <string.h>
36#include <mtrr.h>
37#include <macros.h>
38#include <spd.h>
39#include <cpu.h>
40#include <msr.h>
41#include <amd/k8/k8.h>
42#include <amd/k8/sysconf.h>
43#include <device/pci.h>
44#include <device/hypertransport_def.h>
45#include <device/hypertransport.h>
46#include <mc146818rtc.h>
47#include <lib.h>
48#include <lapic.h>
49
50static unsigned int cpu_bus_scan(struct device * dev, unsigned int max)
51{
52 struct bus *cpu_bus;
53 struct device * dev_mc;
54 int bsp_apicid;
55 int i,j;
56 unsigned nb_cfg_54;
57 unsigned siblings;
58 int e0_later_single_core;
59 int disable_siblings;
60
61 nb_cfg_54 = 0;
62 sysconf.enabled_apic_ext_id = 0;
63 sysconf.lift_bsp_apicid = 0;
64 siblings = 0;
65
66
67 bsp_apicid = lapicid();
68 sysconf.apicid_offset = bsp_apicid;
69
70 disable_siblings = !CONFIG_LOGICAL_CPUS;
71#if CONFIG_LOGICAL_CPUS == 1
72 get_option(&disable_siblings, "dual_core");
73#endif
74
75
76
77
78 nb_cfg_54 = read_nb_cfg_54();
79
80 dev_mc = dev_find_slot(0, PCI_DEVFN(0x18, 0));
81 if (!dev_mc) {
82 die("0:18.0 not found?");
83 }
84
85 sysconf.nodes = ((pci_read_config32(dev_mc, 0x60)>>4) & 7) + 1;
86
87
88 if (pci_read_config32(dev_mc, 0x68) & (HTTC_APIC_EXT_ID|HTTC_APIC_EXT_BRD_CST))
89 {
90 sysconf.enabled_apic_ext_id = 1;
91 if(bsp_apicid == 0) {
92
93 sysconf.apicid_offset = CONFIG_APIC_ID_OFFSET;
94 } else
95 {
96 sysconf.lift_bsp_apicid = 1;
97 }
98
99 }
100
101
102 cpu_bus = &dev->link[0];
103 for(i = 0; i < sysconf.nodes; i++) {
104 struct device * dev, *cpu;
105 struct device_path cpu_path;
106
107
108 dev = dev_find_slot(0, PCI_DEVFN(0x18 + i, 3));
109 if (!dev) {
110
111
112
113 int j;
114 struct device * dev_f0;
115 for(j = 0; j <= 3; j++) {
116 dev = pci_probe_dev(NULL, dev_mc->bus,
117 PCI_DEVFN(0x18 + i, j));
118 }
119
120
121
122 dev_f0 = dev_find_slot(0, PCI_DEVFN(0x18+i,0));
123 if(dev_f0) {
124 dev_f0->links = 3;
125 for(j=0;j<3;j++) {
126 dev_f0->link[j].link = j;
127 dev_f0->link[j].dev = dev_f0;
128 }
129 }
130
131 }
132
133#warning clean this mess up
134 e0_later_single_core = 0;
135 if (dev && dev->enabled) {
136 j = pci_read_config32(dev, 0xe8);
137 j = (j >> 12) & 3;
138 printk(BIOS_DEBUG, " %s siblings=%d\n", dev_path(dev), j);
139
140 if(nb_cfg_54) {
141
142
143
144
145 if(j == 0 ){
146 e0_later_single_core = 1;
147 } else {
148 e0_later_single_core = 0;
149 }
150 if(e0_later_single_core) {
151 printk(BIOS_DEBUG, "\tFound Rev E or Rev F later single core\n");
152
153 j=1;
154 }
155
156 if(siblings > j ) {
157 }
158 else {
159 siblings = j;
160 }
161 } else {
162 siblings = j;
163 }
164 }
165
166 unsigned jj;
167 if(e0_later_single_core || disable_siblings) {
168 jj = 0;
169 } else
170 {
171 jj = siblings;
172 }
173#if 0
174 jj = 0;
175#endif
176
177 for (j = 0; j <=jj; j++ ) {
178
179
180 cpu_path.type = DEVICE_PATH_APIC;
181 cpu_path.apic.apic_id = i * (nb_cfg_54?(siblings+1):1) + j * (nb_cfg_54?1:8);
182
183
184 cpu = find_dev_path(cpu_bus, &cpu_path);
185
186
187 if (dev && dev->enabled) {
188
189 struct device_id did;
190 did.type = DEVICE_ID_CPU;
191#warning fill cpuid; right now it is zero
192 if (!cpu) {
193 cpu = alloc_dev(cpu_bus, &cpu_path, &did);
194 }
195 if (cpu) {
196 cpu->enabled = 1;
197 }
198 }
199
200
201 if (cpu && (!dev || !dev->enabled)) {
202 cpu->enabled = 0;
203 }
204
205
206 if (cpu) {
207 cpu->path.apic.node_id = i;
208 cpu->path.apic.core_id = j;
209 if(sysconf.enabled_apic_ext_id) {
210 if(sysconf.lift_bsp_apicid) {
211 cpu->path.apic.apic_id += sysconf.apicid_offset;
212 } else
213 {
214 if (cpu->path.apic.apic_id != 0)
215 cpu->path.apic.apic_id += sysconf.apicid_offset;
216 }
217 }
218 printk(BIOS_DEBUG, "CPU: %s %s\n",
219 dev_path(cpu), cpu->enabled?"enabled":"disabled");
220 }
221
222 }
223 }
224 return max;
225}
226
227static void cpu_bus_init(struct device * dev)
228{
229
230
231
232}
233
234static void cpu_bus_noop(struct device * dev)
235{
236}
237