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