- See Issue Tracker id-11.
[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
5 */
6 #include <device/pci_def.h>
7 #include <device/pci_ids.h>
8 #include <device/hypertransport_def.h>
9
10
11 /* We can reduce the size of code generated by romcc by
12  * changing all of the fixed size types that live in registers
13  * into simple unsigned variables. (ie s/uint8_t/unsigned/g)
14  */
15 #ifndef K8_HT_FREQ_1G_SUPPORT
16         #define K8_HT_FREQ_1G_SUPPORT 0
17 #endif
18
19 #ifndef K8_SCAN_PCI_BUS
20         #define K8_SCAN_PCI_BUS 0
21 #endif
22
23 static inline void print_linkn_in (const char *strval, uint8_t byteval)
24 {
25 #if 1
26 #if CONFIG_USE_INIT
27         printk_debug("%s%02x\r\n", strval, byteval); 
28 #else
29         print_debug(strval); print_debug_hex8(byteval); print_debug("\r\n");
30 #endif
31 #endif
32 }
33
34 static uint8_t ht_lookup_capability(device_t dev, uint16_t val)
35 {
36         uint8_t pos;
37         uint8_t hdr_type;
38
39         hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
40         pos = 0;
41         hdr_type &= 0x7f;
42
43         if ((hdr_type == PCI_HEADER_TYPE_NORMAL) ||
44             (hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
45                 pos = PCI_CAPABILITY_LIST;
46         }
47         if (pos > PCI_CAP_LIST_NEXT) {
48                 pos = pci_read_config8(dev, pos);
49         }
50         while(pos != 0) { /* loop through the linked list */
51                 uint8_t cap;
52                 cap = pci_read_config8(dev, pos + PCI_CAP_LIST_ID);
53                 if (cap == PCI_CAP_ID_HT) {
54                         uint16_t flags;
55
56                         flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
57                         if ((flags >> 13) == val) {
58                                 /* Entry is a slave or host , success... */
59                                 break;
60                         }
61                 }
62                 pos = pci_read_config8(dev, pos + PCI_CAP_LIST_NEXT);
63         }
64         return pos;
65 }
66
67 static uint8_t ht_lookup_slave_capability(device_t dev)
68 {          
69         return ht_lookup_capability(dev, 0); // Slave/Primary Interface Block Format
70 }
71
72 static uint8_t ht_lookup_host_capability(device_t dev)
73 {
74         return ht_lookup_capability(dev, 1); // Host/Secondary Interface Block Format
75 }
76
77 static void ht_collapse_previous_enumeration(uint8_t bus)
78 {
79         device_t dev;
80         uint32_t id;
81
82         /* Check if is already collapsed */
83         dev = PCI_DEV(bus, 0, 0);
84         id = pci_read_config32(dev, PCI_VENDOR_ID);
85         if ( ! ( (id == 0xffffffff) || (id == 0x00000000) ||
86             (id == 0x0000ffff) || (id == 0xffff0000) ) ) {
87                      return;
88         }
89
90         /* Spin through the devices and collapse any previous
91          * hypertransport enumeration.
92          */
93         for(dev = PCI_DEV(bus, 1, 0); dev <= PCI_DEV(bus, 0x1f, 0x7); dev += PCI_DEV(0, 1, 0)) {
94                 uint32_t id;
95                 uint8_t pos;
96                 uint16_t flags;
97                 
98                 id = pci_read_config32(dev, PCI_VENDOR_ID);
99                 if ((id == 0xffffffff) || (id == 0x00000000) ||
100                     (id == 0x0000ffff) || (id == 0xffff0000)) {
101                         continue;
102                 }
103 #if 0
104 #if CK804_DEVN_BASE==0 
105                 //CK804 workaround: 
106                 // CK804 UnitID changes not use
107                 if(id == 0x005e10de) {
108                         break;
109                 }
110 #endif
111 #endif
112                 
113                 pos = ht_lookup_slave_capability(dev);
114                 if (!pos) {
115                         continue;
116                 }
117
118                 /* Clear the unitid */
119                 flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
120                 flags &= ~0x1f;
121                 pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
122         }
123 }
124
125 static uint16_t ht_read_freq_cap(device_t dev, uint8_t pos)
126 {
127         /* Handle bugs in valid hypertransport frequency reporting */
128         uint16_t freq_cap;
129         uint32_t id;
130
131         freq_cap = pci_read_config16(dev, pos);
132         freq_cap &= ~(1 << HT_FREQ_VENDOR); /* Ignore Vendor HT frequencies */
133
134         id = pci_read_config32(dev, 0);
135
136         /* AMD 8131 Errata 48 */
137         if (id == (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_AMD_8131_PCIX << 16))) {
138                 freq_cap &= ~(1 << HT_FREQ_800Mhz);
139         } 
140
141         /* AMD 8151 Errata 23 */
142         if (id == (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_AMD_8151_SYSCTRL << 16))) {
143                 freq_cap &= ~(1 << HT_FREQ_800Mhz);
144         } 
145         
146         /* AMD K8 Unsupported 1Ghz? */
147         if (id == (PCI_VENDOR_ID_AMD | (0x1100 << 16))) {
148 #if K8_HT_FREQ_1G_SUPPORT == 1
149                 /* Supported starting with E0 */
150                 device_t dev_2 = PCI_DEV(0,0x18,2);
151                 if(pci_read_config32(dev_2,0x9c) < 0x20f00) 
152 #endif
153                         freq_cap &= ~(1 << HT_FREQ_1000Mhz);
154         }
155
156         return freq_cap;
157 }
158 #define LINK_OFFS(CTRL, WIDTH,FREQ,FREQ_CAP) \
159       (((CTRL & 0xff) << 24) | ((WIDTH & 0xff) << 16) | ((FREQ & 0xff) << 8) | (FREQ_CAP & 0xFF))
160
161 #define LINK_CTRL(OFFS)     ((OFFS >> 24) & 0xFF)
162 #define LINK_WIDTH(OFFS)    ((OFFS >> 16) & 0xFF)
163 #define LINK_FREQ(OFFS)     ((OFFS >> 8) & 0xFF)
164 #define LINK_FREQ_CAP(OFFS) ((OFFS) & 0xFF)
165
166 #define PCI_HT_HOST_OFFS LINK_OFFS(             \
167                 PCI_HT_CAP_HOST_CTRL,           \
168                 PCI_HT_CAP_HOST_WIDTH,          \
169                 PCI_HT_CAP_HOST_FREQ,           \
170                 PCI_HT_CAP_HOST_FREQ_CAP)
171
172 #define PCI_HT_SLAVE0_OFFS LINK_OFFS(           \
173                 PCI_HT_CAP_SLAVE_CTRL0,         \
174                 PCI_HT_CAP_SLAVE_WIDTH0,        \
175                 PCI_HT_CAP_SLAVE_FREQ0,         \
176                 PCI_HT_CAP_SLAVE_FREQ_CAP0)
177
178 #define PCI_HT_SLAVE1_OFFS LINK_OFFS(           \
179                 PCI_HT_CAP_SLAVE_CTRL1,         \
180                 PCI_HT_CAP_SLAVE_WIDTH1,        \
181                 PCI_HT_CAP_SLAVE_FREQ1,         \
182                 PCI_HT_CAP_SLAVE_FREQ_CAP1)
183
184 static int ht_optimize_link(
185         device_t dev1, uint8_t pos1, unsigned offs1,
186         device_t dev2, uint8_t pos2, unsigned offs2)
187 {
188         static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
189         static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
190         uint16_t freq_cap1, freq_cap2;
191         uint8_t width_cap1, width_cap2, width, old_width, ln_width1, ln_width2;
192         uint8_t freq, old_freq;
193         int needs_reset;
194         /* Set link width and frequency */
195
196         /* Initially assume everything is already optimized and I don't need a reset */
197         needs_reset = 0;
198
199         /* Get the frequency capabilities */
200         freq_cap1 = ht_read_freq_cap(dev1, pos1 + LINK_FREQ_CAP(offs1));
201         freq_cap2 = ht_read_freq_cap(dev2, pos2 + LINK_FREQ_CAP(offs2));
202
203         /* Calculate the highest possible frequency */
204         freq = log2(freq_cap1 & freq_cap2);
205
206         /* See if I am changing the link freqency */
207         old_freq = pci_read_config8(dev1, pos1 + LINK_FREQ(offs1));
208         old_freq &= 0x0f;
209         needs_reset |= old_freq != freq;
210         old_freq = pci_read_config8(dev2, pos2 + LINK_FREQ(offs2));
211         old_freq &= 0x0f;
212         needs_reset |= old_freq != freq;
213
214         /* Set the Calulcated link frequency */
215         pci_write_config8(dev1, pos1 + LINK_FREQ(offs1), freq);
216         pci_write_config8(dev2, pos2 + LINK_FREQ(offs2), freq);
217
218         /* Get the width capabilities */
219         width_cap1 = pci_read_config8(dev1, pos1 + LINK_WIDTH(offs1));
220         width_cap2 = pci_read_config8(dev2, pos2 + LINK_WIDTH(offs2));
221
222         /* Calculate dev1's input width */
223         ln_width1 = link_width_to_pow2[width_cap1 & 7];
224         ln_width2 = link_width_to_pow2[(width_cap2 >> 4) & 7];
225         if (ln_width1 > ln_width2) {
226                 ln_width1 = ln_width2;
227         }
228         width = pow2_to_link_width[ln_width1];
229         /* Calculate dev1's output width */
230         ln_width1 = link_width_to_pow2[(width_cap1 >> 4) & 7];
231         ln_width2 = link_width_to_pow2[width_cap2 & 7];
232         if (ln_width1 > ln_width2) {
233                 ln_width1 = ln_width2;
234         }
235         width |= pow2_to_link_width[ln_width1] << 4;
236
237         /* See if I am changing dev1's width */
238         old_width = pci_read_config8(dev1, pos1 + LINK_WIDTH(offs1) + 1);
239         needs_reset |= old_width != width;
240
241         /* Set dev1's widths */
242         pci_write_config8(dev1, pos1 + LINK_WIDTH(offs1) + 1, width);
243
244         /* Calculate dev2's width */
245         width = ((width & 0x70) >> 4) | ((width & 0x7) << 4);
246
247         /* See if I am changing dev2's width */
248         old_width = pci_read_config8(dev2, pos2 + LINK_WIDTH(offs2) + 1);
249         needs_reset |= old_width != width;
250
251         /* Set dev2's widths */
252         pci_write_config8(dev2, pos2 + LINK_WIDTH(offs2) + 1, width);
253
254         return needs_reset;
255 }
256 #if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1)
257 static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus);
258 static int scan_pci_bus( unsigned bus) 
259 {
260         /*      
261                 here we already can access PCI_DEV(bus, 0, 0) to PCI_DEV(bus, 0x1f, 0x7)
262                 So We can scan these devices to find out if they are bridge 
263                 If it is pci bridge, We need to set busn in bridge, and go on
264                 For ht bridge, We need to set the busn in bridge and ht_setup_chainx, and the scan_pci_bus
265         */    
266         unsigned int devfn;
267         unsigned new_bus;
268         unsigned max_bus;
269
270         new_bus = (bus & 0xff); // mask out the reset_needed
271
272         if(new_bus<0x40) {
273                 max_bus = 0x3f;
274         } else if (new_bus<0x80) {
275                 max_bus = 0x7f;
276         } else if (new_bus<0xc0) {
277                 max_bus = 0xbf;
278         } else {
279                 max_bus = 0xff;
280         }
281
282         new_bus = bus;
283
284 #if 0
285 #if CONFIG_USE_INIT == 1
286         printk_debug("bus_num=%02x\r\n", bus);
287 #endif
288 #endif
289
290         for (devfn = 0; devfn <= 0xff; devfn++) { 
291                 uint8_t hdr_type;
292                 uint16_t class;
293                 uint32_t buses;
294                 device_t dev;
295                 uint16_t cr;
296                 dev = PCI_DEV((bus & 0xff), ((devfn>>3) & 0x1f), (devfn & 0x7));
297                 hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE);
298                 class = pci_read_config16(dev, PCI_CLASS_DEVICE);
299
300 #if 0
301 #if CONFIG_USE_INIT == 1
302                 if(hdr_type !=0xff ) {
303                         printk_debug("dev=%02x fn=%02x hdr_type=%02x class=%04x\r\n", 
304                                 (devfn>>3)& 0x1f, (devfn & 0x7), hdr_type, class);
305                 }
306 #endif
307 #endif
308                 switch(hdr_type & 0x7f) {  /* header type */
309                         case PCI_HEADER_TYPE_BRIDGE:
310                                 if (class  != PCI_CLASS_BRIDGE_PCI) goto bad;
311                                 /* set the bus range dev */
312
313                                 /* Clear all status bits and turn off memory, I/O and master enables. */
314                                 cr = pci_read_config16(dev, PCI_COMMAND);
315                                 pci_write_config16(dev, PCI_COMMAND, 0x0000);
316                                 pci_write_config16(dev, PCI_STATUS, 0xffff);
317
318                                 buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
319
320                                 buses &= 0xff000000;
321                                 new_bus++;
322                                 buses |= (((unsigned int) (bus & 0xff) << 0) |
323                                         ((unsigned int) (new_bus & 0xff) << 8) |
324                                         ((unsigned int) max_bus << 16));
325                                 pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
326                                 
327                                 {
328                                 /* here we need to figure out if dev is a ht bridge
329                                         if it is ht bridge, we need to call ht_setup_chainx at first
330                                    Not verified --- yhlu
331                                 */
332                                         uint8_t upos;
333                                         upos = ht_lookup_host_capability(dev); // one func one ht sub
334                                         if (upos) { // sub ht chain
335                                                 uint8_t busn;
336                                                 busn = (new_bus & 0xff);
337                                                 /* Make certain the HT bus is not enumerated */
338                                                 ht_collapse_previous_enumeration(busn);
339                                                 /* scan the ht chain */
340                                                 new_bus |= (ht_setup_chainx(dev,upos,busn)<<16); // store reset_needed to upword
341                                         }
342                                 }
343                                 
344                                 new_bus = scan_pci_bus(new_bus);
345                                 /* set real max bus num in that */
346
347                                 buses = (buses & 0xff00ffff) |
348                                         ((unsigned int) (new_bus & 0xff) << 16);
349                                         pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
350
351                                 pci_write_config16(dev, PCI_COMMAND, cr);
352
353                                 break;  
354                         default:
355                         bad:
356                                 ;
357                 }
358
359                 /* if this is not a multi function device, 
360                  * or the device is not present don't waste
361                  * time probing another function. 
362                  * Skip to next device. 
363                  */
364                 if ( ((devfn & 0x07) == 0x00) && ((hdr_type & 0x80) != 0x80))
365                 {
366                         devfn += 0x07;
367                 }
368         }
369         
370         return new_bus; 
371 }
372 #endif
373 static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus)
374 {
375         uint8_t next_unitid, last_unitid;
376         unsigned uoffs;
377         int reset_needed=0;
378
379         uoffs = PCI_HT_HOST_OFFS;
380         next_unitid = 1;
381
382         do {
383                 uint32_t id;
384                 uint8_t pos;
385                 uint16_t flags, ctrl;
386                 uint8_t count;
387                 unsigned offs;
388         
389                 /* Wait until the link initialization is complete */
390                 do {
391                         ctrl = pci_read_config16(udev, upos + LINK_CTRL(uoffs));
392                         /* Is this the end of the hypertransport chain? */
393                         if (ctrl & (1 << 6)) {
394                                 break;
395                         }
396                         /* Has the link failed */
397                         if (ctrl & (1 << 4)) {
398                                 break;
399                         }
400                 } while((ctrl & (1 << 5)) == 0);
401         
402                 device_t dev = PCI_DEV(bus, 0, 0);
403                 last_unitid = next_unitid;
404
405                 id = pci_read_config32(dev, PCI_VENDOR_ID);
406
407                 /* If the chain is enumerated quit */
408                 if (    (id == 0xffffffff) || (id == 0x00000000) ||
409                         (id == 0x0000ffff) || (id == 0xffff0000))
410                 {
411                         break;
412                 }
413
414                 pos = ht_lookup_slave_capability(dev);
415                 if (!pos) {
416                         print_err("HT link capability not found\r\n");
417                         break;
418                 }
419
420 #if CK804_DEVN_BASE==0 
421                 //CK804 workaround: 
422                 // CK804 UnitID changes not use
423                 id = pci_read_config32(dev, PCI_VENDOR_ID);
424                 if(id != 0x005e10de) {
425 #endif
426
427                 /* Update the Unitid of the current device */
428                 flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
429                 flags &= ~0x1f; /* mask out the bse Unit ID */
430                 flags |= next_unitid & 0x1f;
431                 pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);
432
433                 /* Note the change in device number */
434                 dev = PCI_DEV(bus, next_unitid, 0);
435 #if CK804_DEVN_BASE==0  
436                 } 
437                 else {
438                         dev = PCI_DEV(bus, 0, 0);
439                 }
440 #endif
441
442                 /* Compute the number of unitids consumed */
443                 count = (flags >> 5) & 0x1f;
444                 next_unitid += count;
445
446                 /* Find which side of the ht link we are on,
447                  * by reading which direction our last write to PCI_CAP_FLAGS
448                  * came from.
449                  */
450                 flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
451                 offs = ((flags>>10) & 1) ? PCI_HT_SLAVE1_OFFS : PCI_HT_SLAVE0_OFFS;
452                 
453                 /* Setup the Hypertransport link */
454                 reset_needed |= ht_optimize_link(udev, upos, uoffs, dev, pos, offs);
455
456 #if CK804_DEVN_BASE==0
457                 if(id == 0x005e10de) {
458                         break;
459                 }
460 #endif
461
462                 /* Remeber the location of the last device */
463                 udev = dev;
464                 upos = pos;
465                 uoffs = ( offs != PCI_HT_SLAVE0_OFFS ) ? PCI_HT_SLAVE0_OFFS : PCI_HT_SLAVE1_OFFS;
466
467         } while((last_unitid != next_unitid) && (next_unitid <= 0x1f));
468
469         return reset_needed;
470 }
471
472 static int ht_setup_chain(device_t udev, unsigned upos)
473 {
474         /* Assumption the HT chain that is bus 0 has the HT I/O Hub on it.
475          * On most boards this just happens.  If a cpu has multiple
476          * non Coherent links the appropriate bus registers for the
477          * links needs to be programed to point at bus 0.
478          */
479
480         /* Make certain the HT bus is not enumerated */
481         ht_collapse_previous_enumeration(0);
482
483         return ht_setup_chainx(udev, upos, 0);
484 }
485 static int optimize_link_read_pointer(uint8_t node, uint8_t linkn, uint8_t linkt, uint8_t val)
486 {
487         uint32_t dword, dword_old;
488         uint8_t link_type;
489         
490         /* This works on an Athlon64 because unimplemented links return 0 */
491         dword = pci_read_config32(PCI_DEV(0,0x18+node,0), 0x98 + (linkn * 0x20));
492         link_type = dword & 0xff;
493         
494         dword_old = dword = pci_read_config32(PCI_DEV(0,0x18+node,3), 0xdc);
495         
496         if ( (link_type & 7) == linkt ) { /* Coherent Link only linkt = 3, ncoherent = 7*/
497                 dword &= ~( 0xff<<(linkn *8) );
498                 dword |= val << (linkn *8);
499         }
500         
501         if (dword != dword_old) {
502                 pci_write_config32(PCI_DEV(0,0x18+node,3), 0xdc, dword);
503                 return 1;
504         }
505         
506         return 0;
507 }
508
509 static int optimize_link_in_coherent(uint8_t ht_c_num)
510 {
511         int reset_needed; 
512         uint8_t i;
513
514         reset_needed = 0;
515
516         for (i = 0; i < ht_c_num; i++) {
517                 uint32_t reg;
518                 uint8_t nodeid, linkn;
519                 uint8_t busn;
520                 uint8_t val;
521
522                 reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
523                 
524                 nodeid = ((reg & 0xf0)>>4); // nodeid
525                 linkn = ((reg & 0xf00)>>8); // link n
526                 busn = (reg & 0xff0000)>>16; //busn
527         
528                 reg = pci_read_config32( PCI_DEV(busn, 1, 0), PCI_VENDOR_ID);
529                 if ( (reg & 0xffff) == PCI_VENDOR_ID_AMD) {
530                         val = 0x25;
531                 } else if ( (reg & 0xffff) == PCI_VENDOR_ID_NVIDIA ) {
532                         val = 0x25;//???
533                 } else {
534                         continue;
535                 }
536
537                 reset_needed |= optimize_link_read_pointer(nodeid, linkn, 0x07, val);
538
539         }
540
541         return reset_needed;
542 }
543
544 static int ht_setup_chains(uint8_t ht_c_num)
545 {
546         /* Assumption the HT chain that is bus 0 has the HT I/O Hub on it. 
547          * On most boards this just happens.  If a cpu has multiple
548          * non Coherent links the appropriate bus registers for the
549          * links needs to be programed to point at bus 0.
550          */
551         int reset_needed; 
552         uint8_t upos;
553         device_t udev;
554         uint8_t i;
555
556         reset_needed = 0;
557
558         for (i = 0; i < ht_c_num; i++) {
559                 uint32_t reg;
560                 uint8_t devpos;
561                 unsigned regpos;
562                 uint32_t dword;
563                 uint8_t busn;
564                 #if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1)
565                 unsigned bus;
566                 #endif
567                 
568                 reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4);
569
570                 //We need setup 0x94, 0xb4, and 0xd4 according to the reg
571                 devpos = ((reg & 0xf0)>>4)+0x18; // nodeid; it will decide 0x18 or 0x19
572                 regpos = ((reg & 0xf00)>>8) * 0x20 + 0x94; // link n; it will decide 0x94 or 0xb4, 0x0xd4;
573                 busn = (reg & 0xff0000)>>16;
574                 
575                 dword = pci_read_config32( PCI_DEV(0, devpos, 0), regpos) ;
576                 dword &= ~(0xffff<<8);
577                 dword |= (reg & 0xffff0000)>>8;
578                 pci_write_config32( PCI_DEV(0, devpos,0), regpos , dword);
579                 
580                 /* Make certain the HT bus is not enumerated */
581                 ht_collapse_previous_enumeration(busn);
582
583                 upos = ((reg & 0xf00)>>8) * 0x20 + 0x80;
584                 udev =  PCI_DEV(0, devpos, 0);
585                 
586                 reset_needed |= ht_setup_chainx(udev,upos,busn);
587
588                 #if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1)
589                 /* You can use use this in romcc, because there is function call in romcc, recursive will kill you */
590                 bus = busn; // we need 32 bit 
591                 reset_needed |= (scan_pci_bus(bus)>>16); // take out reset_needed that stored in upword
592                 #endif
593         }
594
595         reset_needed |= optimize_link_in_coherent(ht_c_num);            
596         
597         return reset_needed;
598 }
599
600 #ifndef K8_ALLOCATE_IO_RANGE 
601         #define K8_ALLOCATE_IO_RANGE 0
602 #endif
603
604 static int ht_setup_chains_x(void)
605 {               
606         uint8_t nodeid;
607         uint32_t reg; 
608         uint32_t tempreg;
609         uint8_t next_busn;
610         uint8_t ht_c_num;
611         uint8_t nodes;
612 #if K8_ALLOCATE_IO_RANGE == 1   
613         unsigned next_io_base;
614 #endif
615       
616         /* read PCI_DEV(0,0x18,0) 0x64 bit [8:9] to find out SbLink m */
617         reg = pci_read_config32(PCI_DEV(0, 0x18, 0), 0x64);
618         /* update PCI_DEV(0, 0x18, 1) 0xe0 to 0x05000m03, and next_busn=0x3f+1 */
619         print_linkn_in("SBLink=", ((reg>>8) & 3) );
620         tempreg = 3 | ( 0<<4) | (((reg>>8) & 3)<<8) | (0<<16)| (0x3f<<24);
621         pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0, tempreg);
622
623         next_busn=0x3f+1; /* 0 will be used ht chain with SB we need to keep SB in bus0 in auto stage*/
624
625 #if K8_ALLOCATE_IO_RANGE == 1
626         /* io range allocation */
627         tempreg = 0 | (((reg>>8) & 0x3) << 4 )|  (0x3<<12); //limit
628         pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC4, tempreg);
629         tempreg = 3 | ( 3<<4) | (0<<12);        //base
630         pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC0, tempreg);
631         next_io_base = 0x3+0x1;
632 #endif
633
634         /* clean others */
635         for(ht_c_num=1;ht_c_num<4; ht_c_num++) {
636                 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4, 0);
637                 /* io range allocation */
638                 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xc4 + ht_c_num * 8, 0);
639                 pci_write_config32(PCI_DEV(0, 0x18, 1), 0xc0 + ht_c_num * 8, 0);
640         }
641  
642         nodes = ((pci_read_config32(PCI_DEV(0, 0x18, 0), 0x60)>>4) & 7) + 1;
643
644         for(nodeid=0; nodeid<nodes; nodeid++) {
645                 device_t dev; 
646                 uint8_t linkn;
647                 dev = PCI_DEV(0, 0x18+nodeid,0);
648                 for(linkn = 0; linkn<3; linkn++) {
649                         unsigned regpos;
650                         regpos = 0x98 + 0x20 * linkn;
651                         reg = pci_read_config32(dev, regpos);
652                         if ((reg & 0x17) != 7) continue; /* it is not non conherent or not connected*/
653                         print_linkn_in("NC node|link=", ((nodeid & 0xf)<<4)|(linkn & 0xf));
654                         tempreg = 3 | (nodeid <<4) | (linkn<<8);
655                         /*compare (temp & 0xffff), with (PCI(0, 0x18, 1) 0xe0 to 0xec & 0xfffff) */
656                         for(ht_c_num=0;ht_c_num<4; ht_c_num++) {
657                                 reg = pci_read_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4);
658                                 if(((reg & 0xffff) == (tempreg & 0xffff)) || ((reg & 0xffff) == 0x0000)) {  /*we got it*/
659                                         break;
660                                 }
661                         }
662                         if(ht_c_num == 4) break; /*used up only 4 non conherent allowed*/
663                         /*update to 0xe0...*/
664                         if((reg & 0xf) == 3) continue; /*SbLink so don't touch it */
665                         print_linkn_in("\tbusn=", next_busn);
666                         tempreg |= (next_busn<<16)|((next_busn+0x3f)<<24);
667                         pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4, tempreg);
668                         next_busn+=0x3f+1;
669
670 #if K8_ALLOCATE_IO_RANGE == 1                   
671                         /* io range allocation */
672                         tempreg = nodeid | (linkn<<4) |  ((next_io_base+0x3)<<12); //limit
673                         pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC4 + ht_c_num * 8, tempreg);
674                         tempreg = 3 | ( 3<<4) | (next_io_base<<12);        //base
675                         pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC0 + ht_c_num * 8, tempreg);
676                         next_io_base += 0x3+0x1;
677 #endif
678
679                 }
680         }
681         /*update 0xe0, 0xe4, 0xe8, 0xec from PCI_DEV(0, 0x18,1) to PCI_DEV(0, 0x19,1) to PCI_DEV(0, 0x1f,1);*/
682
683         for(nodeid = 1; nodeid<nodes; nodeid++) {
684                 int i;
685                 device_t dev;
686                 dev = PCI_DEV(0, 0x18+nodeid,1);
687                 for(i = 0; i< 4; i++) {
688                         unsigned regpos;
689                         regpos = 0xe0 + i * 4;
690                         reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos);
691                         pci_write_config32(dev, regpos, reg);
692                 }
693
694 #if K8_ALLOCATE_IO_RANGE == 1
695                 /* io range allocation */
696                 for(i = 0; i< 4; i++) {
697                         unsigned regpos;
698                         regpos = 0xc4 + i * 8;
699                         reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos);
700                         pci_write_config32(dev, regpos, reg);
701                 }
702                 for(i = 0; i< 4; i++) {
703                         unsigned regpos;
704                         regpos = 0xc0 + i * 8;
705                         reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos);
706                         pci_write_config32(dev, regpos, reg);
707                 }
708 #endif
709         }
710         
711         /* recount ht_c_num*/
712         uint8_t i=0;
713         for(ht_c_num=0;ht_c_num<4; ht_c_num++) {
714                 reg = pci_read_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4);
715                 if(((reg & 0xf) != 0x0)) {
716                         i++;
717                 }
718         }
719
720         return ht_setup_chains(i);
721
722 }