1 /* coherent hypertransport initialization for AMD64
3 * written by Stefan Reinauer <stepan@openbios.org>
4 * (c) 2003-2004 by SuSE Linux AG
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)
10 * This code is licensed under GPL.
14 * This algorithm assumes a grid configuration as follows:
17 * org. : 1x1 2x1 2x2 2x3 2x4
66 #include <device/pci_def.h>
67 #include <device/pci_ids.h>
68 #include <device/hypertransport_def.h>
69 #include "arch/romcc_io.h"
72 #define enable_bsp_routing() enable_routing(0)
74 #define NODE_HT(x) PCI_DEV(0,24+x,0)
75 #define NODE_MP(x) PCI_DEV(0,24+x,1)
76 #define NODE_MC(x) PCI_DEV(0,24+x,3)
78 #define DEFAULT 0x00010101 /* default row entry */
83 #ifndef CROSS_BAR_47_56
84 #define CROSS_BAR_47_56 0
87 #ifndef TRY_HIGH_FIRST
88 #define TRY_HIGH_FIRST 0
91 #ifndef K8_HT_FREQ_1G_SUPPORT
92 #define K8_HT_FREQ_1G_SUPPORT 0
95 #ifndef K8_HT_CHECK_PENDING_LINK
96 #if CONFIG_MAX_PHYSICAL_CPUS >= 4
97 #define K8_HT_CHECK_PENDING_LINK 1
99 #define K8_HT_CHECK_PENDING_LINK 0
103 #ifndef CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED
104 #define CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED 0
108 static inline void print_linkn (const char *strval, uint8_t byteval)
112 printk_debug("%s%02x\r\n", strval, byteval);
114 print_debug(strval); print_debug_hex8(byteval); print_debug("\r\n");
119 static void disable_probes(void)
121 /* disable read/write/fill probes for uniprocessor setup
122 * they don't make sense if only one cpu is available
125 /* Hypetransport Transaction Control Register
127 * [ 0: 0] Disable read byte probe
129 * 1 = Probes not issued
130 * [ 1: 1] Disable Read Doubleword probe
132 * 1 = Probes not issued
133 * [ 2: 2] Disable write byte probes
135 * 1 = Probes not issued
136 * [ 3: 3] Disable Write Doubleword Probes
138 * 1 = Probes not issued.
139 * [10:10] Disable Fill Probe
140 * 0 = Probes issued for cache fills
141 * 1 = Probes not issued for cache fills.
146 print_spew("Disabling read/write/fill probes for UP... ");
148 val=pci_read_config32(NODE_HT(0), HT_TRANSACTION_CONTROL);
149 val |= HTTC_DIS_FILL_P | HTTC_DIS_RMT_MEM_C | HTTC_DIS_P_MEM_C |
150 HTTC_DIS_MTS | HTTC_DIS_WR_DW_P | HTTC_DIS_WR_B_P |
151 HTTC_DIS_RD_DW_P | HTTC_DIS_RD_B_P;
152 pci_write_config32(NODE_HT(0), HT_TRANSACTION_CONTROL, val);
154 print_spew("done.\r\n");
158 static void enable_routing(u8 node)
162 /* HT Initialization Control Register
164 * [ 0: 0] Routing Table Disable
165 * 0 = Packets are routed according to routing tables
166 * 1 = Packets are routed according to the default link field
167 * [ 1: 1] Request Disable (BSP should clear this)
168 * 0 = Request packets may be generated
169 * 1 = Request packets may not be generated.
170 * [ 3: 2] Default Link (Read-only)
174 * 11 = CPU on same node
176 * - Scratch bit cleared by a cold reset
177 * [ 5: 5] BIOS Reset Detect
178 * - Scratch bit cleared by a cold reset
179 * [ 6: 6] INIT Detect
180 * - Scratch bit cleared by a warm or cold reset not by an INIT
184 /* Enable routing table */
185 print_spew("Enabling routing table for node ");
186 print_spew_hex8(node);
188 val=pci_read_config32(NODE_HT(node), 0x6c);
189 val &= ~((1<<1)|(1<<0));
190 pci_write_config32(NODE_HT(node), 0x6c, val);
192 print_spew(" done.\r\n");
195 static void fill_row(u8 node, u8 row, u32 value)
197 pci_write_config32(NODE_HT(node), 0x40+(row<<2), value);
200 #if CONFIG_MAX_PHYSICAL_CPUS > 1
201 static u8 link_to_register(int ldt)
204 * [ 0: 3] Request Route
205 * [0] Route to this node
206 * [1] Route to Link 0
207 * [2] Route to Link 1
208 * [3] Route to Link 2
211 if (ldt&0x08) return 0x40;
212 if (ldt&0x04) return 0x20;
213 if (ldt&0x02) return 0x00;
215 /* we should never get here */
216 print_spew("Unknown Link\n");
220 static u32 get_row(u8 node, u8 row)
222 return pci_read_config32(NODE_HT(node), 0x40+(row<<2));
225 static int link_connection(u8 src, u8 dest)
227 return get_row(src, dest) & 0x0f;
230 static void rename_temp_node(u8 node)
234 print_spew("Renaming current temporary node to ");
235 print_spew_hex8(node);
237 val=pci_read_config32(NODE_HT(7), 0x60);
238 val &= (~7); /* clear low bits. */
239 val |= node; /* new node */
240 pci_write_config32(NODE_HT(7), 0x60, val);
242 print_spew(" done.\r\n");
244 #if K8_HT_CHECK_PENDING_LINK == 1
245 static void wait_ht_stable(uint8_t node)
248 for(linkn = 0; linkn<3; linkn++) {
252 regpos = 0x98 + 0x20 * linkn;
253 for(i = 0; i < 0xff; i++) { //wait to make sure it is done
254 reg = pci_read_config32(NODE_HT(node), regpos);
255 if ((reg & 0x10) == 0) break; // init complete
262 static int verify_connection(u8 dest)
264 /* See if we have a valid connection to dest */
267 /* Verify that the coherent hypertransport link is
268 * established and actually working by reading the
269 * remode node's vendor/device id
271 val = pci_read_config32(NODE_HT(dest),0);
272 if(val != 0x11001022)
278 static unsigned read_freq_cap(device_t dev, unsigned pos)
280 /* Handle bugs in valid hypertransport frequency reporting */
284 freq_cap = pci_read_config16(dev, pos);
285 freq_cap &= ~(1 << HT_FREQ_VENDOR); /* Ignore Vendor HT frequencies */
287 if (!is_cpu_pre_e0()) {
291 id = pci_read_config32(dev, 0);
293 /* AMD K8 Unsupported 1Ghz? */
294 if (id == (PCI_VENDOR_ID_AMD | (0x1100 << 16))) {
295 if (is_cpu_pre_e0()) {
296 freq_cap &= ~(1 << HT_FREQ_1000Mhz);
303 static int optimize_connection(device_t node1, uint8_t link1, device_t node2, uint8_t link2)
305 static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
306 static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
307 uint16_t freq_cap1, freq_cap2, freq_cap, freq_mask;
308 uint8_t width_cap1, width_cap2, width_cap, width, old_width, ln_width1, ln_width2;
309 uint8_t freq, old_freq;
311 /* Set link width and frequency */
313 /* Initially assume everything is already optimized and I don't need a reset */
316 /* Get the frequency capabilities */
317 freq_cap1 = read_freq_cap(node1, link1 + PCI_HT_CAP_HOST_FREQ_CAP);
318 freq_cap2 = read_freq_cap(node2, link2 + PCI_HT_CAP_HOST_FREQ_CAP);
320 /* Calculate the highest possible frequency */
321 freq = log2(freq_cap1 & freq_cap2);
323 /* See if I am changing the link freqency */
324 old_freq = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_FREQ);
326 needs_reset |= old_freq != freq;
327 old_freq = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_FREQ);
329 needs_reset |= old_freq != freq;
331 /* Set the Calulcated link frequency */
332 pci_write_config8(node1, link1 + PCI_HT_CAP_HOST_FREQ, freq);
333 pci_write_config8(node2, link2 + PCI_HT_CAP_HOST_FREQ, freq);
335 /* Get the width capabilities */
336 width_cap1 = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH);
337 width_cap2 = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH);
339 /* Calculate node1's input width */
340 ln_width1 = link_width_to_pow2[width_cap1 & 7];
341 ln_width2 = link_width_to_pow2[(width_cap2 >> 4) & 7];
342 if (ln_width1 > ln_width2) {
343 ln_width1 = ln_width2;
345 width = pow2_to_link_width[ln_width1];
346 /* Calculate node1's output width */
347 ln_width1 = link_width_to_pow2[(width_cap1 >> 4) & 7];
348 ln_width2 = link_width_to_pow2[width_cap2 & 7];
349 if (ln_width1 > ln_width2) {
350 ln_width1 = ln_width2;
352 width |= pow2_to_link_width[ln_width1] << 4;
354 /* See if I am changing node1's width */
355 old_width = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH + 1);
356 needs_reset |= old_width != width;
358 /* Set node1's widths */
359 pci_write_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH + 1, width);
361 // * Calculate node2's width */
362 width = ((width & 0x70) >> 4) | ((width & 0x7) << 4);
364 /* See if I am changing node2's width */
365 old_width = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH + 1);
366 needs_reset |= old_width != width;
368 /* Set node2's widths */
369 pci_write_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH + 1, width);
373 static uint8_t get_linkn_first(uint8_t byte)
375 if(byte & 0x02) { byte = 0; }
376 else if(byte & 0x04) { byte = 1; }
377 else if(byte & 0x08) { byte = 2; }
381 static uint8_t get_linkn_last(uint8_t byte)
383 if(byte & 0x02) { byte &= 0x0f; byte |= 0x00; }
384 if(byte & 0x04) { byte &= 0x0f; byte |= 0x10; }
385 if(byte & 0x08) { byte &= 0x0f; byte |= 0x20; }
389 static uint8_t get_linkn_last_count(uint8_t byte)
392 if(byte & 0x02) { byte &= 0xcf; byte |= 0x00; byte+=0x40; }
393 if(byte & 0x04) { byte &= 0xcf; byte |= 0x10; byte+=0x40; }
394 if(byte & 0x08) { byte &= 0xcf; byte |= 0x20; byte+=0x40; }
398 static void setup_row_local(u8 source, u8 row) /* source will be 7 when it is for temp use*/
403 for(linkn = 0; linkn<3; linkn++) {
406 regpos = 0x98 + 0x20 * linkn;
407 reg = pci_read_config32(NODE_HT(source), regpos);
408 if ((reg & 0x17) != 3) continue; /* it is not conherent or not connected*/
413 fill_row(source,row, val);
416 static void setup_row_direct_x(u8 temp, u8 source, u8 dest, u8 linkn)
421 val |= 1<<(linkn+1+8); /*for direct connect response route should equal to request table*/
423 if(((source &1)!=(dest &1))
425 && ( (source<4)||(source>5) ) //(6,7) (7,6) should still be here
426 //(6,5) (7,4) should be here
431 /*for CROSS_BAR_47_56 47, 56, should be here too
432 and for 47, 56, 57, 75, 46, 64 we need to substract another link to
435 val_s = get_row(temp, source);
436 val |= ((val_s>>16) - (1<<(linkn+1)))<<16;
439 fill_row(temp,dest, val );
443 static void opt_broadcast_rt(u8 source, u8 dest, u8 kickout) {
445 val = get_row(source, dest);
446 val -= link_connection(source, kickout)<<16;
447 fill_row(source, dest, val);
450 static void opt_broadcast_rt_group(const u8 *conn, int num) {
453 for(i=0; i<num; i+=3) {
454 opt_broadcast_rt(conn[i], conn[i+1],conn[i+2]);
457 static void opt_broadcast_rt_plus(u8 source, u8 dest, u8 kickout) {
459 val = get_row(source, dest);
460 val += link_connection(source, kickout)<<16;
461 fill_row(source, dest, val);
464 static void opt_broadcast_rt_plus_group(const u8 *conn, int num) {
467 for(i=0; i<num; i+=3) {
468 opt_broadcast_rt_plus(conn[i], conn[i+1],conn[i+2]);
473 static void setup_row_direct(u8 source, u8 dest, u8 linkn){
474 setup_row_direct_x(source, source, dest, linkn);
477 static void setup_remote_row_direct(u8 source, u8 dest, u8 linkn){
478 setup_row_direct_x(7, source, dest, linkn);
481 static void setup_temp_row(u8 source, u8 dest)
483 /* copy val from (source, dest) to (source,7) */
484 fill_row(source,7,get_row(source,dest));
487 static void clear_temp_row(u8 source)
489 fill_row(source, 7, DEFAULT);
492 static void setup_remote_node(u8 node)
494 static const uint8_t pci_reg[] = {
495 0x44, 0x4c, 0x54, 0x5c, 0x64, 0x6c, 0x74, 0x7c,
496 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78,
497 0x84, 0x8c, 0x94, 0x9c, 0xa4, 0xac, 0xb4, 0xbc,
498 0x80, 0x88, 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8,
499 0xc4, 0xcc, 0xd4, 0xdc,
500 0xc0, 0xc8, 0xd0, 0xd8,
501 0xe0, 0xe4, 0xe8, 0xec,
505 print_spew("setup_remote_node: ");
507 /* copy the default resource map from node 0 */
508 for(i = 0; i < sizeof(pci_reg)/sizeof(pci_reg[0]); i++) {
512 value = pci_read_config32(NODE_MP(0), reg);
513 pci_write_config32(NODE_MP(7), reg, value);
516 print_spew("done\r\n");
519 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 1*/
522 #if CONFIG_MAX_PHYSICAL_CPUS > 2
524 static void setup_row_indirect_x(u8 temp, u8 source, u8 dest)
526 static void setup_row_indirect_x(u8 temp, u8 source, u8 dest, u8 gateway, u8 diff)
529 /*for indirect connection, we need to compute the val from val_s(source, source), and val_g(source, gateway) */
536 gateway = source + 2;
538 gateway = source - 2;
541 val_s = get_row(temp, source);
542 val = get_row(temp, gateway);
549 diff = ((source&1)!=(dest &1));
552 if(diff && (val_s!=(val&0xff)) ) { /* use another connect as response*/
554 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
556 /* Some node have two links left
557 * don't worry we only have (2, (3 as source need to handle
560 byte = get_linkn_last_count(byte);
561 if((byte>>2)>1) { /* make sure not the corner*/
563 val_s-=link_connection(temp, source-2); /* -down*/
568 val_s-=link_connection(temp, 6); // for 7,2 via 5
569 } else if (source==6){
570 val_s-=link_connection(temp, 7); // for 6,3 via 4
573 if (source < gateway) { // for 5, 4 via 7
574 val_s-=link_connection(temp, source-2);
577 val_s-=link_connection(temp, source+2); /* -up*/
585 if(diff) { /* cross rung?*/
589 val_s = get_row(temp, source);
590 val |= ((val_s>>16) - link_connection(temp, gateway))<<16;
593 fill_row(temp, dest, val);
598 static void setup_row_indirect(u8 source, u8 dest)
600 setup_row_indirect_x(source, source, dest);
603 static void setup_row_indirect(u8 source, u8 dest, u8 gateway, u8 diff)
605 setup_row_indirect_x(source, source, dest, gateway, diff);
609 static void setup_row_indirect_group(const u8 *conn, int num)
614 for(i=0; i<num; i+=2) {
615 setup_row_indirect(conn[i], conn[i+1]);
617 for(i=0; i<num; i+=4) {
618 setup_row_indirect(conn[i], conn[i+1],conn[i+2], conn[i+3]);
625 static void setup_remote_row_indirect(u8 source, u8 dest)
627 setup_row_indirect_x(7, source, dest);
630 static void setup_remote_row_indirect(u8 source, u8 dest, u8 gateway, u8 diff)
632 setup_row_indirect_x(7, source, dest, gateway, diff);
636 static void setup_remote_row_indirect_group(const u8 *conn, int num)
641 for(i=0; i<num; i+=2) {
642 setup_remote_row_indirect(conn[i], conn[i+1]);
644 for(i=0; i<num; i+=4) {
645 setup_remote_row_indirect(conn[i], conn[i+1],conn[i+2], conn[i+3]);
650 #endif /*CONFIG_MAX_PHYSICAL_CPUS > 2*/
653 static void setup_uniprocessor(void)
655 print_spew("Enabling UP settings\r\n");
656 #if CONFIG_LOGICAL_CPUS==1
657 unsigned tmp = (pci_read_config32(NODE_MC(0), 0xe8) >> 12) & 3;
663 struct setup_smp_result {
668 #if CONFIG_MAX_PHYSICAL_CPUS > 2
669 static int optimize_connection_group(const u8 *opt_conn, int num) {
672 for(i=0; i<num; i+=2) {
673 needs_reset = optimize_connection(
674 NODE_HT(opt_conn[i]), 0x80 + link_to_register(link_connection(opt_conn[i],opt_conn[i+1])),
675 NODE_HT(opt_conn[i+1]), 0x80 + link_to_register(link_connection(opt_conn[i+1],opt_conn[i])) );
681 #if CONFIG_MAX_PHYSICAL_CPUS > 1
682 static struct setup_smp_result setup_smp2(void)
684 struct setup_smp_result result;
688 result.needs_reset = 0;
690 setup_row_local(0, 0); /* it will update the broadcast RT*/
693 byte = (val>>16) & 0xfe;
694 if(byte<0x2) { /* no coherent connection so get out.*/
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 */
703 byte = get_linkn_first(byte); /*Min Link to node1 --- according to AMD*/
705 print_linkn("(0,1) link=", byte);
706 setup_row_direct(0,1, byte);
707 setup_temp_row(0, 1);
709 verify_connection(7);
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);
718 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 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*/
724 byte = (val>>16) & 0xfe;
725 #if TRY_HIGH_FIRST == 1
726 byte = get_linkn_first(byte); /* Min link to Node1 */
728 byte = get_linkn_last(byte); /* Max link to Node1*/
730 print_linkn("\t-->(0,1) link=", byte);
731 setup_row_direct(0,1, byte);
732 setup_temp_row(0, 1);
734 verify_connection(7);
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);
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 */
749 /*don't need and it is done by clear_dead_links */
753 result.needs_reset |= optimize_connection(
754 NODE_HT(0), 0x80 + link_to_register(link_connection(0,1)),
755 NODE_HT(1), 0x80 + link_to_register(link_connection(1,0)) );
759 #endif /*CONFIG_MAX_PHYSICAL_CPUS > 1 */
761 #if CONFIG_MAX_PHYSICAL_CPUS > 2
763 static struct setup_smp_result setup_smp4(int needs_reset)
765 struct setup_smp_result result;
770 result.needs_reset = needs_reset;
772 /* Setup and check temporary connection from Node 0 to Node 2 */
774 byte = ((val>>16) & 0xfe) - link_connection(0,1);
775 byte = get_linkn_last_count(byte);
777 if((byte>>2)==0) { /* We should have two coherent for 4p and above*/
782 byte &= 3; /* bit [3,2] is count-1*/
783 print_linkn("(0,2) link=", byte);
784 setup_row_direct(0, 2, byte); /*(0,2) direct link done*/
786 /* We found 3 nodes so far. Now setup a temporary
787 * connection from node 0 to node 3 via node 1
789 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
790 /* here should setup_row_direct(1,3) at first, before that we should find the link in node 1 to 3*/
792 byte = ((val>>16) & 0xfe) - link_connection(1,0);
793 byte = get_linkn_first(byte);
794 print_linkn("(1,3) link=", byte);
795 setup_row_direct(1,3,byte); /* (1, 3) direct link done*/
797 /* We found 4 nodes so far. Now setup all nodes for 4p */
798 // We need to make sure 0,2 and 1,3 link is set already
800 static const u8 conn4_1[] = {
805 static const u8 conn4_1[] = {
811 setup_row_indirect_group(conn4_1, sizeof(conn4_1)/sizeof(conn4_1[0]));
814 verify_connection(7);
815 val = pci_read_config32(NODE_HT(7), 0x6c);
816 byte = (val>>2) & 0x3; /* get default link on 7 to 0*/
817 print_linkn("(2,0) link=", byte);
819 setup_row_local(7,2);
820 setup_remote_row_direct(2, 0, byte); /* node 2 to node 0 direct link done */
821 setup_remote_node(2); /* Setup the regs on the remote node */
823 rename_temp_node(2); /* Rename Node 7 to Node 2 */
824 enable_routing(2); /* Enable routing on Node 2 */
828 verify_connection(7);
830 val = pci_read_config32(NODE_HT(7), 0x6c);
831 byte = (val>>2) & 0x3; /* get default link on 7 to 1*/
832 print_linkn("(3,1) link=", byte);
834 setup_row_local(7,3);
835 setup_remote_row_direct(3, 1, byte); /* node 3 to node 1 direct link done */
836 setup_remote_node(3); /* Setup the regs on the remote node */
838 /* We need to init link between 2, and 3 direct link */
840 byte = ((val>>16) & 0xfe) - link_connection(2,0);
841 byte = get_linkn_last_count(byte);
842 print_linkn("(2,3) link=", byte & 3);
844 setup_row_direct(2,3, byte & 0x3);
847 verify_connection(7); /* to 3*/
849 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
850 /* We need to find out which link is to node3 */
851 if((byte>>2)==2) { /* one to node3, one to node0, one to node4*/
853 if((val>>16) == 1) { /* that link is to node4, because via node1 it has been set, recompute it*/
855 byte = ((val>>16) & 0xfe) - link_connection(2,0);
856 byte = get_linkn_first(byte);
857 print_linkn("\t-->(2,3) link=", byte);
858 setup_row_direct(2,3,byte);
860 verify_connection(7); /* to 3*/
865 val = pci_read_config32(NODE_HT(7), 0x6c);
866 byte = (val>>2) & 0x3; /* get default link on 7 to 2*/
867 print_linkn("(3,2) link=", byte);
868 setup_remote_row_direct(3,2, byte);
870 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
871 /* set link from 3 to 5 before enable it*/
873 byte = ((val>>16) & 0xfe) - link_connection(7,2) - link_connection(7,1);
874 byte = get_linkn_last_count(byte);
875 if((byte>>2)==1) { /* We should have three coherent links on node 3 for 6p and above*/
876 byte &= 3; /*bit [3,2] is count-2*/
877 print_linkn("(3,5) link=", byte);
878 setup_remote_row_direct(3, 5, byte);
882 byte = ((val>>16) & 0xfe) - link_connection(2,3) - link_connection(2,0);
883 byte = get_linkn_last_count(byte);
885 if((byte>>2)==1) { /* We should have three coherent link on node 2 for 6p and above*/
886 byte &= 3; /* bit [3,2] is count-2*/
887 print_linkn("(2,4) link=", byte);
888 setup_row_direct(2, 4, byte);
892 //Beside 3, 1 is set, We need to make sure 3, 5 is set already in case has three link in 3
894 static const u8 conn4_3[] = {
898 static const u8 conn4_3[] = {
902 setup_remote_row_indirect_group(conn4_3, sizeof(conn4_3)/sizeof(conn4_3[0]));
904 /* ready to enable RT for Node 3 */
906 enable_routing(3); /* enable routing on node 3 (temp.) */
908 // beside 2, 0 is set, We need to make sure 2, 4 link is set already in case has three link in 2
910 static const u8 conn4_2[] = {
914 static const u8 conn4_2[] = {
918 setup_row_indirect_group(conn4_2, sizeof(conn4_2)/sizeof(conn4_2[0]));
921 /*We need to do sth to reverse work for setup_temp_row (0,1) (1,3) */
922 /* it will be done by clear_dead_links */
927 /* optimize physical connections - by LYH */
928 static const u8 opt_conn4[] = {
934 result.needs_reset |= optimize_connection_group(opt_conn4, sizeof(opt_conn4)/sizeof(opt_conn4[0]));
940 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 2 */
942 #if CONFIG_MAX_PHYSICAL_CPUS > 4
944 static struct setup_smp_result setup_smp6(int needs_reset)
946 struct setup_smp_result result;
951 result.needs_reset = needs_reset;
953 /* Setup and check temporary connection from Node 0 to Node 4 through 2*/
955 byte = ((val>>16) & 0xfe) - link_connection(2,3) - link_connection(2,0);
956 byte = get_linkn_last_count(byte);
958 if((byte>>2)==0) { /* We should have three coherent link on node 2 for 6p and above*/
963 /* Setup and check temporary connection from Node 0 to Node 5 through 1, 3*/
964 /* set link from 3 to 5 before enable it*/
966 byte = ((val>>16) & 0xfe) - link_connection(3,2) - link_connection(3,1);
967 byte = get_linkn_last_count(byte);
968 if((byte>>2)==0) { /* We should have three coherent links on node 3 for 6p and above*/
973 /* We found 6 nodes so far. Now setup all nodes for 6p */
974 #warning "FIXME we need to find out the correct gateway for 6p"
975 static const u8 conn6_1[] = {
993 setup_row_indirect_group(conn6_1, sizeof(conn6_1)/sizeof(conn6_1[0]));
995 for(byte=0; byte<4; byte+=2) {
996 setup_temp_row(byte,byte+2);
998 verify_connection(7);
999 val = pci_read_config32(NODE_HT(7), 0x6c);
1000 byte = (val>>2) & 0x3; /*get default link on 7 to 2*/
1001 print_linkn("(4,2) link=", byte);
1003 setup_row_local(7,4);
1004 setup_remote_row_direct(4, 2, byte);
1005 setup_remote_node(4); /* Setup the regs on the remote node */
1007 /* Set indirect connection to 0, to 3 */
1008 //we only need to set 4,0 here
1009 static const u8 conn6_2[] = {
1010 #if !CROSS_BAR_47_56
1017 setup_remote_row_indirect_group(conn6_2, sizeof(conn6_2)/sizeof(conn6_2[0]));
1019 rename_temp_node(4);
1022 setup_temp_row(0,1);
1023 for(byte=0; byte<4; byte+=2) {
1024 setup_temp_row(byte+1,byte+3);
1026 verify_connection(7);
1028 val = pci_read_config32(NODE_HT(7), 0x6c);
1029 byte = (val>>2) & 0x3; /* get default link on 7 to 3*/
1030 print_linkn("(5,3) link=", byte);
1031 setup_row_local(7,5);
1032 setup_remote_row_direct(5, 3, byte);
1033 setup_remote_node(5); /* Setup the regs on the remote node */
1035 #if !CROSS_BAR_47_56
1036 /* We need to init link between 4, and 5 direct link */
1038 byte = ((val>>16) & 0xfe) - link_connection(4,2);
1039 byte = get_linkn_last_count(byte);
1040 print_linkn("(4,5) link=", byte & 3);
1042 setup_row_direct(4,5, byte & 0x3);
1043 setup_temp_row(0,2);
1044 setup_temp_row(2,4);
1045 setup_temp_row(4,5);
1046 verify_connection(7); /* to 5*/
1048 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1049 /* We need to find out which link is to node5 */
1051 if((byte>>2)==2) { /* one to node5, one to node2, one to node6*/
1053 if((val>>16) == 1) { /* that link is to node6, because via node 3 node 5 has been set*/
1055 byte = ((val>>16) & 0xfe) - link_connection(4,2);
1056 byte = get_linkn_first(byte);
1057 print_linkn("\t-->(4,5) link=", byte);
1058 setup_row_direct(4,5,byte);
1059 setup_temp_row(4,5);
1060 verify_connection(7); /* to 5*/
1065 val = pci_read_config32(NODE_HT(7), 0x6c);
1066 byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
1067 print_linkn("(5,4) link=", byte);
1068 setup_remote_row_direct(5,4, byte);
1072 byte = ((val>>16) & 0xfe) - link_connection(7,4) - link_connection(7,3);
1073 byte = get_linkn_last_count(byte);
1074 if((byte>>2)==1) { /* We should have three coherent links on node 5 for 6p and above*/
1075 byte &= 3; /*bit [3,2] is count-2*/
1076 print_linkn("(5,7) link=", byte);
1077 setup_remote_row_direct(5, 7, byte);
1082 byte = ((val>>16) & 0xfe) - link_connection(4,5) - link_connection(4,2);
1083 byte = get_linkn_last_count(byte);
1085 if((byte>>2)==1) { /* We should have three coherent link on node 4 for 6p and above*/
1086 byte &= 3; /* bit [3,2] is count-2*/
1087 print_linkn("(4,6) link=", byte);
1088 setup_row_direct(4, 6, byte);
1093 //We need to set 5,0 here only, We need to set up 5, 7 to make 5,0
1094 /* Set indirect connection to 0, to 3 for indirect we will use clockwise routing */
1095 static const u8 conn6_3[] = {
1096 #if !CROSS_BAR_47_56
1103 setup_remote_row_indirect_group(conn6_3, sizeof(conn6_3)/sizeof(conn6_3[0]));
1105 /* ready to enable RT for 5 */
1106 rename_temp_node(5);
1107 enable_routing(5); /* enable routing on node 5 (temp.) */
1109 static const u8 conn6_4[] = {
1110 #if !CROSS_BAR_47_56
1129 setup_row_indirect_group(conn6_4, sizeof(conn6_4)/sizeof(conn6_4[0]));
1132 /* We need to do sth about reverse about setup_temp_row (0,1), (2,4), (1, 3), (3,5)
1133 * It will be done by clear_dead_links
1135 for(byte=0; byte<4; byte++) {
1136 clear_temp_row(byte);
1140 /* optimize physical connections - by LYH */
1141 static const uint8_t opt_conn6[] ={
1144 #if !CROSS_BAR_47_56
1148 result.needs_reset |= optimize_connection_group(opt_conn6, sizeof(opt_conn6)/sizeof(opt_conn6[0]));
1154 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 4 */
1156 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1158 static struct setup_smp_result setup_smp8(int needs_reset)
1160 struct setup_smp_result result;
1165 result.needs_reset = needs_reset;
1167 /* Setup and check temporary connection from Node 0 to Node 6 via 2 and 4 to 7 */
1170 byte = ((val>>16) & 0xfe) - link_connection(4,2);
1172 byte = ((val>>16) & 0xfe) - link_connection(4,5) - link_connection(4,2);
1173 byte = get_linkn_last_count(byte); /* Max link to 6*/
1174 if((byte>>2)==0) { /* We should have two or three coherent links on node 4 for 8p*/
1181 byte = get_linkn_last_count(byte); /* Max link to 6*/
1182 if((byte>>2)<2) { /* We should have two or three coherent links on node 4 for 8p*/
1186 #if TRY_HIGH_FIRST == 1
1187 byte = ((val>>16) & 0xfe) - link_connection(4,2);
1188 byte = get_linkn_first(byte); /*Min link to 6*/
1190 byte &= 3; /* bit [3,2] is count-1 or 2*/
1192 print_linkn("(4,6) link=", byte);
1193 setup_row_direct(4, 6, byte);
1196 #if !CROSS_BAR_47_56
1197 /* Setup and check temporary connection from Node 0 to Node 7 through 1, 3, 5*/
1199 byte = ((val>>16) & 0xfe) - link_connection(5,4) - link_connection(5,3);
1200 byte = get_linkn_last_count(byte);
1201 if((byte>>2)==0) { /* We should have three coherent links on node 5 for 6p and above*/
1207 /* We found 8 nodes so far. Now setup all nodes for 8p */
1208 static const u8 conn8_1[] = {
1209 #if !CROSS_BAR_47_56
1231 setup_row_indirect_group(conn8_1,sizeof(conn8_1)/sizeof(conn8_1[0]));
1233 for(byte=0; byte<6; byte+=2) {
1234 setup_temp_row(byte,byte+2);
1236 verify_connection(7);
1237 val = pci_read_config32(NODE_HT(7), 0x6c);
1238 byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
1239 print_linkn("(6,4) link=", byte);
1241 setup_row_local(7,6);
1242 setup_remote_row_direct(6, 4, byte);
1243 setup_remote_node(6); /* Setup the regs on the remote node */
1244 /* Set indirect connection to 0, to 3 */
1245 #warning "FIXME we need to find out the correct gateway for 8p"
1246 static const u8 conn8_2[] = {
1247 #if !CROSS_BAR_47_56
1254 setup_remote_row_indirect_group(conn8_2, sizeof(conn8_2)/sizeof(conn8_2[0]));
1258 /* here init 5, 6 */
1259 /* Setup and check temporary connection from Node 0 to Node 5 through 1, 3, 5*/
1261 byte = ((val>>16) & 0xfe) - link_connection(5,3);
1262 #if TRY_HIGH_FIRST == 1
1263 byte = get_linkn_first(byte);
1265 byte = get_linkn_last(byte);
1267 print_linkn("(5,6) link=", byte);
1268 setup_row_direct(5, 6, byte);
1270 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
1271 for(byte=0; byte<4; byte+=2) {
1272 setup_temp_row(byte+1,byte+3);
1274 setup_temp_row(5,6);
1276 verify_connection(7);
1278 val = get_row(7,6); // to chect it if it is node6 before renaming
1279 if( (val>>16) == 1) { // it is real node 7 so swap it
1280 /* We need to recompute link to 6 */
1282 byte = ((val>>16) & 0xfe) - link_connection(5,3);
1283 #if TRY_HIGH_FIRST == 1
1284 byte = get_linkn_first(byte);
1286 byte = get_linkn_last(byte);
1288 print_linkn("\t-->(5,6) link=", byte);
1289 setup_row_direct(5, 6, byte);
1291 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
1292 for(byte=0; byte<4; byte+=2) {
1293 setup_temp_row(byte+1,byte+3);
1296 setup_temp_row(5,6);
1298 verify_connection(7);
1300 val = pci_read_config32(NODE_HT(7), 0x6c);
1301 byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
1302 print_linkn("(6,5) link=", byte);
1303 setup_remote_row_direct(6, 5, byte);
1304 /*Till now 56, 65 done */
1307 rename_temp_node(6);
1310 #if !CROSS_BAR_47_56
1311 setup_temp_row(0,1);
1312 for(byte=0; byte<6; byte+=2) {
1313 setup_temp_row(byte+1,byte+3);
1316 verify_connection(7);
1318 val = pci_read_config32(NODE_HT(7), 0x6c);
1319 byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
1320 print_linkn("(7,5) link=", byte);
1321 setup_row_local(7,7);
1322 setup_remote_row_direct(7, 5, byte);
1326 byte = ((val>>16) & 0xfe) - link_connection(4,2) - link_connection(4,6);
1327 byte = get_linkn_first(byte);
1328 print_linkn("(4,7) link=", byte);
1329 setup_row_direct(4, 7, byte);
1331 /* Setup and check temporary connection from Node 0 to Node 7 through 2, and 4*/
1332 for(byte=0; byte<4; byte+=2) {
1333 setup_temp_row(byte,byte+2);
1336 verify_connection(7);
1338 val = pci_read_config32(NODE_HT(7), 0x6c);
1339 byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
1340 print_linkn("(7,4) link=", byte);
1341 setup_row_local(7,7);
1342 setup_remote_row_direct(7, 4, byte);
1343 /* till now 4-7, 7-4 done. */
1345 setup_remote_node(7); /* Setup the regs on the remote node */
1348 /* here init 5, 7 */
1349 /* Setup and check temporary connection from Node 0 to Node 5 through 1, 3, 5*/
1351 byte = ((val>>16) & 0xfe) - link_connection(5,3) - link_connection(5,6);
1352 byte = get_linkn_first(byte);
1353 print_linkn("(5,7) link=", byte);
1354 setup_row_direct(5, 7, byte);
1356 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
1357 for(byte=0; byte<4; byte+=2) {
1358 setup_temp_row(byte+1,byte+3);
1361 verify_connection(7);
1363 val = pci_read_config32(NODE_HT(7), 0x6c);
1364 byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
1365 print_linkn("(7,5) link=", byte);
1366 setup_remote_row_direct(7, 5, byte);
1367 /*Till now 57, 75 done */
1371 /* We need to init link between 6, and 7 direct link */
1373 #if !CROSS_BAR_47_56
1374 byte = ((val>>16) & 0xfe) - link_connection(6,4);
1376 byte = ((val>>16) & 0xfe) - link_connection(6,4) - link_connection(6,5);
1378 byte = get_linkn_first(byte);
1379 print_linkn("(6,7) link=", byte);
1380 setup_row_direct(6,7, byte);
1383 #if !CROSS_BAR_47_56
1384 byte = ((val>>16) & 0xfe) - link_connection(7,5);
1386 byte = ((val>>16) & 0xfe) - link_connection(7,5) - link_connection(7,4);
1388 byte = get_linkn_first(byte);
1389 print_linkn("(7,6) link=", byte);
1390 setup_row_direct(7,6, byte);
1392 /* Set indirect connection to 0, to 3 for indirect we will use clockwise routing */
1393 static const u8 conn8_3[] = {
1394 #if !CROSS_BAR_47_56
1395 0, 7, /* restore it*/
1417 6, 1, 5, 0, // or 4, 1
1419 6, 3, 5, 0, // or 4, 1
1421 7, 0, 4, 0, // or 5, 1
1423 7, 2, 4, 0, // or 5, 1
1426 0, 7, 2, 0, /* restore it*/
1431 2, 5, 4, 1, /* reset it */
1434 4, 1, 2, 1, /* reset it */
1437 5, 2, 3, 1, /* reset it */
1443 setup_row_indirect_group(conn8_3, sizeof(conn8_3)/sizeof(conn8_3[0]));
1446 /* for 47, 56, 57, 75, 46, 64 we need to substract another link to
1448 static const u8 conn8_4[] = {
1471 6, 1, 7, // needed for via 5
1474 6, 3, 7, // needed for via 5
1476 7, 0, 6, // needed for via 4
1479 7, 2, 6, // needed for via 4
1484 opt_broadcast_rt_group(conn8_4, sizeof(conn8_4)/sizeof(conn8_4[0]));
1486 static const u8 conn8_5[] = {
1492 opt_broadcast_rt_plus_group(conn8_5, sizeof(conn8_5)/sizeof(conn8_5[0]));
1497 /* ready to enable RT for Node 7 */
1498 enable_routing(7); /* enable routing on node 7 (temp.) */
1500 static const uint8_t opt_conn8[] ={
1509 /* optimize physical connections - by LYH */
1510 result.needs_reset |= optimize_connection_group(opt_conn8, sizeof(opt_conn8)/sizeof(opt_conn8[0]));
1515 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 6 */
1518 #if CONFIG_MAX_PHYSICAL_CPUS > 1
1520 static struct setup_smp_result setup_smp(void)
1522 struct setup_smp_result result;
1524 print_spew("Enabling SMP settings\r\n");
1526 result = setup_smp2();
1527 #if CONFIG_MAX_PHYSICAL_CPUS > 2
1528 if(result.nodes == 2)
1529 result = setup_smp4(result.needs_reset);
1532 #if CONFIG_MAX_PHYSICAL_CPUS > 4
1533 if(result.nodes == 4)
1534 result = setup_smp6(result.needs_reset);
1537 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1538 if(result.nodes == 6)
1539 result = setup_smp8(result.needs_reset);
1543 printk_debug("%02x nodes initialized.\r\n", result.nodes);
1545 print_debug_hex8(result.nodes);
1546 print_debug(" nodes initialized.\r\n");
1552 static unsigned verify_mp_capabilities(unsigned nodes)
1554 unsigned node, mask;
1556 mask = 0x06; /* BigMPCap */
1558 for (node=0; node<nodes; node++) {
1559 mask &= pci_read_config32(NODE_MC(node), 0xe8);
1563 #if CONFIG_MAX_PHYSICAL_CPUS > 2
1564 case 0x02: /* MPCap */
1566 print_err("Going back to DP\r\n");
1571 case 0x00: /* Non SMP */
1573 print_err("Going back to UP\r\n");
1584 static void clear_dead_routes(unsigned nodes)
1588 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1589 if(nodes==8) return;/* don't touch (7,7)*/
1595 for(node = 7; node >= 0; node--) {
1596 for(row = 7; row >= last_row; row--) {
1597 fill_row(node, row, DEFAULT);
1601 /* Update the local row */
1602 for( node=0; node<nodes; node++) {
1604 for(row =0; row<nodes; row++) {
1605 val |= get_row(node, row);
1607 fill_row(node, node, (((val & 0xff) | ((val >> 8) & 0xff)) << 16) | 0x0101);
1610 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 1 */
1612 static unsigned count_cpus(unsigned nodes)
1614 #if CONFIG_LOGICAL_CPUS==1
1615 unsigned node, totalcpus, tmp;
1618 for (node=0; node<nodes; node++) {
1619 tmp = (pci_read_config32(NODE_MC(node), 0xe8) >> 12) & 3 ;
1620 totalcpus += (tmp + 1);
1630 static void coherent_ht_finalize(unsigned nodes)
1632 unsigned total_cpus;
1633 unsigned cpu_node_count;
1636 total_cpus = count_cpus(nodes);
1637 cpu_node_count = ((total_cpus -1)<<16)|((nodes - 1) << 4);
1639 /* set up cpu count and node count and enable Limit
1640 * Config Space Range for all available CPUs.
1641 * Also clear non coherent hypertransport bus range
1642 * registers on Hammer A0 revision.
1645 print_spew("coherent_ht_finalize\r\n");
1646 rev_a0 = is_cpu_rev_a0();
1647 for (node = 0; node < nodes; node++) {
1650 dev = NODE_HT(node);
1652 /* Set the Total CPU and Node count in the system */
1653 val = pci_read_config32(dev, 0x60);
1654 val &= (~0x000F0070);
1655 val |= cpu_node_count;
1656 pci_write_config32(dev, 0x60, val);
1658 /* Only respond to real cpu pci configuration cycles
1659 * and optimize the HT settings
1661 val=pci_read_config32(dev, HT_TRANSACTION_CONTROL);
1662 val &= ~((HTTC_BUF_REL_PRI_MASK << HTTC_BUF_REL_PRI_SHIFT) |
1663 (HTTC_MED_PRI_BYP_CNT_MASK << HTTC_MED_PRI_BYP_CNT_SHIFT) |
1664 (HTTC_HI_PRI_BYP_CNT_MASK << HTTC_HI_PRI_BYP_CNT_SHIFT));
1665 val |= HTTC_LIMIT_CLDT_CFG |
1666 (HTTC_BUF_REL_PRI_8 << HTTC_BUF_REL_PRI_SHIFT) |
1667 (3 << HTTC_MED_PRI_BYP_CNT_SHIFT) |
1668 (3 << HTTC_HI_PRI_BYP_CNT_SHIFT);
1669 pci_write_config32(dev, HT_TRANSACTION_CONTROL, val);
1672 pci_write_config32(dev, 0x94, 0);
1673 pci_write_config32(dev, 0xb4, 0);
1674 pci_write_config32(dev, 0xd4, 0);
1678 print_spew("done\r\n");
1681 static int apply_cpu_errata_fixes(unsigned nodes, int needs_reset)
1684 for(node = 0; node < nodes; node++) {
1687 dev = NODE_MC(node);
1688 if (is_cpu_pre_c0()) {
1691 * Limit the number of downstream posted requests to 1
1693 cmd = pci_read_config32(dev, 0x70);
1694 if ((cmd & (3 << 0)) != 2) {
1697 pci_write_config32(dev, 0x70, cmd );
1700 cmd = pci_read_config32(dev, 0x7c);
1701 if ((cmd & (3 << 4)) != 0) {
1704 pci_write_config32(dev, 0x7c, cmd );
1707 /* Clock Power/Timing Low */
1708 cmd = pci_read_config32(dev, 0xd4);
1709 if (cmd != 0x000D0001) {
1711 pci_write_config32(dev, 0xd4, cmd);
1712 needs_reset = 1; /* Needed? */
1716 else if (is_cpu_pre_d0()) { // d0 later don't need it
1719 * Set Clk Ramp Hystersis to 7
1720 * Clock Power/Timing Low
1722 cmd_ref = 0x04e20707; /* Registered */
1723 cmd = pci_read_config32(dev, 0xd4);
1724 if(cmd != cmd_ref) {
1725 pci_write_config32(dev, 0xd4, cmd_ref );
1726 needs_reset = 1; /* Needed? */
1733 static int optimize_link_read_pointers(unsigned nodes, int needs_reset)
1736 for(node = 0; node < nodes; node++) {
1737 device_t f0_dev, f3_dev;
1738 uint32_t cmd_ref, cmd;
1740 f0_dev = NODE_HT(node);
1741 f3_dev = NODE_MC(node);
1742 cmd_ref = cmd = pci_read_config32(f3_dev, 0xdc);
1743 for(link = 0; link < 3; link++) {
1746 /* This works on an Athlon64 because unimplemented links return 0 */
1747 reg = 0x98 + (link * 0x20);
1748 link_type = pci_read_config32(f0_dev, reg);
1749 /* Only handle coherent links */
1750 if ((link_type & (LinkConnected | InitComplete|NonCoherent)) ==
1751 (LinkConnected|InitComplete))
1753 cmd &= ~(0xff << (link *8));
1754 cmd |= 0x25 << (link *8);
1757 if (cmd != cmd_ref) {
1758 pci_write_config32(f3_dev, 0xdc, cmd);
1765 static void startup_other_cores(unsigned nodes)
1768 for(node = 0; node < nodes; node++) {
1771 dev = NODE_MC(node);
1772 siblings = (pci_read_config32(dev, 0xe8) >> 12) & 0x3;
1777 /* Redirect all MC4 accesses and error logging to core0 */
1778 val = pci_read_config32(dev, 0x44);
1779 val |= (1 << 27); //NbMcaToMstCpuEn bit
1780 pci_write_config32(dev, 0x44, val);
1782 dev_f0 = NODE_HT(node);
1783 /* Enable extended apic id's and second core */
1784 val = pci_read_config32(dev_f0, 0x68);
1785 val |= (1 << 18) | (1 << 17) | ( 1 << 5);
1786 pci_write_config32(dev_f0, 0x68, val);
1792 static int setup_coherent_ht_domain(void)
1794 struct setup_smp_result result;
1796 result.needs_reset = 0;
1798 #if K8_HT_CHECK_PENDING_LINK == 1
1802 enable_bsp_routing();
1804 #if CONFIG_MAX_PHYSICAL_CPUS > 1
1805 result = setup_smp();
1807 result.nodes = verify_mp_capabilities(result.nodes);
1808 clear_dead_routes(result.nodes);
1809 if (result.nodes == 1) {
1810 setup_uniprocessor();
1812 coherent_ht_finalize(result.nodes);
1813 startup_other_cores(result.nodes);
1814 result.needs_reset = apply_cpu_errata_fixes(result.nodes, result.needs_reset);
1815 result.needs_reset = optimize_link_read_pointers(result.nodes, result.needs_reset);
1816 return result.needs_reset;