Whitespace cleanup (trivial).
[coreboot.git] / src / northbridge / amd / amdk8 / incoherent_ht.c
1 /*
2         This should be done by Eric
3         2004.12 yhlu add multi ht chain dynamically support
4         2005.11 yhlu add let real sb to use small unitid
5 */
6 #include <device/pci_def.h>
7 #include <device/pci_ids.h>
8 #include <device/hypertransport_def.h>
9
10 #ifndef K8_HT_FREQ_1G_SUPPORT
11         #define K8_HT_FREQ_1G_SUPPORT 0
12 #endif
13
14 #ifndef K8_SCAN_PCI_BUS
15         #define K8_SCAN_PCI_BUS 0
16 #endif
17
18 #ifndef K8_ALLOCATE_IO_RANGE
19         #define K8_ALLOCATE_IO_RANGE 0
20 #endif
21
22 // Do we need allocate MMIO? Current We direct last 64M to sblink only, We can not lose access to last 4M range to ROM
23 #ifndef K8_ALLOCATE_MMIO_RANGE
24         #define K8_ALLOCATE_MMIO_RANGE 0
25 #endif
26
27 static inline void print_linkn_in (const char *strval, uint8_t byteval)
28 {
29 #if CONFIG_USE_PRINTK_IN_CAR
30         printk_debug("%s%02x\r\n", strval, byteval);
31 #else
32         print_debug(strval); print_debug_hex8(byteval); print_debug("\r\n");
33 #endif
34 }
35
36 static uint8_t ht_lookup_capability(device_t dev, uint16_t val)
37 {
38         uint8_t pos;
39         uint8_t hdr_type;
40
41         hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
42         pos = 0;
43         hdr_type &= 0x7f;
44
45         if ((hdr_type == PCI_HEADER_TYPE_NORMAL) ||
46             (hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
47                 pos = PCI_CAPABILITY_LIST;
48         }
49         if (pos > PCI_CAP_LIST_NEXT) {
50                 pos = pci_read_config8(dev, pos);
51         }
52         while(pos != 0) { /* loop through the linked list */
53                 uint8_t cap;
54                 cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID);
55                 if (cap == PCI_CAP_ID_HT) {
56                         uint16_t flags;
57
58                         flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
59                         if ((flags >> 13) == val) {
60                                 /* Entry is a slave or host , success... */
61                                 break;
62                         }
63                 }
64                 pos = pci_read_config8(dev, pos + PCI_CAP_LIST_NEXT);
65         }
66         return pos;
67 }
68
69 static uint8_t ht_lookup_slave_capability(device_t dev)
70 {
71         return ht_lookup_capability(dev, 0); // Slave/Primary Interface Block Format
72 }
73
74 static uint8_t ht_lookup_host_capability(device_t dev)
75 {
76         return ht_lookup_capability(dev, 1); // Host/Secondary Interface Block Format
77 }
78
79 static void ht_collapse_previous_enumeration(uint8_t bus, unsigned offset_unitid)
80 {
81         device_t dev;
82         uint32_t id;
83
84         //actually, only for one HT device HT chain, and unitid is 0
85 #if HT_CHAIN_UNITID_BASE == 0
86         if(offset_unitid) {
87                 return;
88         }
89 #endif
90
91         /* Check if is already collapsed */
92         if((!offset_unitid) || (offset_unitid && (!((HT_CHAIN_END_UNITID_BASE == 0) && (HT_CHAIN_END_UNITID_BASE <HT_CHAIN_UNITID_BASE))))) {
93                 dev = PCI_DEV(bus, 0, 0);
94                 id = pci_read_config32(dev, PCI_VENDOR_ID);
95                 if (!((id == 0xffffffff) || (id == 0x00000000) ||
96                       (id == 0x0000ffff) || (id == 0xffff0000))) {
97                         return;
98                 }
99         }
100
101         /* Spin through the devices and collapse any previous
102          * hypertransport enumeration.
103          */
104         for(dev = PCI_DEV(bus, 1, 0); dev <= PCI_DEV(bus, 0x1f, 0x7); dev += PCI_DEV(0, 1, 0)) {
105                 uint32_t id;
106                 uint8_t pos;
107                 uint16_t flags;
108
109                 id = pci_read_config32(dev, PCI_VENDOR_ID);
110                 if ((id == 0xffffffff) || (id == 0x00000000) ||
111                     (id == 0x0000ffff) || (id == 0xffff0000)) {
112                         continue;
113                 }
114
115                 pos = ht_lookup_slave_capability(dev);
116                 if (!pos) {
117                         continue;
118                 }
119
120                 /* Clear the unitid */
121                 flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
122                 flags &= ~0x1f;
123                 pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
124         }
125 }
126
127 static uint16_t ht_read_freq_cap(device_t dev, uint8_t pos)
128 {
129         /* Handle bugs in valid hypertransport frequency reporting */
130         uint16_t freq_cap;
131         uint32_t id;
132
133         freq_cap = pci_read_config16(dev, pos);
134         freq_cap &= ~(1 << HT_FREQ_VENDOR); /* Ignore Vendor HT frequencies */
135
136         id = pci_read_config32(dev, 0);
137
138         /* AMD 8131 Errata 48 */
139         if (id == (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_AMD_8131_PCIX << 16))) {
140                 freq_cap &= ~(1 << HT_FREQ_800Mhz);
141                 return freq_cap;
142         }
143
144         /* AMD 8151 Errata 23 */
145         if (id == (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_AMD_8151_SYSCTRL << 16))) {
146                 freq_cap &= ~(1 << HT_FREQ_800Mhz);
147                 return freq_cap;
148         }
149
150         /* AMD K8 Unsupported 1Ghz? */
151         if (id == (PCI_VENDOR_ID_AMD | (0x1100 << 16))) {
152         #if K8_HT_FREQ_1G_SUPPORT == 1
153                 #if K8_REV_F_SUPPORT == 0
154                 if (is_cpu_pre_e0()) {  // only E0 later support 1GHz
155                         freq_cap &= ~(1 << HT_FREQ_1000Mhz);
156                 }
157                 #endif
158         #else
159                 freq_cap &= ~(1 << HT_FREQ_1000Mhz);
160         #endif
161         }
162
163         return freq_cap;
164 }
165
166 static uint8_t ht_read_width_cap(device_t dev, uint8_t pos)
167 {
168         uint8_t width_cap = pci_read_config8(dev, pos);
169
170         uint32_t id;
171
172         id = pci_read_config32(dev, 0);
173
174         /* netlogic micro cap doesn't support 16 bit yet */
175         if (id == (0x184e | (0x0001 << 16))) {
176                 if((width_cap & 0x77) == 0x11) {
177                         width_cap &= 0x88;
178                 }
179         }
180
181         return width_cap;
182
183 }
184
185 #define LINK_OFFS(CTRL, WIDTH,FREQ,FREQ_CAP) \
186         (((CTRL & 0xff) << 24) | ((WIDTH & 0xff) << 16) | ((FREQ & 0xff) << 8) | (FREQ_CAP & 0xFF))
187
188 #define LINK_CTRL(OFFS)     ((OFFS >> 24) & 0xFF)
189 #define LINK_WIDTH(OFFS)    ((OFFS >> 16) & 0xFF)
190 #define LINK_FREQ(OFFS)     ((OFFS >> 8) & 0xFF)
191 #define LINK_FREQ_CAP(OFFS) ((OFFS) & 0xFF)
192
193 #define PCI_HT_HOST_OFFS LINK_OFFS(             \
194                 PCI_HT_CAP_HOST_CTRL,           \
195                 PCI_HT_CAP_HOST_WIDTH,          \
196                 PCI_HT_CAP_HOST_FREQ,           \
197                 PCI_HT_CAP_HOST_FREQ_CAP)
198
199 #define PCI_HT_SLAVE0_OFFS LINK_OFFS(           \
200                 PCI_HT_CAP_SLAVE_CTRL0,         \
201                 PCI_HT_CAP_SLAVE_WIDTH0,        \
202                 PCI_HT_CAP_SLAVE_FREQ0,         \
203                 PCI_HT_CAP_SLAVE_FREQ_CAP0)
204
205 #define PCI_HT_SLAVE1_OFFS LINK_OFFS(           \
206                 PCI_HT_CAP_SLAVE_CTRL1,         \
207                 PCI_HT_CAP_SLAVE_WIDTH1,        \
208                 PCI_HT_CAP_SLAVE_FREQ1,         \
209                 PCI_HT_CAP_SLAVE_FREQ_CAP1)
210
211 static int ht_optimize_link(
212         device_t dev1, uint8_t pos1, unsigned offs1,
213         device_t dev2, uint8_t pos2, unsigned offs2)
214 {
215         static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
216         static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
217         uint16_t freq_cap1, freq_cap2;
218         uint8_t width_cap1, width_cap2, width, old_width, ln_width1, ln_width2;
219         uint8_t freq, old_freq;
220         int needs_reset;
221         /* Set link width and frequency */
222
223         /* Initially assume everything is already optimized and I don't need a reset */
224         needs_reset = 0;
225
226         /* Get the frequency capabilities */
227         freq_cap1 = ht_read_freq_cap(dev1, pos1 + LINK_FREQ_CAP(offs1));
228         freq_cap2 = ht_read_freq_cap(dev2, pos2 + LINK_FREQ_CAP(offs2));
229
230         /* Calculate the highest possible frequency */
231         freq = log2(freq_cap1 & freq_cap2);
232
233         /* See if I am changing the link freqency */
234         old_freq = pci_read_config8(dev1, pos1 + LINK_FREQ(offs1));
235         old_freq &= 0x0f;
236         needs_reset |= old_freq != freq;
237         old_freq = pci_read_config8(dev2, pos2 + LINK_FREQ(offs2));
238         old_freq &= 0x0f;
239         needs_reset |= old_freq != freq;
240
241         /* Set the Calulcated link frequency */
242         pci_write_config8(dev1, pos1 + LINK_FREQ(offs1), freq);
243         pci_write_config8(dev2, pos2 + LINK_FREQ(offs2), freq);
244
245         /* Get the width capabilities */
246         width_cap1 = ht_read_width_cap(dev1, pos1 + LINK_WIDTH(offs1));
247         width_cap2 = ht_read_width_cap(dev2, pos2 + LINK_WIDTH(offs2));
248
249         /* Calculate dev1's input width */
250         ln_width1 = link_width_to_pow2[width_cap1 & 7];
251         ln_width2 = link_width_to_pow2[(width_cap2 >> 4) & 7];
252         if (ln_width1 > ln_width2) {
253                 ln_width1 = ln_width2;
254         }
255         width = pow2_to_link_width[ln_width1];
256         /* Calculate dev1's output width */
257         ln_width1 = link_width_to_pow2[(width_cap1 >> 4) & 7];
258         ln_width2 = link_width_to_pow2[width_cap2 & 7];
259         if (ln_width1 > ln_width2) {
260                 ln_width1 = ln_width2;
261         }
262         width |= pow2_to_link_width[ln_width1] << 4;
263
264         /* See if I am changing dev1's width */
265         old_width = pci_read_config8(dev1, pos1 + LINK_WIDTH(offs1) + 1);
266         old_width &= 0x77;
267         needs_reset |= old_width != width;
268
269         /* Set dev1's widths */
270         pci_write_config8(dev1, pos1 + LINK_WIDTH(offs1) + 1, width);
271
272         /* Calculate dev2's width */
273         width = ((width & 0x70) >> 4) | ((width & 0x7) << 4);
274
275         /* See if I am changing dev2's width */
276         old_width = pci_read_config8(dev2, pos2 + LINK_WIDTH(offs2) + 1);
277         old_width &= 0x77;
278         needs_reset |= old_width != width;
279
280         /* Set dev2's widths */
281         pci_write_config8(dev2, pos2 + LINK_WIDTH(offs2) + 1, width);
282
283         return needs_reset;
284 }
285
286 #if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1)
287
288 #if RAMINIT_SYSINFO == 1
289 static void ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned offset_unitid, struct sys_info *sysinfo);
290 static int scan_pci_bus( unsigned bus , struct sys_info *sysinfo)
291 #else
292 static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned offset_unitid);
293 static int scan_pci_bus( unsigned bus)
294 #endif
295 {
296         /*
297                 here we already can access PCI_DEV(bus, 0, 0) to PCI_DEV(bus, 0x1f, 0x7)
298                 So We can scan these devices to find out if they are bridge
299                 If it is pci bridge, We need to set busn in bridge, and go on
300                 For ht bridge, We need to set the busn in bridge and ht_setup_chainx, and the scan_pci_bus
301         */
302         unsigned int devfn;
303         unsigned new_bus;
304         unsigned max_bus;
305
306         new_bus = (bus & 0xff); // mask out the reset_needed
307
308         if(new_bus<0x40) {
309                 max_bus = 0x3f;
310         } else if (new_bus<0x80) {
311                 max_bus = 0x7f;
312         } else if (new_bus<0xc0) {
313                 max_bus = 0xbf;
314         } else {
315                 max_bus = 0xff;
316         }
317
318         new_bus = bus;
319
320         for (devfn = 0; devfn <= 0xff; devfn++) {
321                 uint8_t hdr_type;
322                 uint16_t class;
323                 uint32_t buses;
324                 device_t dev;
325                 uint16_t cr;
326                 dev = PCI_DEV((bus & 0xff), ((devfn>>3) & 0x1f), (devfn & 0x7));
327                 hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
328                 class = pci_read_config16(dev, PCI_CLASS_DEVICE);
329
330                 switch(hdr_type & 0x7f) {  /* header type */
331                         case PCI_HEADER_TYPE_BRIDGE:
332                                 if (class  != PCI_CLASS_BRIDGE_PCI) goto bad;
333                                 /* set the bus range dev */
334
335                                 /* Clear all status bits and turn off memory, I/O and master enables. */
336                                 cr = pci_read_config16(dev, PCI_COMMAND);
337                                 pci_write_config16(dev, PCI_COMMAND, 0x0000);
338                                 pci_write_config16(dev, PCI_STATUS, 0xffff);
339
340                                 buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
341
342                                 buses &= 0xff000000;
343                                 new_bus++;
344                                 buses |= (((unsigned int) (bus & 0xff) << 0) |
345                                         ((unsigned int) (new_bus & 0xff) << 8) |
346                                         ((unsigned int) max_bus << 16));
347                                 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
348
349                                 /* here we need to figure out if dev is a ht bridge
350                                         if it is ht bridge, we need to call ht_setup_chainx at first
351                                         Not verified --- yhlu
352                                 */
353                                 uint8_t upos;
354                                 upos = ht_lookup_host_capability(dev); // one func one ht sub
355                                 if (upos) { // sub ht chain
356                                         uint8_t busn;
357                                         busn = (new_bus & 0xff);
358                                         /* Make certain the HT bus is not enumerated */
359                                         ht_collapse_previous_enumeration(busn, 0);
360                                         /* scan the ht chain */
361                                         #if RAMINIT_SYSINFO == 1
362                                         ht_setup_chainx(dev,upos,busn, 0, sysinfo); // don't need offset unitid
363                                         #else
364                                         new_bus |= (ht_setup_chainx(dev, upos, busn, 0)<<16); // store reset_needed to upword
365                                         #endif
366                                 }
367
368                                 #if RAMINIT_SYSINFO == 1
369                                 new_bus = scan_pci_bus(new_bus, sysinfo);
370                                 #else
371                                 new_bus = scan_pci_bus(new_bus);
372                                 #endif
373                                 /* set real max bus num in that */
374
375                                 buses = (buses & 0xff00ffff) |
376                                         ((unsigned int) (new_bus & 0xff) << 16);
377                                 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
378
379                                 pci_write_config16(dev, PCI_COMMAND, cr);
380
381                                 break;
382                         default:
383                         bad:
384                                 ;
385                 }
386
387                 /* if this is not a multi function device,
388                  * or the device is not present don't waste
389                  * time probing another function.
390                  * Skip to next device.
391                  */
392                 if ( ((devfn & 0x07) == 0x00) && ((hdr_type & 0x80) != 0x80))
393                 {
394                         devfn += 0x07;
395                 }
396         }
397
398         return new_bus;
399 }
400 #endif
401
402 #if RAMINIT_SYSINFO == 1
403 static void ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned offset_unitid, struct sys_info *sysinfo)
404 #else
405 static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned offset_unitid)
406 #endif
407 {
408         //even HT_CHAIN_UNITID_BASE == 0, we still can go through this function, because of end_of_chain check, also We need it to optimize link
409
410         uint8_t next_unitid, last_unitid;
411         unsigned uoffs;
412
413 #if RAMINIT_SYSINFO == 0
414         int reset_needed = 0;
415 #endif
416
417 #if HT_CHAIN_END_UNITID_BASE != 0x20
418         //let't record the device of last ht device, So we can set the Unitid to HT_CHAIN_END_UNITID_BASE
419         unsigned real_last_unitid;
420         uint8_t real_last_pos;
421         int ht_dev_num = 0;
422         uint8_t end_used = 0;
423 #endif
424
425         uoffs = PCI_HT_HOST_OFFS;
426         next_unitid = (offset_unitid) ? HT_CHAIN_UNITID_BASE:1;
427
428         do {
429                 uint32_t id;
430                 uint8_t pos;
431                 uint16_t flags, ctrl;
432                 uint8_t count;
433                 unsigned offs;
434
435                 /* Wait until the link initialization is complete */
436                 do {
437                         ctrl = pci_read_config16(udev, upos + LINK_CTRL(uoffs));
438                         /* Is this the end of the hypertransport chain? */
439                         if (ctrl & (1 << 6)) {
440                                 goto end_of_chain;
441                         }
442
443                         if (ctrl & ((1 << 4) | (1 << 8))) {
444                                 /*
445                                  * Either the link has failed, or we have
446                                  * a CRC error.
447                                  * Sometimes this can happen due to link
448                                  * retrain, so lets knock it down and see
449                                  * if its transient
450                                  */
451                                 ctrl |= ((1 << 4) | (1 <<8)); // Link fail + Crc
452                                 pci_write_config16(udev, upos + LINK_CTRL(uoffs), ctrl);
453                                 ctrl = pci_read_config16(udev, upos + LINK_CTRL(uoffs));
454                                 if (ctrl & ((1 << 4) | (1 << 8))) {
455                                         print_err("Detected error on Hypertransport Link\n");
456                                         break;
457                                 }
458                         }
459                 } while((ctrl & (1 << 5)) == 0);
460
461                 device_t dev = PCI_DEV(bus, 0, 0);
462                 last_unitid = next_unitid;
463
464                 id = pci_read_config32(dev, PCI_VENDOR_ID);
465
466                 /* If the chain is enumerated quit */
467                 if ((id == 0xffffffff) || (id == 0x00000000) ||
468                     (id == 0x0000ffff) || (id == 0xffff0000))
469                 {
470                         break;
471                 }
472
473                 pos = ht_lookup_slave_capability(dev);
474                 if (!pos) {
475                         print_err("udev="); print_err_hex32(udev);
476                         print_err("\tupos="); print_err_hex32(upos);
477                         print_err("\tuoffs="); print_err_hex32(uoffs);
478                         print_err("\tHT link capability not found\r\n");
479                         break;
480                 }
481
482
483 #if HT_CHAIN_END_UNITID_BASE != 0x20
484                 if(offset_unitid) {
485                         if(next_unitid>= (bus ? 0x20:0x18) ) {
486                                 if(!end_used) {
487                                         next_unitid = HT_CHAIN_END_UNITID_BASE;
488                                         end_used = 1;
489                                 } else {
490                                         goto out;
491                                 }
492
493                         }
494                         real_last_pos = pos;
495                         real_last_unitid = next_unitid;
496                         ht_dev_num++;
497                 }
498 #endif
499                 /* Update the Unitid of the current device */
500                 flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
501                 flags &= ~0x1f; /* mask out the base Unit ID */
502                 flags |= next_unitid & 0x1f;
503                 pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
504
505                 /* Compute the number of unitids consumed */
506                 count = (flags >> 5) & 0x1f;
507
508                 /* Note the change in device number */
509                 dev = PCI_DEV(bus, next_unitid, 0);
510
511                 next_unitid += count;
512
513                 /* Find which side of the ht link we are on,
514                  * by reading which direction our last write to PCI_CAP_FLAGS
515                  * came from.
516                  */
517                 flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
518                 offs = ((flags>>10) & 1) ? PCI_HT_SLAVE1_OFFS : PCI_HT_SLAVE0_OFFS;
519
520                 #if RAMINIT_SYSINFO == 1
521                 /* store the link pair here and we will Setup the Hypertransport link later, after we get final FID/VID */
522                 {
523                         struct link_pair_st *link_pair = &sysinfo->link_pair[sysinfo->link_pair_num];
524                         link_pair->udev = udev;
525                         link_pair->upos = upos;
526                         link_pair->uoffs = uoffs;
527                         link_pair->dev = dev;
528                         link_pair->pos = pos;
529                         link_pair->offs = offs;
530                         sysinfo->link_pair_num++;
531                 }
532                 #else
533                 reset_needed |= ht_optimize_link(udev, upos, uoffs, dev, pos, offs);
534                 #endif
535
536                 /* Remeber the location of the last device */
537                 udev = dev;
538                 upos = pos;
539                 uoffs = ( offs != PCI_HT_SLAVE0_OFFS ) ? PCI_HT_SLAVE0_OFFS : PCI_HT_SLAVE1_OFFS;
540
541         } while (last_unitid != next_unitid );
542
543 out:
544 end_of_chain: ;
545
546 #if HT_CHAIN_END_UNITID_BASE != 0x20
547         if(offset_unitid && (ht_dev_num>1) && (real_last_unitid != HT_CHAIN_END_UNITID_BASE) && !end_used ) {
548                 uint16_t flags;
549                 int i;
550                 flags = pci_read_config16(PCI_DEV(bus,real_last_unitid,0), real_last_pos + PCI_CAP_FLAGS);
551                 flags &= ~0x1f;
552                 flags |= HT_CHAIN_END_UNITID_BASE & 0x1f;
553                 pci_write_config16(PCI_DEV(bus, real_last_unitid, 0), real_last_pos + PCI_CAP_FLAGS, flags);
554
555                 #if RAMINIT_SYSINFO == 1
556                 // Here need to change the dev in the array
557                 for(i=0;i<sysinfo->link_pair_num;i++)
558                 {
559                         struct link_pair_st *link_pair = &sysinfo->link_pair[i];
560                         if(link_pair->udev == PCI_DEV(bus, real_last_unitid, 0)) {
561                                 link_pair->udev = PCI_DEV(bus, HT_CHAIN_END_UNITID_BASE, 0);
562                                 continue;
563                         }
564                         if(link_pair->dev == PCI_DEV(bus, real_last_unitid, 0)) {
565                                 link_pair->dev = PCI_DEV(bus, HT_CHAIN_END_UNITID_BASE, 0);
566                         }
567                 }
568                 #endif
569
570         }
571 #endif
572
573 #if RAMINIT_SYSINFO == 0
574         return reset_needed;
575 #endif
576
577 }
578
579 #if RAMINIT_SYSINFO == 1
580 static void ht_setup_chain(device_t udev, unsigned upos, struct sys_info *sysinfo)
581 #else
582 static int ht_setup_chain(device_t udev, unsigned upos)
583 #endif
584 {
585         unsigned offset_unitid = 0;
586 #if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20))
587         offset_unitid = 1;
588 #endif
589
590         /* Assumption the HT chain that is bus 0 has the HT I/O Hub on it.
591          * On most boards this just happens.  If a cpu has multiple
592          * non Coherent links the appropriate bus registers for the
593          * links needs to be programed to point at bus 0.
594          */
595
596         /* Make certain the HT bus is not enumerated */
597         ht_collapse_previous_enumeration(0, 0);
598
599 #if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20))
600         offset_unitid = 1;
601 #endif
602
603 #if RAMINIT_SYSINFO == 1
604         ht_setup_chainx(udev, upos, 0, offset_unitid, sysinfo);
605 #else
606         return ht_setup_chainx(udev, upos, 0, offset_unitid);
607 #endif
608 }
609 static int optimize_link_read_pointer(uint8_t node, uint8_t linkn, uint8_t linkt, uint8_t val)
610 {
611         uint32_t dword, dword_old;
612         uint8_t link_type;
613
614         /* This works on an Athlon64 because unimplemented links return 0 */
615         dword = pci_read_config32(PCI_DEV(0,0x18+node,0), 0x98 + (linkn * 0x20));
616         link_type = dword & 0xff;
617
618
619         if ( (link_type & 7) == linkt ) { /* Coherent Link only linkt = 3, ncoherent = 7*/
620                 dword_old = dword = pci_read_config32(PCI_DEV(0,0x18+node,3), 0xdc);
621                 dword &= ~( 0xff<<(linkn *8) );
622                 dword |= val << (linkn *8);
623
624                 if (dword != dword_old) {
625                         pci_write_config32(PCI_DEV(0,0x18+node,3), 0xdc, dword);
626                         return 1;
627                 }
628         }
629
630         return 0;
631 }
632
633 static int optimize_link_read_pointers_chain(uint8_t ht_c_num)
634 {
635         int reset_needed;
636         uint8_t i;
637
638         reset_needed = 0;
639
640         for (i = 0; i < ht_c_num; i++) {
641                 uint32_t reg;
642                 uint8_t nodeid, linkn;
643                 uint8_t busn;
644                 uint8_t val;
645                 unsigned devn = 1;
646
647         #if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20))
648                 #if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
649                 if(i==0) // to check if it is sb ht chain
650                 #endif
651                         devn = HT_CHAIN_UNITID_BASE;
652         #endif
653
654                 reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
655
656                 nodeid = ((reg & 0xf0)>>4); // nodeid
657                 linkn = ((reg & 0xf00)>>8); // link n
658                 busn = (reg & 0xff0000)>>16; //busn
659
660                 reg = pci_read_config32( PCI_DEV(busn, devn, 0), PCI_VENDOR_ID); // ? the chain dev maybe offseted
661                 if ( (reg & 0xffff) == PCI_VENDOR_ID_AMD) {
662                         val = 0x25;
663                 } else if ( (reg & 0xffff) == PCI_VENDOR_ID_NVIDIA ) {
664                         val = 0x25;//???
665                 } else {
666                         continue;
667                 }
668
669                 reset_needed |= optimize_link_read_pointer(nodeid, linkn, 0x07, val);
670
671         }
672
673         return reset_needed;
674 }
675
676 static int set_ht_link_buffer_count(uint8_t node, uint8_t linkn, uint8_t linkt, unsigned val)
677 {
678         uint32_t dword;
679         uint8_t link_type;
680         unsigned regpos;
681         device_t dev;
682
683         /* This works on an Athlon64 because unimplemented links return 0 */
684         regpos = 0x98 + (linkn * 0x20);
685         dev = PCI_DEV(0,0x18+node,0);
686         dword = pci_read_config32(dev, regpos);
687         link_type = dword & 0xff;
688
689         if ( (link_type & 0x7) == linkt ) { /* Coherent Link only linkt = 3, ncoherent = 7*/
690                 regpos = 0x90 + (linkn * 0x20);
691                 dword = pci_read_config32(dev, regpos );
692
693                 if (dword != val) {
694                         pci_write_config32(dev, regpos, val);
695                         return 1;
696                 }
697         }
698
699         return 0;
700 }
701 static int set_ht_link_buffer_counts_chain(uint8_t ht_c_num, unsigned vendorid,  unsigned val)
702 {
703         int reset_needed;
704         uint8_t i;
705
706         reset_needed = 0;
707
708         for (i = 0; i < ht_c_num; i++) {
709                 uint32_t reg;
710                 uint8_t nodeid, linkn;
711                 uint8_t busn;
712                 unsigned devn;
713
714                 reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
715                 if((reg & 3) != 3) continue; // not enabled
716
717                 nodeid = ((reg & 0xf0)>>4); // nodeid
718                 linkn = ((reg & 0xf00)>>8); // link n
719                 busn = (reg & 0xff0000)>>16; //busn
720
721                 for(devn = 0; devn < 0x20; devn++) {
722                         reg = pci_read_config32( PCI_DEV(busn, devn, 0), PCI_VENDOR_ID); //1?
723                         if ( (reg & 0xffff) == vendorid ) {
724                                 reset_needed |= set_ht_link_buffer_count(nodeid, linkn, 0x07,val);
725                                 break;
726                         }
727                 }
728         }
729
730         return reset_needed;
731 }
732
733
734 #if RAMINIT_SYSINFO == 1
735 static void ht_setup_chains(uint8_t ht_c_num, struct sys_info *sysinfo)
736 #else
737 static int ht_setup_chains(uint8_t ht_c_num)
738 #endif
739 {
740         /* Assumption the HT chain that is bus 0 has the HT I/O Hub on it.
741          * On most boards this just happens.  If a cpu has multiple
742          * non Coherent links the appropriate bus registers for the
743          * links needs to be programed to point at bus 0.
744          */
745         uint8_t upos;
746         device_t udev;
747         uint8_t i;
748
749 #if RAMINIT_SYSINFO == 0
750         int reset_needed = 0;
751 #else
752         sysinfo->link_pair_num = 0;
753 #endif
754
755         // first one is SB Chain
756         for (i = 0; i < ht_c_num; i++) {
757                 uint32_t reg;
758                 uint8_t devpos;
759                 unsigned regpos;
760                 uint32_t dword;
761                 uint8_t busn;
762                 #if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1)
763                 unsigned bus;
764                 #endif
765                 unsigned offset_unitid = 0;
766
767                 reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
768
769                 //We need setup 0x94, 0xb4, and 0xd4 according to the reg
770                 devpos = ((reg & 0xf0)>>4)+0x18; // nodeid; it will decide 0x18 or 0x19
771                 regpos = ((reg & 0xf00)>>8) * 0x20 + 0x94; // link n; it will decide 0x94 or 0xb4, 0x0xd4;
772                 busn = (reg & 0xff0000)>>16;
773
774                 dword = pci_read_config32( PCI_DEV(0, devpos, 0), regpos) ;
775                 dword &= ~(0xffff<<8);
776                 dword |= (reg & 0xffff0000)>>8;
777                 pci_write_config32( PCI_DEV(0, devpos,0), regpos , dword);
778
779
780         #if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20))
781                 #if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
782                 if(i==0) // to check if it is sb ht chain
783                 #endif
784                         offset_unitid = 1;
785         #endif
786
787                 /* Make certain the HT bus is not enumerated */
788                 ht_collapse_previous_enumeration(busn, offset_unitid);
789
790                 upos = ((reg & 0xf00)>>8) * 0x20 + 0x80;
791                 udev =  PCI_DEV(0, devpos, 0);
792
793 #if RAMINIT_SYSINFO == 1
794                 ht_setup_chainx(udev,upos,busn, offset_unitid, sysinfo); // all not
795 #else
796                 reset_needed |= ht_setup_chainx(udev,upos,busn, offset_unitid); //all not
797 #endif
798
799                 #if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1)
800                 /* You can use use this in romcc, because there is function call in romcc, recursive will kill you */
801                 bus = busn; // we need 32 bit
802 #if RAMINIT_SYSINFO == 1
803                 scan_pci_bus(bus, sysinfo);
804 #else
805                 reset_needed |= (scan_pci_bus(bus)>>16); // take out reset_needed that stored in upword
806 #endif
807                 #endif
808         }
809
810 #if RAMINIT_SYSINFO == 0
811         reset_needed |= optimize_link_read_pointers_chain(ht_c_num);
812
813         return reset_needed;
814 #endif
815
816 }
817
818 #if defined (__GNUC__)
819 static inline unsigned get_nodes(void);
820 #endif
821
822 #if RAMINIT_SYSINFO == 1
823 static void ht_setup_chains_x(struct sys_info *sysinfo)
824 #else
825 static int ht_setup_chains_x(void)
826 #endif
827 {
828         uint8_t nodeid;
829         uint32_t reg;
830         uint32_t tempreg;
831         uint8_t next_busn;
832         uint8_t ht_c_num;
833         uint8_t nodes;
834 #if K8_ALLOCATE_IO_RANGE == 1
835         unsigned next_io_base;
836 #endif
837
838         nodes = get_nodes();
839
840         /* read PCI_DEV(0,0x18,0) 0x64 bit [8:9] to find out SbLink m */
841         reg = pci_read_config32(PCI_DEV(0, 0x18, 0), 0x64);
842         /* update PCI_DEV(0, 0x18, 1) 0xe0 to 0x05000m03, and next_busn=0x3f+1 */
843         print_linkn_in("SBLink=", ((reg>>8) & 3) );
844 #if RAMINIT_SYSINFO == 1
845         sysinfo->sblk = (reg>>8) & 3;
846         sysinfo->sbbusn = 0;
847         sysinfo->nodes = nodes;
848 #endif
849         tempreg = 3 | ( 0<<4) | (((reg>>8) & 3)<<8) | (0<<16)| (0x3f<<24);
850         pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0, tempreg);
851
852         next_busn=0x3f+1; /* 0 will be used ht chain with SB we need to keep SB in bus0 in auto stage*/
853
854 #if K8_ALLOCATE_IO_RANGE == 1
855         /* io range allocation */
856         tempreg = 0 | (((reg>>8) & 0x3) << 4 )|  (0x3<<12); //limit
857         pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC4, tempreg);
858         tempreg = 3 | ( 3<<4) | (0<<12);        //base
859         pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC0, tempreg);
860         next_io_base = 0x3+0x1;
861 #endif
862
863         /* clean others */
864         for(ht_c_num=1;ht_c_num<4; ht_c_num++) {
865                 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4, 0);
866
867 #if K8_ALLOCATE_IO_RANGE == 1
868                 /* io range allocation */
869                 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xc4 + ht_c_num * 8, 0);
870                 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xc0 + ht_c_num * 8, 0);
871 #endif
872         }
873
874         for(nodeid=0; nodeid<nodes; nodeid++) {
875                 device_t dev;
876                 uint8_t linkn;
877                 dev = PCI_DEV(0, 0x18+nodeid,0);
878                 for(linkn = 0; linkn<3; linkn++) {
879                         unsigned regpos;
880                         regpos = 0x98 + 0x20 * linkn;
881                         reg = pci_read_config32(dev, regpos);
882                         if ((reg & 0x17) != 7) continue; /* it is not non conherent or not connected*/
883                         print_linkn_in("NC node|link=", ((nodeid & 0xf)<<4)|(linkn & 0xf));
884                         tempreg = 3 | (nodeid <<4) | (linkn<<8);
885                         /*compare (temp & 0xffff), with (PCI(0, 0x18, 1) 0xe0 to 0xec & 0xfffff) */
886                         for(ht_c_num=0;ht_c_num<4; ht_c_num++) {
887                                 reg = pci_read_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4);
888                                 if(((reg & 0xffff) == (tempreg & 0xffff)) || ((reg & 0xffff) == 0x0000)) {  /*we got it*/
889                                         break;
890                                 }
891                         }
892                         if(ht_c_num == 4) break; /*used up only 4 non conherent allowed*/
893                         /*update to 0xe0...*/
894                         if((reg & 0xf) == 3) continue; /*SbLink so don't touch it */
895                         print_linkn_in("\tbusn=", next_busn);
896                         tempreg |= (next_busn<<16)|((next_busn+0x3f)<<24);
897                         pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4, tempreg);
898                         next_busn+=0x3f+1;
899
900 #if K8_ALLOCATE_IO_RANGE == 1
901                         /* io range allocation */
902                         tempreg = nodeid | (linkn<<4) |  ((next_io_base+0x3)<<12); //limit
903                         pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC4 + ht_c_num * 8, tempreg);
904                         tempreg = 3 /*| ( 3<<4)*/ | (next_io_base<<12); //base :ISA and VGA ?
905                         pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC0 + ht_c_num * 8, tempreg);
906                         next_io_base += 0x3+0x1;
907 #endif
908
909                 }
910         }
911         /*update 0xe0, 0xe4, 0xe8, 0xec from PCI_DEV(0, 0x18,1) to PCI_DEV(0, 0x19,1) to PCI_DEV(0, 0x1f,1);*/
912
913         for(nodeid = 1; nodeid<nodes; nodeid++) {
914                 int i;
915                 device_t dev;
916                 dev = PCI_DEV(0, 0x18+nodeid,1);
917                 for(i = 0; i< 4; i++) {
918                         unsigned regpos;
919                         regpos = 0xe0 + i * 4;
920                         reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos);
921                         pci_write_config32(dev, regpos, reg);
922                 }
923
924 #if K8_ALLOCATE_IO_RANGE == 1
925                 /* io range allocation */
926                 for(i = 0; i< 4; i++) {
927                         unsigned regpos;
928                         regpos = 0xc4 + i * 8;
929                         reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos);
930                         pci_write_config32(dev, regpos, reg);
931                 }
932                 for(i = 0; i< 4; i++) {
933                         unsigned regpos;
934                         regpos = 0xc0 + i * 8;
935                         reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos);
936                         pci_write_config32(dev, regpos, reg);
937                 }
938 #endif
939         }
940
941         /* recount ht_c_num*/
942         uint8_t i=0;
943         for(ht_c_num=0;ht_c_num<4; ht_c_num++) {
944                 reg = pci_read_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4);
945                 if(((reg & 0xf) != 0x0)) {
946                         i++;
947                 }
948         }
949
950 #if RAMINIT_SYSINFO == 1
951         sysinfo->ht_c_num = i;
952         ht_setup_chains(i, sysinfo);
953         sysinfo->sbdn = get_sbdn(sysinfo->sbbusn);
954 #else
955         return ht_setup_chains(i);
956 #endif
957
958 }
959
960 #if RAMINIT_SYSINFO == 1
961 static int optimize_link_incoherent_ht(struct sys_info *sysinfo)
962 {
963         // We need to use recorded link pair info to optimize the link
964         int i;
965         int reset_needed = 0;
966
967         unsigned link_pair_num = sysinfo->link_pair_num;
968
969         for(i=0; i< link_pair_num; i++) {
970                 struct link_pair_st *link_pair= &sysinfo->link_pair[i];
971                 reset_needed |= ht_optimize_link(link_pair->udev, link_pair->upos, link_pair->uoffs, link_pair->dev, link_pair->pos, link_pair->offs);
972         }
973
974         reset_needed |= optimize_link_read_pointers_chain(sysinfo->ht_c_num);
975
976         return reset_needed;
977
978 }
979 #endif
980
981
982