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