The ARRAY_SIZE macro is convenient, yet mostly unused. Switch lots of
[coreboot.git] / src / northbridge / amd / amdk8 / coherent_ht.c
1 /* coherent hypertransport initialization for AMD64 
2  * 
3  * written by Stefan Reinauer <stepan@openbios.org>
4  * (c) 2003-2004 by SuSE Linux AG
5  *
6  * (c) 2004 Tyan Computer
7  *  2004.12 yhlu added support to create routing table dynamically.
8  *          it also support 8 ways too. (8 ways ladder or 8 ways crossbar)
9  *
10  * This code is licensed under GPL.
11  */
12
13 /*
14  * This algorithm assumes a grid configuration as follows:
15  *
16  * nodes :  1    2    4    6    8
17  * org.  :  1x1  2x1  2x2  2x3  2x4
18  Ladder:
19                         CPU7-------------CPU6 
20                         |                |    
21                         |                |
22                         |                | 
23                         |                |     
24                         |                |        
25                         |                |    
26                         CPU5-------------CPU4                    
27                         |                |    
28                         |                |   
29                         |                |  
30                         |                |    
31                         |                |         
32                         |                |       
33                         CPU3-------------CPU2              
34                         |                |    
35                         |                | 
36                         |                |
37                         |                |
38                         |                | 
39                         |                |    
40                         CPU1-------------CPU0    
41  CROSS_BAR_47_56:
42                         CPU7-------------CPU6 
43                         |  \____    ___/ |    
44                         |       \  /     |
45                         |        \/      | 
46                         |        /\      |     
47                         |       /  \     |        
48                         |  ____/    \___ |    
49                         CPU5             CPU4                    
50                         |                |    
51                         |                |   
52                         |                |  
53                         |                |    
54                         |                |         
55                         |                |       
56                         CPU3-------------CPU2              
57                         |                |    
58                         |                | 
59                         |                |
60                         |                |
61                         |                | 
62                         |                |    
63                         CPU1-------------CPU0           
64  */
65
66 #include <device/pci_def.h>
67 #include <device/pci_ids.h>
68 #include <device/hypertransport_def.h>
69 #include <stdlib.h>
70 #include "arch/romcc_io.h"
71
72 #include "amdk8.h"
73
74 #define enable_bsp_routing()    enable_routing(0)
75
76 #define NODE_HT(x) PCI_DEV(0,24+x,0)
77 #define NODE_MP(x) PCI_DEV(0,24+x,1)
78 #define NODE_MC(x) PCI_DEV(0,24+x,3)
79
80 #define DEFAULT 0x00010101      /* default row entry */
81
82
83 #ifndef CROSS_BAR_47_56
84         #define CROSS_BAR_47_56 0
85 #endif
86
87 #ifndef TRY_HIGH_FIRST
88         #define TRY_HIGH_FIRST 0
89 #endif
90
91 #ifndef K8_HT_FREQ_1G_SUPPORT
92         #define K8_HT_FREQ_1G_SUPPORT 0
93 #endif
94
95 #ifndef K8_HT_CHECK_PENDING_LINK
96         #if CONFIG_MAX_PHYSICAL_CPUS >= 4
97                 #define K8_HT_CHECK_PENDING_LINK 1
98         #else
99                 #define K8_HT_CHECK_PENDING_LINK 0
100         #endif
101 #endif
102
103 #ifndef CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED
104         #define CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED 0
105 #endif
106
107 #ifndef ENABLE_APIC_EXT_ID
108         #define ENABLE_APIC_EXT_ID 0
109 #endif
110
111
112 static inline void print_linkn (const char *strval, uint8_t byteval) 
113 {
114 #if 1
115 #if CONFIG_USE_PRINTK_IN_CAR
116         printk_debug("%s%02x\r\n", strval, byteval); 
117 #else
118         print_debug(strval); print_debug_hex8(byteval); print_debug("\r\n");
119 #endif
120 #endif
121 }
122
123 static void disable_probes(void)
124 {
125         /* disable read/write/fill probes for uniprocessor setup
126          * they don't make sense if only one cpu is available
127          */
128
129         /* Hypetransport Transaction Control Register 
130          * F0:0x68
131          * [ 0: 0] Disable read byte probe
132          *         0 = Probes issues
133          *         1 = Probes not issued
134          * [ 1: 1] Disable Read Doubleword probe
135          *         0 = Probes issued
136          *         1 = Probes not issued
137          * [ 2: 2] Disable write byte probes
138          *         0 = Probes issued
139          *         1 = Probes not issued
140          * [ 3: 3] Disable Write Doubleword Probes
141          *         0 = Probes issued
142          *         1 = Probes not issued.
143          * [10:10] Disable Fill Probe
144          *         0 = Probes issued for cache fills
145          *         1 = Probes not issued for cache fills.
146          */
147
148         u32 val;
149
150         print_spew("Disabling read/write/fill probes for UP... ");
151
152         val=pci_read_config32(NODE_HT(0), HT_TRANSACTION_CONTROL);
153         val |= HTTC_DIS_FILL_P | HTTC_DIS_RMT_MEM_C | HTTC_DIS_P_MEM_C |
154                 HTTC_DIS_MTS | HTTC_DIS_WR_DW_P | HTTC_DIS_WR_B_P | 
155                 HTTC_DIS_RD_DW_P | HTTC_DIS_RD_B_P;
156         pci_write_config32(NODE_HT(0), HT_TRANSACTION_CONTROL, val);
157
158         print_spew("done.\r\n");
159
160 }
161
162 static void enable_apic_ext_id(u8 node) 
163 {
164 #if ENABLE_APIC_EXT_ID==1
165 #warning "FIXME Is the right place to enable apic ext id here?"
166
167       u32 val;
168
169         val = pci_read_config32(NODE_HT(node), 0x68);
170         val |= (HTTC_APIC_EXT_SPUR | HTTC_APIC_EXT_ID | HTTC_APIC_EXT_BRD_CST);
171         pci_write_config32(NODE_HT(node), 0x68, val);
172 #endif
173 }
174
175 static void enable_routing(u8 node)
176 {
177         u32 val;
178
179         /* HT Initialization Control Register
180          * F0:0x6C
181          * [ 0: 0] Routing Table Disable
182          *         0 = Packets are routed according to routing tables
183          *         1 = Packets are routed according to the default link field
184          * [ 1: 1] Request Disable (BSP should clear this)
185          *         0 = Request packets may be generated
186          *         1 = Request packets may not be generated.
187          * [ 3: 2] Default Link (Read-only)
188          *         00 = LDT0
189          *         01 = LDT1
190          *         10 = LDT2
191          *         11 = CPU on same node
192          * [ 4: 4] Cold Reset
193          *         - Scratch bit cleared by a cold reset
194          * [ 5: 5] BIOS Reset Detect
195          *         - Scratch bit cleared by a cold reset
196          * [ 6: 6] INIT Detect
197          *         - Scratch bit cleared by a warm or cold reset not by an INIT
198          *
199          */
200
201         /* Enable routing table */
202         print_spew("Enabling routing table for node ");
203         print_spew_hex8(node);
204
205         val=pci_read_config32(NODE_HT(node), 0x6c);
206         val &= ~((1<<1)|(1<<0));
207         pci_write_config32(NODE_HT(node), 0x6c, val);
208
209         print_spew(" done.\r\n");
210 }
211
212 static void fill_row(u8 node, u8 row, u32 value)
213 {
214         pci_write_config32(NODE_HT(node), 0x40+(row<<2), value);
215 }
216
217 #if CONFIG_MAX_PHYSICAL_CPUS > 1
218 static u8 link_to_register(int ldt)
219 {
220         /*
221          * [ 0: 3] Request Route
222          *     [0] Route to this node
223          *     [1] Route to Link 0
224          *     [2] Route to Link 1
225          *     [3] Route to Link 2
226          */
227
228         if (ldt&0x08) return 0x40;
229         if (ldt&0x04) return 0x20;
230         if (ldt&0x02) return 0x00;
231         
232         /* we should never get here */
233         print_spew("Unknown Link\n");
234         return 0;
235 }
236
237 static u32 get_row(u8 node, u8 row)
238 {
239         return pci_read_config32(NODE_HT(node), 0x40+(row<<2));
240 }
241
242 static int link_connection(u8 src, u8 dest)
243 {
244         return get_row(src, dest) & 0x0f;
245 }
246
247 static void rename_temp_node(u8 node)
248 {
249         uint32_t val;
250
251         print_spew("Renaming current temporary node to ");
252         print_spew_hex8(node);
253
254         val=pci_read_config32(NODE_HT(7), 0x60);
255         val &= (~7);  /* clear low bits. */
256         val |= node;   /* new node        */
257         pci_write_config32(NODE_HT(7), 0x60, val);
258
259         print_spew(" done.\r\n");
260 }
261
262 static int verify_connection(u8 dest)
263 {
264         /* See if we have a valid connection to dest */
265         u32 val;
266         
267         /* Verify that the coherent hypertransport link is
268          * established and actually working by reading the
269          * remode node's vendor/device id
270          */
271         val = pci_read_config32(NODE_HT(dest),0);
272         if(val != 0x11001022)
273                 return 0;
274
275         return 1;
276 }
277
278 static uint16_t read_freq_cap(device_t dev, uint8_t pos)
279 {
280         /* Handle bugs in valid hypertransport frequency reporting */
281         uint16_t freq_cap;
282         uint32_t id;
283
284         freq_cap = pci_read_config16(dev, pos);
285         freq_cap &= ~(1 << HT_FREQ_VENDOR); /* Ignore Vendor HT frequencies */
286
287 #if K8_HT_FREQ_1G_SUPPORT == 1
288     #if K8_REV_F_SUPPORT == 0
289         if (!is_cpu_pre_e0())
290     #endif 
291         {
292                 return freq_cap;
293         }
294 #endif
295
296         id = pci_read_config32(dev, 0);
297
298         /* AMD K8 Unsupported 1Ghz? */
299         if (id == (PCI_VENDOR_ID_AMD | (0x1100 << 16))) {
300                 freq_cap &= ~(1 << HT_FREQ_1000Mhz);
301         }
302         
303         return freq_cap;
304 }
305
306 static int optimize_connection(device_t node1, uint8_t link1, device_t node2, uint8_t link2)
307 {
308         static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
309         static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
310         uint16_t freq_cap1, freq_cap2;
311         uint8_t width_cap1, width_cap2, width, old_width, ln_width1, ln_width2;
312         uint8_t freq, old_freq;
313         int needs_reset;
314         /* Set link width and frequency */
315
316         /* Initially assume everything is already optimized and I don't need a reset */
317         needs_reset = 0;
318
319         /* Get the frequency capabilities */
320         freq_cap1 = read_freq_cap(node1, link1 + PCI_HT_CAP_HOST_FREQ_CAP);
321         freq_cap2 = read_freq_cap(node2, link2 + PCI_HT_CAP_HOST_FREQ_CAP);
322
323         /* Calculate the highest possible frequency */
324         freq = log2(freq_cap1 & freq_cap2);
325
326         /* See if I am changing the link freqency */
327         old_freq = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_FREQ);
328         old_freq &= 0x0f;
329         needs_reset |= old_freq != freq;
330         old_freq = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_FREQ);
331         old_freq &= 0x0f;
332         needs_reset |= old_freq != freq;
333
334         /* Set the Calulcated link frequency */
335         pci_write_config8(node1, link1 + PCI_HT_CAP_HOST_FREQ, freq);
336         pci_write_config8(node2, link2 + PCI_HT_CAP_HOST_FREQ, freq);
337
338         /* Get the width capabilities */
339         width_cap1 = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH);
340         width_cap2 = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH);
341
342         /* Calculate node1's input width */
343         ln_width1 = link_width_to_pow2[width_cap1 & 7];
344         ln_width2 = link_width_to_pow2[(width_cap2 >> 4) & 7];
345         if (ln_width1 > ln_width2) {
346                 ln_width1 = ln_width2;
347         }
348         width = pow2_to_link_width[ln_width1];
349         /* Calculate node1's output width */
350         ln_width1 = link_width_to_pow2[(width_cap1 >> 4) & 7];
351         ln_width2 = link_width_to_pow2[width_cap2 & 7];
352         if (ln_width1 > ln_width2) {
353                 ln_width1 = ln_width2;
354         }
355         width |= pow2_to_link_width[ln_width1] << 4;
356         
357         /* See if I am changing node1's width */
358         old_width = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH + 1);
359         old_width &= 0x77;      
360         needs_reset |= old_width != width;
361
362         /* Set node1's widths */
363         pci_write_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH + 1, width);
364
365         // * Calculate node2's width */
366         width = ((width & 0x70) >> 4) | ((width & 0x7) << 4);
367
368         /* See if I am changing node2's width */
369         old_width = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH + 1);
370         old_width &= 0x77;
371         needs_reset |= old_width != width;
372
373         /* Set node2's widths */
374         pci_write_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH + 1, width);
375
376         return needs_reset;
377 }
378
379 static uint8_t get_linkn_first(uint8_t byte)
380 {
381         if(byte & 0x02) { byte = 0; }
382         else if(byte & 0x04) { byte = 1; }
383         else if(byte & 0x08) { byte = 2; }
384         return byte;
385 }
386
387 static uint8_t get_linkn_last(uint8_t byte)
388 {
389         if(byte & 0x02) { byte &= 0x0f; byte |= 0x00;  }
390         if(byte & 0x04) { byte &= 0x0f; byte |= 0x10;  }
391         if(byte & 0x08) { byte &= 0x0f; byte |= 0x20;  }
392         return byte>>4;
393 }
394
395 static uint8_t get_linkn_last_count(uint8_t byte)
396 {
397         byte &= 0x0f;
398         if(byte & 0x02) { byte &= 0xcf; byte |= 0x00; byte+=0x40; }
399         if(byte & 0x04) { byte &= 0xcf; byte |= 0x10; byte+=0x40; }
400         if(byte & 0x08) { byte &= 0xcf; byte |= 0x20; byte+=0x40; }
401         return byte>>4;
402 }
403
404 static void setup_row_local(u8 source, u8 row) /* source will be 7 when it is for temp use*/
405 {
406         uint8_t linkn;
407         uint32_t val;
408         val = 1;
409         for(linkn = 0; linkn<3; linkn++) { 
410                 uint8_t regpos; 
411                 uint32_t reg;
412                 regpos = 0x98 + 0x20 * linkn;
413                 reg = pci_read_config32(NODE_HT(source), regpos);
414                 if ((reg & 0x17) != 3) continue; /* it is not conherent or not connected*/
415                 val |= 1<<(linkn+1); 
416         }
417         val <<= 16;
418         val |= 0x0101;
419         fill_row(source,row, val);
420 }
421
422 static void setup_row_direct_x(u8 temp, u8 source, u8 dest, u8 linkn)
423 {
424         uint32_t val;
425         uint32_t val_s;
426         val = 1<<(linkn+1);
427         val |= 1<<(linkn+1+8); /*for direct connect response route should equal to request table*/
428
429         if(((source &1)!=(dest &1)) 
430 #if CROSS_BAR_47_56
431                 && ( (source<4)||(source>5) ) //(6,7) (7,6) should still be here
432                                                //(6,5) (7,4) should be here     
433 #endif
434         ){
435                 val |= (1<<16);
436         } else {
437                 /*for CROSS_BAR_47_56  47, 56, should be here too
438                         and for 47, 56, 57, 75, 46, 64 we need to substract another link to 
439                                 6,  7,  6,  6,  7,  7 
440                 */
441                 val_s = get_row(temp, source);
442                 val |= ((val_s>>16) - (1<<(linkn+1)))<<16;
443         }
444
445         fill_row(temp,dest, val );
446 }
447
448 #if CROSS_BAR_47_56
449 static void opt_broadcast_rt(u8 source, u8 dest, u8 kickout) {
450         uint32_t val;
451         val = get_row(source, dest);
452         val -= link_connection(source, kickout)<<16;
453         fill_row(source, dest, val);
454 }
455
456 static void opt_broadcast_rt_group(const u8 *conn, int num) {
457         int i;
458
459         for(i=0; i<num; i+=3) {
460                 opt_broadcast_rt(conn[i], conn[i+1],conn[i+2]);
461         }
462 }
463 static void opt_broadcast_rt_plus(u8 source, u8 dest, u8 kickout) {
464         uint32_t val;
465         val = get_row(source, dest);
466         val += link_connection(source, kickout)<<16;
467         fill_row(source, dest, val);
468 }       
469         
470 static void opt_broadcast_rt_plus_group(const u8 *conn, int num) {
471         int i;  
472                 
473         for(i=0; i<num; i+=3) {
474                 opt_broadcast_rt_plus(conn[i], conn[i+1],conn[i+2]);
475         }       
476
477 #endif
478
479 static void setup_row_direct(u8 source, u8 dest, u8 linkn){
480         setup_row_direct_x(source, source, dest, linkn);
481 }
482
483 static void setup_remote_row_direct(u8 source, u8 dest, u8 linkn){
484         setup_row_direct_x(7, source, dest, linkn);
485 }
486
487 static void setup_temp_row(u8 source, u8 dest)
488 {
489         /* copy val from (source, dest) to (source,7) */
490         fill_row(source,7,get_row(source,dest));
491 }
492
493 static void clear_temp_row(u8 source)
494 {
495         fill_row(source, 7, DEFAULT);
496 }
497
498 static void setup_remote_node(u8 node)
499 {
500         static const uint8_t pci_reg[] = { 
501                 0x44, 0x4c, 0x54, 0x5c, 0x64, 0x6c, 0x74, 0x7c, 
502                 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78,
503                 0x84, 0x8c, 0x94, 0x9c, 0xa4, 0xac, 0xb4, 0xbc,
504                 0x80, 0x88, 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8,
505                 0xc4, 0xcc, 0xd4, 0xdc,
506                 0xc0, 0xc8, 0xd0, 0xd8,
507                 0xe0, 0xe4, 0xe8, 0xec,
508         };
509         int i;
510
511         print_spew("setup_remote_node: ");
512
513         /* copy the default resource map from node 0 */
514         for(i = 0; i < ARRAY_SIZE(pci_reg); i++) {
515                 uint32_t value;
516                 uint8_t reg;
517                 reg = pci_reg[i];
518                 value = pci_read_config32(NODE_MP(0), reg);
519                 pci_write_config32(NODE_MP(7), reg, value);
520
521         }
522         print_spew("done\r\n");
523 }
524
525 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 1*/
526
527
528 #if CONFIG_MAX_PHYSICAL_CPUS > 2
529 #if !CROSS_BAR_47_56
530 static void setup_row_indirect_x(u8 temp, u8 source, u8 dest)
531 #else
532 static void setup_row_indirect_x(u8 temp, u8 source, u8 dest, u8 gateway, u8 diff)
533 #endif
534 {
535         /*for indirect connection, we need to compute the val from val_s(source, source), and val_g(source, gateway) */
536         uint32_t val_s;
537         uint32_t val;
538 #if !CROSS_BAR_47_56    
539         u8 gateway;
540         u8 diff;
541         if(source<dest) {
542                 gateway = source + 2;
543         } else {
544                 gateway = source - 2;
545         }
546 #endif
547         val_s = get_row(temp, source);
548         val = get_row(temp, gateway);
549         
550         val &= 0xffff;
551         val_s >>= 16;
552         val_s &= 0xfe;
553         
554 #if !CROSS_BAR_47_56
555         diff = ((source&1)!=(dest &1));
556 #endif
557
558         if(diff && (val_s!=(val&0xff)) ) { /* use another connect as response*/
559                 val_s -= val &  0xff;
560 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
561                 uint8_t byte;
562                 /* Some node have two links left
563                  * don't worry we only have (2, (3 as source need to handle
564                  */
565                 byte = val_s;
566                 byte = get_linkn_last_count(byte);
567                 if((byte>>2)>1) { /* make sure not the corner*/
568                         if(source<dest) {
569                                 val_s-=link_connection(temp, source-2); /* -down*/
570                         } else {
571 #if CROSS_BAR_47_56             
572                                 #if 0           
573                                 if(source==7) {
574                                         val_s-=link_connection(temp, 6);  // for 7,2 via 5
575                                 } else if (source==6){
576                                         val_s-=link_connection(temp, 7);  // for 6,3 via 4
577                                 } else 
578                                 #endif
579                                 if (source < gateway) { // for 5, 4 via 7
580                                         val_s-=link_connection(temp, source-2);
581                                 } else
582 #endif                                  
583                                         val_s-=link_connection(temp, source+2); /* -up*/
584                         }
585                 }
586 #endif
587                 val &= 0xff;
588                 val |= (val_s<<8);
589         } 
590
591         if(diff) { /* cross rung?*/
592                 val |= (1<<16);
593         }
594         else {
595                 val_s = get_row(temp, source);
596                 val |= ((val_s>>16) - link_connection(temp, gateway))<<16; 
597         }
598
599         fill_row(temp, dest, val);
600
601 }
602
603 #if !CROSS_BAR_47_56
604 static void setup_row_indirect(u8 source, u8 dest)
605 {       
606         setup_row_indirect_x(source, source, dest);
607 }
608 #else           
609 static void setup_row_indirect(u8 source, u8 dest, u8 gateway, u8 diff)
610 {
611         setup_row_indirect_x(source, source, dest, gateway, diff);
612 }
613 #endif   
614
615 static void setup_row_indirect_group(const u8 *conn, int num)
616 {
617         int i;
618
619 #if !CROSS_BAR_47_56
620         for(i=0; i<num; i+=2) {
621                 setup_row_indirect(conn[i], conn[i+1]);
622 #else
623         for(i=0; i<num; i+=4) {
624                 setup_row_indirect(conn[i], conn[i+1],conn[i+2], conn[i+3]);
625 #endif
626
627         }
628 }
629
630 #if !CROSS_BAR_47_56
631 static void setup_remote_row_indirect(u8 source, u8 dest)
632 {
633         setup_row_indirect_x(7, source, dest);
634 }
635 #else
636 static void setup_remote_row_indirect(u8 source, u8 dest, u8 gateway, u8 diff)
637 {
638         setup_row_indirect_x(7, source, dest, gateway, diff);
639 }
640 #endif
641
642 static void setup_remote_row_indirect_group(const u8 *conn, int num)
643 {
644         int i;
645
646 #if !CROSS_BAR_47_56
647         for(i=0; i<num; i+=2) {
648                 setup_remote_row_indirect(conn[i], conn[i+1]);
649 #else
650         for(i=0; i<num; i+=4) {
651                 setup_remote_row_indirect(conn[i], conn[i+1],conn[i+2], conn[i+3]);
652 #endif
653         }
654 }
655
656 #endif /*CONFIG_MAX_PHYSICAL_CPUS > 2*/
657
658
659 static void setup_uniprocessor(void)
660 {
661         print_spew("Enabling UP settings\r\n");
662 #if CONFIG_LOGICAL_CPUS==1
663         unsigned tmp = (pci_read_config32(NODE_MC(0), 0xe8) >> 12) & 3;
664         if (tmp>0) return;
665 #endif
666         disable_probes();
667 }
668
669 #if CONFIG_MAX_PHYSICAL_CPUS > 2
670 static int optimize_connection_group(const u8 *opt_conn, int num) {
671         int needs_reset = 0;
672         int i;
673         for(i=0; i<num; i+=2) {
674                 needs_reset = optimize_connection(
675                         NODE_HT(opt_conn[i]), 0x80 + link_to_register(link_connection(opt_conn[i],opt_conn[i+1])),
676                         NODE_HT(opt_conn[i+1]), 0x80 + link_to_register(link_connection(opt_conn[i+1],opt_conn[i])) );
677         }               
678         return needs_reset;
679 }  
680 #endif
681
682 #if CONFIG_MAX_PHYSICAL_CPUS > 1
683 static unsigned setup_smp2(void)
684 {
685         unsigned nodes;
686         u8 byte;
687         uint32_t val;
688         nodes = 2;
689
690         setup_row_local(0, 0); /* it will update the broadcast RT*/
691         
692         val = get_row(0,0);
693         byte = (val>>16) & 0xfe;
694         if(byte<0x2) { /* no coherent connection so get out.*/
695                 nodes = 1;
696                 return nodes;
697         }
698
699         /* Setup and check a temporary connection to node 1 */
700 #if TRY_HIGH_FIRST == 1
701         byte = get_linkn_last(byte); /* Max Link to node1 */
702 #else
703         byte = get_linkn_first(byte); /*Min Link to node1 --- according to AMD*/
704 #endif
705         print_linkn("(0,1) link=", byte);
706         setup_row_direct(0,1, byte);
707         setup_temp_row(0, 1);
708         
709         verify_connection(7);
710
711         /* We found 2 nodes so far */
712         val = pci_read_config32(NODE_HT(7), 0x6c);
713         byte = (val>>2) & 0x3; /*get default link on node7 to node0*/
714         print_linkn("(1,0) link=", byte);
715         setup_row_local(7,1);
716         setup_remote_row_direct(1, 0, byte);
717
718 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)      
719         val = get_row(7,1);
720         byte = (val>>16) & 0xfe;
721         byte = get_linkn_last_count(byte);
722         if((byte>>2)==3) { /* Oh! we need to treat it as node2. So use another link*/
723                 val = get_row(0,0);
724                 byte = (val>>16) & 0xfe;
725 #if TRY_HIGH_FIRST == 1
726                 byte = get_linkn_first(byte); /* Min link to Node1 */
727 #else
728                 byte = get_linkn_last(byte);  /* Max link to Node1*/
729 #endif
730                 print_linkn("\t-->(0,1) link=", byte);
731                 setup_row_direct(0,1, byte);
732                 setup_temp_row(0, 1);
733         
734                 verify_connection(7);
735                         
736                 /* We found 2 nodes so far */
737                 val = pci_read_config32(NODE_HT(7), 0x6c);
738                 byte = (val>>2) & 0x3; /* get default link on node7 to node0*/
739                 print_linkn("\t-->(1,0) link=", byte); 
740                 setup_row_local(7,1);
741                 setup_remote_row_direct(1, 0, byte);
742         }
743 #endif
744         
745         setup_remote_node(1);  /* Setup the regs on the remote node */
746         rename_temp_node(1);    /* Rename Node 7 to Node 1  */
747         enable_routing(1);      /* Enable routing on Node 1 */
748 #if 0
749         /*don't need and it is done by clear_dead_links */
750         clear_temp_row(0);
751 #endif
752
753         return nodes;
754 }
755 #endif /*CONFIG_MAX_PHYSICAL_CPUS > 1 */
756
757 #if CONFIG_MAX_PHYSICAL_CPUS > 2
758
759 static unsigned setup_smp4(void)
760 {
761         unsigned nodes;
762         u8 byte;
763         uint32_t val;
764
765         nodes=4;
766
767         /* Setup and check temporary connection from Node 0 to Node 2 */
768         val = get_row(0,0);
769         byte = ((val>>16) & 0xfe) - link_connection(0,1);
770         byte = get_linkn_last_count(byte);
771
772         if((byte>>2)==0) { /* We should have two coherent for 4p and above*/
773                 nodes = 2;
774                 return nodes;
775         }
776
777         byte &= 3; /* bit [3,2] is count-1*/
778         print_linkn("(0,2) link=", byte); 
779         setup_row_direct(0, 2, byte);  /*(0,2) direct link done*/
780
781         /* We found 3 nodes so far. Now setup a temporary
782         * connection from node 0 to node 3 via node 1
783         */
784         setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
785         /* here should setup_row_direct(1,3) at first, before that we should find the link in node 1 to 3*/
786         val = get_row(1,1);
787         byte = ((val>>16) & 0xfe) - link_connection(1,0);
788         byte = get_linkn_first(byte);
789         print_linkn("(1,3) link=", byte); 
790         setup_row_direct(1,3,byte);  /* (1, 3) direct link done*/
791
792         /* We found 4 nodes so far. Now setup all nodes for 4p */
793         // We need to make sure 0,2 and 1,3 link is set already
794 #if !CROSS_BAR_47_56
795         static const u8 conn4_1[] = {
796                 0,3,
797                 1,2,
798         };      
799 #else
800         static const u8 conn4_1[] = {
801                 0,3,2,1,
802                 1,2,3,1,
803         };
804 #endif
805
806         setup_row_indirect_group(conn4_1, ARRAY_SIZE(conn4_1));
807
808         setup_temp_row(0,2);
809         verify_connection(7);
810         val = pci_read_config32(NODE_HT(7), 0x6c);
811         byte = (val>>2) & 0x3; /* get default link on 7 to 0*/
812         print_linkn("(2,0) link=", byte); 
813
814         setup_row_local(7,2);
815         setup_remote_row_direct(2, 0, byte);  /* node 2 to node 0 direct link done */
816         setup_remote_node(2);  /* Setup the regs on the remote node */
817
818         rename_temp_node(2);    /* Rename Node 7 to Node 2  */
819         enable_routing(2);      /* Enable routing on Node 2 */
820
821         setup_temp_row(0,1);
822         setup_temp_row(1,3);
823         verify_connection(7);
824
825         val = pci_read_config32(NODE_HT(7), 0x6c);
826         byte = (val>>2) & 0x3; /* get default link on 7 to 1*/
827         print_linkn("(3,1) link=", byte); 
828
829         setup_row_local(7,3);
830         setup_remote_row_direct(3, 1, byte); /* node 3 to node 1 direct link done */
831         setup_remote_node(3);  /* Setup the regs on the remote node */
832
833         /* We need to init link between 2, and 3 direct link */
834         val = get_row(2,2);
835         byte = ((val>>16) & 0xfe) - link_connection(2,0);
836         byte = get_linkn_last_count(byte);
837         print_linkn("(2,3) link=", byte & 3);
838         
839         setup_row_direct(2,3, byte & 0x3);
840         setup_temp_row(0,2);
841         setup_temp_row(2,3);
842         verify_connection(7); /* to 3*/
843
844 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
845         /* We need to find out which link is to node3 */
846         if((byte>>2)==2) { /* one to node3, one to node0, one to node4*/
847                 val = get_row(7,3);
848                 if((val>>16) == 1) { /* that link is to node4, because via node1 it has been set, recompute it*/
849                         val = get_row(2,2);
850                         byte = ((val>>16) & 0xfe) - link_connection(2,0);
851                         byte = get_linkn_first(byte);
852                         print_linkn("\t-->(2,3) link=", byte); 
853                         setup_row_direct(2,3,byte);
854                         setup_temp_row(2,3);
855                         verify_connection(7); /* to 3*/
856                 }
857         } 
858 #endif
859
860         val = pci_read_config32(NODE_HT(7), 0x6c);
861         byte = (val>>2) & 0x3; /* get default link on 7 to 2*/
862         print_linkn("(3,2) link=", byte); 
863         setup_remote_row_direct(3,2, byte);
864
865 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
866         /* set link from 3 to 5 before enable it*/
867         val = get_row(7,3);
868         byte = ((val>>16) & 0xfe) - link_connection(7,2) - link_connection(7,1);
869         byte = get_linkn_last_count(byte);
870         if((byte>>2)==1) { /* We should have three coherent links on node 3 for 6p and above*/
871                 byte &= 3; /*bit [3,2] is count-2*/
872                 print_linkn("(3,5) link=", byte);
873                 setup_remote_row_direct(3, 5, byte);
874         }
875         
876         val = get_row(2,2);
877         byte = ((val>>16) & 0xfe) - link_connection(2,3) - link_connection(2,0);
878         byte = get_linkn_last_count(byte);
879
880         if((byte>>2)==1) { /* We should have three coherent link on node 2 for 6p and above*/
881                 byte &= 3; /* bit [3,2] is count-2*/
882                 print_linkn("(2,4) link=", byte);
883                 setup_row_direct(2, 4, byte);
884         }       
885 #endif
886
887         //Beside 3, 1 is set, We need to make sure 3, 5 is set already in case has three link in 3
888 #if !CROSS_BAR_47_56
889         static const u8 conn4_3[] = {
890                 3,0,
891         };
892 #else
893         static const u8 conn4_3[] = {
894                 3,0,1,1,
895         };
896 #endif
897         setup_remote_row_indirect_group(conn4_3, ARRAY_SIZE(conn4_3));
898
899 /* ready to enable RT for Node 3 */
900         rename_temp_node(3);
901         enable_routing(3);      /* enable routing on node 3 (temp.) */
902
903         // beside 2, 0 is set, We need to make sure 2, 4 link is set already in case has three link in 2
904 #if !CROSS_BAR_47_56    
905         static const u8 conn4_2[] = {
906                 2,1,  
907         };      
908 #else   
909         static const u8 conn4_2[] = {
910                 2,1,0,1,
911         };      
912 #endif          
913         setup_row_indirect_group(conn4_2, ARRAY_SIZE(conn4_2));
914
915 #if 0
916         /*We need to do sth to reverse work for setup_temp_row (0,1) (1,3) */
917         /* it will be done by clear_dead_links */
918         clear_temp_row(0);
919         clear_temp_row(1);
920 #endif
921
922         return nodes;
923
924 }
925
926 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 2 */
927
928 #if CONFIG_MAX_PHYSICAL_CPUS > 4
929
930 static unsigned setup_smp6(void)
931 {
932         unsigned nodes;
933         u8 byte;
934         uint32_t val;
935
936         nodes=6;
937
938         /* Setup and check temporary connection from Node 0 to Node 4  through 2*/
939         val = get_row(2,2);
940         byte = ((val>>16) & 0xfe) - link_connection(2,3) - link_connection(2,0);
941         byte = get_linkn_last_count(byte);
942
943         if((byte>>2)==0) { /* We should have three coherent link on node 2 for 6p and above*/
944                 nodes = 4;
945                 return nodes;
946         }
947
948         /* Setup and check temporary connection from Node 0 to Node 5  through 1, 3*/
949         /* set link from 3 to 5 before enable it*/
950         val = get_row(3,3);
951         byte = ((val>>16) & 0xfe) - link_connection(3,2) - link_connection(3,1);
952         byte = get_linkn_last_count(byte);
953         if((byte>>2)==0) { /* We should have three coherent links on node 3 for 6p and above*/
954                 nodes = 4;
955                 return nodes;
956         }
957         
958         /* We found 6 nodes so far. Now setup all nodes for 6p */
959 #warning "FIXME we need to find out the correct gateway for 6p" 
960         static const u8 conn6_1[] = {
961 #if !CROSS_BAR_47_56
962                 0, 4,
963                 0, 5,
964                 1, 4,
965                 1, 5,
966                 2, 5,
967                 3, 4,
968 #else
969                 0, 4, 2, 0,
970                 0, 5, 2, 1,
971                 1, 4, 3, 1,
972                 1, 5, 3, 0,
973                 2, 5, 3, 0,
974                 3, 4, 2, 0,
975 #endif
976         }; 
977
978         setup_row_indirect_group(conn6_1, ARRAY_SIZE(conn6_1));
979         
980         for(byte=0; byte<4; byte+=2) {
981                 setup_temp_row(byte,byte+2);
982         }
983         verify_connection(7);
984         val = pci_read_config32(NODE_HT(7), 0x6c);
985         byte = (val>>2) & 0x3; /*get default link on 7 to 2*/
986         print_linkn("(4,2) link=", byte); 
987         
988         setup_row_local(7,4);
989         setup_remote_row_direct(4, 2, byte);
990         setup_remote_node(4);  /* Setup the regs on the remote node */
991         
992         /* Set indirect connection to 0, to 3 */
993         //we only need to set 4,0 here
994         static const u8 conn6_2[] = {
995 #if !CROSS_BAR_47_56
996                 4, 0,
997 #else
998                 4, 0, 2, 0,
999 #endif
1000         };      
1001         
1002         setup_remote_row_indirect_group(conn6_2, ARRAY_SIZE(conn6_2));
1003         
1004         rename_temp_node(4);
1005         enable_routing(4);
1006
1007         setup_temp_row(0,1);
1008         for(byte=0; byte<4; byte+=2) {
1009                 setup_temp_row(byte+1,byte+3);
1010         }
1011         verify_connection(7);
1012
1013         val = pci_read_config32(NODE_HT(7), 0x6c);
1014         byte = (val>>2) & 0x3; /* get default link on 7 to 3*/
1015         print_linkn("(5,3) link=", byte); 
1016         setup_row_local(7,5);
1017         setup_remote_row_direct(5, 3, byte);
1018         setup_remote_node(5);  /* Setup the regs on the remote node */
1019         
1020 #if !CROSS_BAR_47_56
1021         /* We need to init link between 4, and 5 direct link */
1022         val = get_row(4,4);
1023         byte = ((val>>16) & 0xfe) - link_connection(4,2);
1024         byte = get_linkn_last_count(byte);
1025         print_linkn("(4,5) link=", byte & 3);
1026         
1027         setup_row_direct(4,5, byte & 0x3);
1028         setup_temp_row(0,2);
1029         setup_temp_row(2,4);
1030         setup_temp_row(4,5);
1031         verify_connection(7); /* to 5*/
1032
1033 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1034         /* We need to find out which link is to node5 */
1035         
1036         if((byte>>2)==2) { /* one to node5, one to node2, one to node6*/
1037                 val = get_row(7,5);
1038                 if((val>>16) == 1) { /* that link is to node6, because via node 3 node 5 has been set*/
1039                         val = get_row(4,4);
1040                         byte = ((val>>16) & 0xfe) - link_connection(4,2);
1041                         byte = get_linkn_first(byte);
1042                         print_linkn("\t-->(4,5) link=", byte);
1043                         setup_row_direct(4,5,byte);
1044                         setup_temp_row(4,5);
1045                         verify_connection(7); /* to 5*/
1046                 }
1047         } 
1048 #endif
1049
1050         val = pci_read_config32(NODE_HT(7), 0x6c);
1051         byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
1052         print_linkn("(5,4) link=", byte); 
1053         setup_remote_row_direct(5,4, byte);
1054         
1055         //init 5, 7 here
1056         val = get_row(7,5);
1057         byte = ((val>>16) & 0xfe) - link_connection(7,4) - link_connection(7,3);
1058         byte = get_linkn_last_count(byte);
1059         if((byte>>2)==1) { /* We should have three coherent links on node 5 for 6p and above*/
1060                 byte &= 3; /*bit [3,2] is count-2*/
1061                 print_linkn("(5,7) link=", byte);
1062                 setup_remote_row_direct(5, 7, byte);
1063         }
1064         
1065         //init 4,6 here
1066         val = get_row(4,4);
1067         byte = ((val>>16) & 0xfe) - link_connection(4,5) - link_connection(4,2);
1068         byte = get_linkn_last_count(byte);
1069
1070         if((byte>>2)==1) { /* We should have three coherent link on node 4 for 6p and above*/
1071                 byte &= 3; /* bit [3,2] is count-2*/
1072                 print_linkn("(4,6) link=", byte);
1073                 setup_row_direct(4, 6, byte);
1074         }       
1075         
1076 #endif  
1077         
1078         //We need to set 5,0 here only, We need to set up 5, 7 to make 5,0
1079         /* Set indirect connection to 0, to 3  for indirect we will use clockwise routing */
1080         static const u8 conn6_3[] = {
1081 #if !CROSS_BAR_47_56
1082                 5, 0,
1083 #else
1084                 5, 0, 3, 0,
1085 #endif
1086         };      
1087         
1088         setup_remote_row_indirect_group(conn6_3, ARRAY_SIZE(conn6_3));
1089
1090 /* ready to enable RT for 5 */
1091         rename_temp_node(5);
1092         enable_routing(5);      /* enable routing on node 5 (temp.) */
1093
1094         static const u8 conn6_4[] = {
1095 #if !CROSS_BAR_47_56
1096                 4, 1,
1097                 4, 3,
1098                 
1099                 5, 2,
1100                 5, 1,
1101                 
1102 #else
1103                 4, 1, 2, 0,
1104                 4, 3, 2, 0,
1105                 4, 5, 2, 0,
1106                 
1107                 5, 2, 3, 0,
1108                 5, 1, 3, 0,
1109                 5, 4, 3, 0,
1110                 
1111 #endif
1112         };      
1113         
1114         setup_row_indirect_group(conn6_4, ARRAY_SIZE(conn6_4));
1115
1116 #if 0
1117         /* We need to do sth about reverse about setup_temp_row (0,1), (2,4), (1, 3), (3,5)
1118          * It will be done by clear_dead_links 
1119          */
1120         for(byte=0; byte<4; byte++) {
1121                 clear_temp_row(byte);
1122         }
1123 #endif
1124
1125         return nodes;
1126
1127 }
1128
1129 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 4 */
1130
1131 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1132
1133 static unsigned setup_smp8(void)
1134 {
1135         unsigned nodes;
1136         u8 byte;
1137         uint32_t val;
1138
1139         nodes=8;
1140
1141         /* Setup and check temporary connection from Node 0 to Node 6 via 2 and 4 to 7 */
1142         val = get_row(4,4);
1143 #if CROSS_BAR_47_56 
1144         byte = ((val>>16) & 0xfe) - link_connection(4,2);
1145 #else
1146         byte = ((val>>16) & 0xfe) - link_connection(4,5) - link_connection(4,2);
1147         byte = get_linkn_last_count(byte); /* Max link to 6*/
1148         if((byte>>2)==0) { /* We should have two or three coherent links on node 4 for 8p*/
1149                 nodes = 6;
1150                 return nodes;
1151         }
1152 #endif
1153
1154 #if CROSS_BAR_47_56 
1155         byte = get_linkn_last_count(byte); /* Max link to 6*/
1156         if((byte>>2)<2) { /* We should have two or three coherent links on node 4 for 8p*/
1157                 nodes = 6;
1158                 return nodes;
1159         }
1160 #if TRY_HIGH_FIRST == 1
1161         byte = ((val>>16) & 0xfe) - link_connection(4,2);
1162         byte = get_linkn_first(byte);  /*Min link to 6*/
1163 #else
1164         byte &= 3; /* bit [3,2] is count-1 or 2*/
1165 #endif
1166         print_linkn("(4,6) link=", byte);
1167         setup_row_direct(4, 6, byte);
1168 #endif
1169
1170 #if !CROSS_BAR_47_56
1171         /* Setup and check temporary connection from Node 0 to Node 7  through 1, 3, 5*/
1172         val = get_row(5,5);
1173         byte = ((val>>16) & 0xfe) - link_connection(5,4) - link_connection(5,3);
1174         byte = get_linkn_last_count(byte);
1175         if((byte>>2)==0) { /* We should have three coherent links on node 5 for 6p and above*/
1176                 nodes = 6;
1177                 return nodes;
1178         }
1179 #endif
1180
1181         /* We found 8 nodes so far. Now setup all nodes for 8p */
1182         static const u8 conn8_1[] = {
1183 #if !CROSS_BAR_47_56
1184                 0, 6,
1185                 /*0, 7,*/
1186                 1, 6,
1187                 /*1, 7,*/
1188                 2, 6,
1189                 /*2, 7,*/
1190                 3, 6,
1191                 /*3, 7,*/
1192                 /*4, 7,*/
1193                 5, 6,
1194 #else
1195                 0, 6, 2, 0,
1196                 /*0, 7, 2, 0,*/
1197                 1, 6, 3, 0,
1198                 /*1, 7, 3, 0,*/
1199                 2, 6, 4, 0,
1200                 /*2, 7, 4, 0,*/
1201                 3, 6, 5, 1,
1202                 /*3, 7, 5, 0,*/
1203 #endif
1204         };
1205
1206         setup_row_indirect_group(conn8_1,ARRAY_SIZE(conn8_1));
1207
1208         for(byte=0; byte<6; byte+=2) {
1209                 setup_temp_row(byte,byte+2);
1210         }
1211         verify_connection(7);
1212         val = pci_read_config32(NODE_HT(7), 0x6c);
1213         byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
1214         print_linkn("(6,4) link=", byte);
1215         
1216         setup_row_local(7,6);
1217         setup_remote_row_direct(6, 4, byte);
1218         setup_remote_node(6);  /* Setup the regs on the remote node */
1219         /* Set indirect connection to 0, to 3   */
1220 #warning "FIXME we need to find out the correct gateway for 8p"         
1221         static const u8 conn8_2[] = {
1222 #if !CROSS_BAR_47_56
1223                 6, 0,
1224 #else
1225                 6, 0, 4, 0,
1226 #endif
1227         };
1228
1229         setup_remote_row_indirect_group(conn8_2, ARRAY_SIZE(conn8_2));
1230
1231 #if CROSS_BAR_47_56
1232         //init 5, 6 here
1233         /* here init 5, 6 */
1234         /* Setup and check temporary connection from Node 0 to Node 5  through 1, 3, 5*/
1235         val = get_row(5,5);
1236         byte = ((val>>16) & 0xfe) - link_connection(5,3);
1237 #if TRY_HIGH_FIRST == 1
1238         byte = get_linkn_first(byte);
1239 #else
1240         byte = get_linkn_last(byte);        
1241 #endif
1242         print_linkn("(5,6) link=", byte);
1243         setup_row_direct(5, 6, byte);
1244
1245         setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
1246         for(byte=0; byte<4; byte+=2) {
1247                 setup_temp_row(byte+1,byte+3);
1248         }
1249         setup_temp_row(5,6);
1250
1251         verify_connection(7);
1252
1253         val = get_row(7,6); // to chect it if it is node6 before renaming
1254         if( (val>>16) == 1) { // it is real node 7 so swap it
1255                 /* We need to recompute link to 6 */
1256                 val = get_row(5,5);
1257                 byte = ((val>>16) & 0xfe) - link_connection(5,3);
1258 #if TRY_HIGH_FIRST == 1
1259                 byte = get_linkn_first(byte);
1260 #else
1261                 byte = get_linkn_last(byte);
1262 #endif
1263                 print_linkn("\t-->(5,6) link=", byte);
1264                 setup_row_direct(5, 6, byte);
1265 #if 0
1266                 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
1267                 for(byte=0; byte<4; byte+=2) {
1268                         setup_temp_row(byte+1,byte+3); 
1269                 }
1270 #endif
1271                 setup_temp_row(5,6);
1272
1273                 verify_connection(7);
1274         }
1275         val = pci_read_config32(NODE_HT(7), 0x6c);
1276         byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
1277         print_linkn("(6,5) link=", byte);
1278         setup_remote_row_direct(6, 5, byte);
1279         /*Till now 56, 65 done */
1280 #endif
1281         
1282         rename_temp_node(6);
1283         enable_routing(6);
1284
1285 #if !CROSS_BAR_47_56
1286         setup_temp_row(0,1);
1287         for(byte=0; byte<6; byte+=2) {
1288                 setup_temp_row(byte+1,byte+3);
1289         }
1290
1291         verify_connection(7);
1292
1293         val = pci_read_config32(NODE_HT(7), 0x6c);
1294         byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
1295         print_linkn("(7,5) link=", byte); 
1296         setup_row_local(7,7);
1297         setup_remote_row_direct(7, 5, byte);
1298
1299 #else
1300         val = get_row(4,4);
1301         byte = ((val>>16) & 0xfe) - link_connection(4,2) - link_connection(4,6);
1302         byte = get_linkn_first(byte); 
1303         print_linkn("(4,7) link=", byte); 
1304         setup_row_direct(4, 7, byte);
1305
1306         /* Setup and check temporary connection from Node 0 to Node 7 through 2, and 4*/
1307         for(byte=0; byte<4; byte+=2) {
1308                 setup_temp_row(byte,byte+2);
1309         }
1310
1311         verify_connection(7);
1312
1313         val = pci_read_config32(NODE_HT(7), 0x6c);
1314         byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
1315         print_linkn("(7,4) link=", byte); 
1316         setup_row_local(7,7);
1317         setup_remote_row_direct(7, 4, byte);
1318         /* till now 4-7, 7-4 done. */
1319 #endif
1320         setup_remote_node(7);  /* Setup the regs on the remote node */
1321
1322 #if CROSS_BAR_47_56
1323         /* here init 5, 7 */
1324         /* Setup and check temporary connection from Node 0 to Node 5  through 1, 3, 5*/
1325         val = get_row(5,5);
1326         byte = ((val>>16) & 0xfe) - link_connection(5,3) - link_connection(5,6);
1327         byte = get_linkn_first(byte);
1328         print_linkn("(5,7) link=", byte); 
1329         setup_row_direct(5, 7, byte);
1330         
1331         setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
1332         for(byte=0; byte<4; byte+=2) {
1333                 setup_temp_row(byte+1,byte+3); 
1334         }
1335
1336         verify_connection(7);
1337
1338         val = pci_read_config32(NODE_HT(7), 0x6c);
1339         byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
1340         print_linkn("(7,5) link=", byte);
1341         setup_remote_row_direct(7, 5, byte);
1342         /*Till now 57, 75 done */
1343         
1344 #endif
1345
1346         /* We need to init link between 6, and 7 direct link */
1347         val = get_row(6,6);
1348 #if !CROSS_BAR_47_56
1349         byte = ((val>>16) & 0xfe) - link_connection(6,4);
1350 #else
1351         byte = ((val>>16) & 0xfe) - link_connection(6,4) - link_connection(6,5);
1352 #endif
1353         byte = get_linkn_first(byte);
1354         print_linkn("(6,7) link=", byte);
1355         setup_row_direct(6,7, byte);
1356
1357         val = get_row(7,7);
1358 #if !CROSS_BAR_47_56
1359         byte = ((val>>16) & 0xfe) - link_connection(7,5);
1360 #else
1361         byte = ((val>>16) & 0xfe) - link_connection(7,5) - link_connection(7,4);
1362 #endif
1363         byte = get_linkn_first(byte);
1364         print_linkn("(7,6) link=", byte);
1365         setup_row_direct(7,6, byte);
1366
1367         /* Set indirect connection to 0, to 3  for indirect we will use clockwise routing */
1368         static const u8 conn8_3[] = {
1369 #if !CROSS_BAR_47_56
1370                 0, 7,  /* restore it*/
1371                 1, 7,
1372                 2, 7,
1373                 3, 7,
1374                 4, 7,
1375                 
1376                 6, 1,
1377                 6, 2,
1378                 6, 3,
1379                 6, 5,
1380                 
1381                 7, 0,
1382                 7, 1,
1383                 7, 2,
1384                 7, 3,
1385                 7, 4,
1386 #else
1387
1388                 
1389                 4, 5, 6, 1,
1390                 5, 4, 7, 1,
1391
1392                 6, 1, 5, 0, // or 4, 1
1393                 6, 2, 4, 0,
1394                 6, 3, 5, 0, // or 4, 1
1395
1396                 7, 0, 4, 0, // or 5, 1
1397                 7, 1, 5, 0,
1398                 7, 2, 4, 0, // or 5, 1
1399                 7, 3, 5, 0,
1400
1401                 0, 7, 2, 0, /* restore it*/
1402                 1, 7, 3, 0,
1403                 2, 7, 4, 1,
1404                 3, 7, 5, 0,
1405
1406                 2, 5, 4, 1, /* reset it */
1407                 3, 4, 5, 1,
1408
1409                 4, 1, 2, 1, /* reset it */
1410                 4, 3, 2, 1,
1411
1412                 5, 2, 3, 1, /* reset it */
1413                 5, 0, 3, 1,
1414                 
1415 #endif
1416         };
1417
1418         setup_row_indirect_group(conn8_3, ARRAY_SIZE(conn8_3));
1419
1420 #if CROSS_BAR_47_56
1421         /* for 47, 56, 57, 75, 46, 64 we need to substract another link to 
1422                6,  7,  6,  6,  7,  7 */
1423         static const u8 conn8_4[] = {
1424 //direct
1425                 4, 7, 6,
1426                 5, 6, 7, 
1427                 5, 7, 6, 
1428                 7, 5, 6,  
1429                 4, 6, 7, 
1430                 6, 4, 7, 
1431
1432 //in direct
1433                 0, 6, 1, 
1434                 0, 7, 1, 
1435                 
1436                 1, 6, 0, 
1437                 1, 7, 0, 
1438
1439                 2, 6, 3, 
1440 //              2, 7, 3, +
1441                 
1442 //              3, 6, 1, +
1443                 3, 7, 2,
1444  
1445                 6, 0, 7,
1446                 6, 1, 7, // needed for via 5
1447                         6, 1, 4, // ???
1448                 6, 2, 7,
1449                 6, 3, 7, // needed for via 5 
1450                         6, 3, 4, //???
1451                 7, 0, 6, // needed for via 4
1452                         7, 0, 5, //???
1453                 7, 1, 6,
1454                 7, 2, 6, // needed for via 4
1455                         7, 2, 5, //???
1456                 7, 3, 6,
1457         };
1458
1459         opt_broadcast_rt_group(conn8_4, ARRAY_SIZE(conn8_4));
1460
1461         static const u8 conn8_5[] = {
1462                 2, 7, 0, 
1463
1464                 3, 6, 1, 
1465         };      
1466                 
1467         opt_broadcast_rt_plus_group(conn8_5, ARRAY_SIZE(conn8_5));
1468 #endif
1469
1470
1471         
1472 /* ready to enable RT for Node 7 */
1473         enable_routing(7);      /* enable routing on node 7 (temp.) */
1474
1475         return nodes;
1476 }
1477
1478 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 6 */
1479
1480
1481 #if CONFIG_MAX_PHYSICAL_CPUS > 1
1482
1483 static unsigned setup_smp(void)
1484 {
1485         unsigned nodes;
1486
1487         print_spew("Enabling SMP settings\r\n");
1488                 
1489         nodes = setup_smp2();
1490 #if CONFIG_MAX_PHYSICAL_CPUS > 2
1491         if(nodes == 2) 
1492                 nodes = setup_smp4();
1493 #endif
1494         
1495 #if CONFIG_MAX_PHYSICAL_CPUS > 4
1496         if(nodes == 4)
1497                 nodes = setup_smp6();
1498 #endif
1499
1500 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1501         if(nodes == 6) 
1502                 nodes = setup_smp8();
1503 #endif
1504
1505 #if CONFIG_USE_PRINTK_IN_CAR
1506         printk_debug("%02x nodes initialized.\r\n", nodes);
1507 #else
1508         print_debug_hex8(nodes);
1509         print_debug(" nodes initialized.\r\n");
1510 #endif
1511         
1512         return nodes;
1513 }
1514
1515 static unsigned verify_mp_capabilities(unsigned nodes)
1516 {
1517         unsigned node, mask;
1518         
1519         mask = 0x06; /* BigMPCap */
1520
1521         for (node=0; node<nodes; node++) {
1522                 mask &= pci_read_config32(NODE_MC(node), 0xe8);
1523         }
1524         
1525         switch(mask) {
1526 #if CONFIG_MAX_PHYSICAL_CPUS > 2
1527         case 0x02: /* MPCap    */
1528                 if(nodes > 2) {
1529                         print_err("Going back to DP\r\n");
1530                         return 2;
1531                 }
1532                 break;
1533 #endif
1534         case 0x00: /* Non SMP */
1535                 if(nodes >1 ) {
1536                         print_err("Going back to UP\r\n");
1537                         return 1;
1538                 }
1539                 break;
1540         }
1541         
1542         return nodes;
1543
1544 }
1545
1546
1547 static void clear_dead_routes(unsigned nodes)
1548 {
1549         int last_row;
1550         int node, row;
1551 #if CONFIG_MAX_PHYSICAL_CPUS == 8
1552         if(nodes==8) return;/* don't touch (7,7)*/
1553 #endif
1554         last_row = nodes;
1555         if (nodes == 1) {
1556                 last_row = 0;
1557         }
1558         for(node = 7; node >= 0; node--) {
1559                 for(row = 7; row >= last_row; row--) {
1560                         fill_row(node, row, DEFAULT);
1561                 }
1562         }
1563         
1564         /* Update the local row */
1565         for( node=0; node<nodes; node++) {
1566                 uint32_t val = 0;
1567                 for(row =0; row<nodes; row++) {
1568                         val |= get_row(node, row);
1569                 }
1570                 fill_row(node, node, (((val & 0xff) | ((val >> 8) & 0xff)) << 16) | 0x0101); 
1571         }
1572 }
1573 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 1 */
1574
1575 #if CONFIG_LOGICAL_CPUS==1
1576 static unsigned verify_dualcore(unsigned nodes)
1577 {
1578         unsigned node, totalcpus, tmp;
1579
1580         totalcpus = 0;
1581         for (node=0; node<nodes; node++) {
1582                 tmp = (pci_read_config32(NODE_MC(node), 0xe8) >> 12) & 3 ;
1583                 totalcpus += (tmp + 1);
1584         }
1585
1586         return totalcpus;
1587                 
1588 }
1589 #endif
1590
1591 static void coherent_ht_finalize(unsigned nodes)
1592 {
1593         unsigned node;
1594 #if K8_REV_F_SUPPORT == 0
1595         int rev_a0;
1596 #endif
1597 #if CONFIG_LOGICAL_CPUS==1
1598         unsigned total_cpus;
1599
1600         if(read_option(CMOS_VSTART_dual_core, CMOS_VLEN_dual_core, 0) == 0) { /* dual_core */
1601                 total_cpus = verify_dualcore(nodes);
1602         }
1603         else {
1604                 total_cpus = nodes;
1605         }
1606 #endif
1607         
1608         /* set up cpu count and node count and enable Limit
1609          * Config Space Range for all available CPUs.
1610          * Also clear non coherent hypertransport bus range
1611          * registers on Hammer A0 revision.
1612          */
1613
1614         print_spew("coherent_ht_finalize\r\n");
1615 #if K8_REV_F_SUPPORT == 0
1616         rev_a0 = is_cpu_rev_a0();
1617 #endif
1618         for (node = 0; node < nodes; node++) {
1619                 device_t dev;
1620                 uint32_t val;
1621                 dev = NODE_HT(node);
1622
1623                 /* Set the Total CPU and Node count in the system */
1624                 val = pci_read_config32(dev, 0x60);
1625                 val &= (~0x000F0070);
1626 #if CONFIG_LOGICAL_CPUS==1
1627                 val |= ((total_cpus-1)<<16)|((nodes-1)<<4);
1628 #else
1629                 val |= ((nodes-1)<<16)|((nodes-1)<<4);
1630 #endif
1631                 pci_write_config32(dev, 0x60, val);
1632
1633                 /* Only respond to real cpu pci configuration cycles
1634                  * and optimize the HT settings 
1635                  */
1636                 val=pci_read_config32(dev, HT_TRANSACTION_CONTROL);
1637                 val &= ~((HTTC_BUF_REL_PRI_MASK << HTTC_BUF_REL_PRI_SHIFT) |
1638                         (HTTC_MED_PRI_BYP_CNT_MASK << HTTC_MED_PRI_BYP_CNT_SHIFT) |
1639                         (HTTC_HI_PRI_BYP_CNT_MASK << HTTC_HI_PRI_BYP_CNT_SHIFT));
1640                 val |= HTTC_LIMIT_CLDT_CFG | 
1641                         (HTTC_BUF_REL_PRI_8 << HTTC_BUF_REL_PRI_SHIFT) |
1642                         (3 << HTTC_MED_PRI_BYP_CNT_SHIFT) |
1643                         (3 << HTTC_HI_PRI_BYP_CNT_SHIFT);
1644                 pci_write_config32(dev, HT_TRANSACTION_CONTROL, val);
1645
1646 #if K8_REV_F_SUPPORT == 0
1647                 if (rev_a0) {
1648                         pci_write_config32(dev, 0x94, 0);
1649                         pci_write_config32(dev, 0xb4, 0);
1650                         pci_write_config32(dev, 0xd4, 0);
1651                 }
1652 #endif
1653         }
1654
1655         print_spew("done\r\n");
1656 }
1657
1658 static int apply_cpu_errata_fixes(unsigned nodes)
1659 {
1660         unsigned node;
1661         int needs_reset = 0;
1662         for(node = 0; node < nodes; node++) {
1663                 device_t dev;
1664                 uint32_t cmd;
1665                 dev = NODE_MC(node);
1666 #if K8_REV_F_SUPPORT == 0
1667                 if (is_cpu_pre_c0()) {
1668
1669                         /* Errata 66
1670                          * Limit the number of downstream posted requests to 1 
1671                          */
1672                         cmd = pci_read_config32(dev, 0x70);
1673                         if ((cmd & (3 << 0)) != 2) {
1674                                 cmd &= ~(3<<0);
1675                                 cmd |= (2<<0);
1676                                 pci_write_config32(dev, 0x70, cmd );
1677                                 needs_reset = 1;
1678                         }
1679                         cmd = pci_read_config32(dev, 0x7c);
1680                         if ((cmd & (3 << 4)) != 0) {
1681                                 cmd &= ~(3<<4);
1682                                 cmd |= (0<<4);
1683                                 pci_write_config32(dev, 0x7c, cmd );
1684                                 needs_reset = 1;
1685                         }
1686                         /* Clock Power/Timing Low */
1687                         cmd = pci_read_config32(dev, 0xd4);
1688                         if (cmd != 0x000D0001) {
1689                                 cmd = 0x000D0001;
1690                                 pci_write_config32(dev, 0xd4, cmd);
1691                                 needs_reset = 1; /* Needed? */
1692                         }
1693
1694                 }
1695                 else if (is_cpu_pre_d0()) { // d0 later don't need it
1696                         uint32_t cmd_ref;
1697                         /* Errata 98 
1698                          * Set Clk Ramp Hystersis to 7
1699                          * Clock Power/Timing Low
1700                          */
1701                         cmd_ref = 0x04e20707; /* Registered */
1702                         cmd = pci_read_config32(dev, 0xd4);
1703                         if(cmd != cmd_ref) {
1704                                 pci_write_config32(dev, 0xd4, cmd_ref );
1705                                 needs_reset = 1; /* Needed? */
1706                         }
1707                 }
1708 #endif
1709         }
1710         return needs_reset;
1711 }
1712
1713 static int optimize_link_read_pointers(unsigned nodes)
1714 {
1715         unsigned node;
1716         int needs_reset = 0;
1717         for(node = 0; node < nodes; node++) {
1718                 device_t f0_dev, f3_dev;
1719                 uint32_t cmd_ref, cmd;
1720                 int link;
1721                 f0_dev = NODE_HT(node);
1722                 f3_dev = NODE_MC(node);
1723                 cmd_ref = cmd = pci_read_config32(f3_dev, 0xdc);
1724                 for(link = 0; link < 3; link++) {
1725                         uint32_t link_type;
1726                         unsigned reg;
1727                         /* This works on an Athlon64 because unimplemented links return 0 */
1728                         reg = 0x98 + (link * 0x20);
1729                         link_type = pci_read_config32(f0_dev, reg);
1730                         /* Only handle coherent links */
1731                         if ((link_type & (LinkConnected | InitComplete|NonCoherent)) == 
1732                                 (LinkConnected|InitComplete)) 
1733                         {
1734                                 cmd &= ~(0xff << (link *8));
1735                                 cmd |= 0x25 << (link *8);
1736                         }
1737                 }
1738                 if (cmd != cmd_ref) {
1739                         pci_write_config32(f3_dev, 0xdc, cmd);
1740                         needs_reset = 1;
1741                 }
1742         }
1743         return needs_reset;
1744 }
1745
1746 static inline unsigned get_nodes(void)
1747 {
1748         return ((pci_read_config32(PCI_DEV(0, 0x18, 0), 0x60)>>4) & 7) + 1;
1749 }
1750
1751 static int optimize_link_coherent_ht(void)
1752 {
1753         int needs_reset = 0;
1754
1755         unsigned nodes;
1756
1757         nodes = get_nodes();
1758
1759 #if CONFIG_MAX_PHYSICAL_CPUS > 1
1760         if(nodes>1) {
1761                 needs_reset |= optimize_connection(
1762                         NODE_HT(0), 0x80 + link_to_register(link_connection(0,1)),
1763                         NODE_HT(1), 0x80 + link_to_register(link_connection(1,0)) );
1764         }
1765
1766 #if CONFIG_MAX_PHYSICAL_CPUS > 2
1767         if(nodes>2) {
1768         /* optimize physical connections - by LYH */
1769                 static const u8 opt_conn4[] = {
1770                         0,2,
1771                         1,3,
1772                         2,3,
1773                 };
1774                 needs_reset |= optimize_connection_group(opt_conn4, ARRAY_SIZE(opt_conn4));
1775         }
1776 #endif
1777
1778 #if CONFIG_MAX_PHYSICAL_CPUS > 4
1779         if(nodes>4) {
1780                 static const uint8_t opt_conn6[] ={
1781                         2, 4,
1782                         3, 5,
1783         #if !CROSS_BAR_47_56
1784                         4, 5,
1785         #endif
1786                 };
1787                 needs_reset |= optimize_connection_group(opt_conn6, ARRAY_SIZE(opt_conn6));
1788         }
1789 #endif
1790
1791 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1792         if(nodes>6) {
1793                static const uint8_t opt_conn8[] ={
1794                        4, 6,
1795         #if CROSS_BAR_47_56
1796                        4, 7,
1797                        5, 6,
1798         #endif
1799                        5, 7,
1800                        6, 7,
1801                };
1802                 needs_reset |= optimize_connection_group(opt_conn8, ARRAY_SIZE(opt_conn8));
1803         }
1804 #endif
1805
1806 #endif
1807
1808         needs_reset |= apply_cpu_errata_fixes(nodes);
1809         needs_reset |= optimize_link_read_pointers(nodes);
1810
1811         return needs_reset;
1812 }
1813
1814 #if RAMINIT_SYSINFO == 1
1815 static void setup_coherent_ht_domain(void)
1816 #else
1817 static int setup_coherent_ht_domain(void)
1818 #endif
1819 {
1820         unsigned nodes;
1821         nodes = 1;
1822
1823         enable_bsp_routing();
1824
1825 #if CONFIG_MAX_PHYSICAL_CPUS > 1
1826         nodes = setup_smp();
1827         nodes = verify_mp_capabilities(nodes);
1828         clear_dead_routes(nodes);
1829 #endif
1830
1831         if (nodes == 1) {
1832                 setup_uniprocessor();
1833         }
1834         coherent_ht_finalize(nodes);
1835
1836 #if RAMINIT_SYSINFO == 0
1837         return optimize_link_coherent_ht();
1838 #endif
1839 }
1840