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 freq_cap &= ~(1 << HT_FREQ_1000Mhz);
301 static int optimize_connection(device_t node1, uint8_t link1, device_t node2, uint8_t link2)
303 static const uint8_t link_width_to_pow2[]= { 3, 4, 0, 5, 1, 2, 0, 0 };
304 static const uint8_t pow2_to_link_width[] = { 0x7, 4, 5, 0, 1, 3 };
305 uint16_t freq_cap1, freq_cap2, freq_cap, freq_mask;
306 uint8_t width_cap1, width_cap2, width_cap, width, old_width, ln_width1, ln_width2;
307 uint8_t freq, old_freq;
309 /* Set link width and frequency */
311 /* Initially assume everything is already optimized and I don't need a reset */
314 /* Get the frequency capabilities */
315 freq_cap1 = read_freq_cap(node1, link1 + PCI_HT_CAP_HOST_FREQ_CAP);
316 freq_cap2 = read_freq_cap(node2, link2 + PCI_HT_CAP_HOST_FREQ_CAP);
318 /* Calculate the highest possible frequency */
319 freq = log2(freq_cap1 & freq_cap2);
321 /* See if I am changing the link freqency */
322 old_freq = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_FREQ);
324 needs_reset |= old_freq != freq;
325 old_freq = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_FREQ);
327 needs_reset |= old_freq != freq;
329 /* Set the Calulcated link frequency */
330 pci_write_config8(node1, link1 + PCI_HT_CAP_HOST_FREQ, freq);
331 pci_write_config8(node2, link2 + PCI_HT_CAP_HOST_FREQ, freq);
333 /* Get the width capabilities */
334 width_cap1 = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH);
335 width_cap2 = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH);
337 /* Calculate node1's input width */
338 ln_width1 = link_width_to_pow2[width_cap1 & 7];
339 ln_width2 = link_width_to_pow2[(width_cap2 >> 4) & 7];
340 if (ln_width1 > ln_width2) {
341 ln_width1 = ln_width2;
343 width = pow2_to_link_width[ln_width1];
344 /* Calculate node1's output width */
345 ln_width1 = link_width_to_pow2[(width_cap1 >> 4) & 7];
346 ln_width2 = link_width_to_pow2[width_cap2 & 7];
347 if (ln_width1 > ln_width2) {
348 ln_width1 = ln_width2;
350 width |= pow2_to_link_width[ln_width1] << 4;
352 /* See if I am changing node1's width */
353 old_width = pci_read_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH + 1);
354 needs_reset |= old_width != width;
356 /* Set node1's widths */
357 pci_write_config8(node1, link1 + PCI_HT_CAP_HOST_WIDTH + 1, width);
359 // * Calculate node2's width */
360 width = ((width & 0x70) >> 4) | ((width & 0x7) << 4);
362 /* See if I am changing node2's width */
363 old_width = pci_read_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH + 1);
364 needs_reset |= old_width != width;
366 /* Set node2's widths */
367 pci_write_config8(node2, link2 + PCI_HT_CAP_HOST_WIDTH + 1, width);
371 static uint8_t get_linkn_first(uint8_t byte)
373 if(byte & 0x02) { byte = 0; }
374 else if(byte & 0x04) { byte = 1; }
375 else if(byte & 0x08) { byte = 2; }
379 static uint8_t get_linkn_last(uint8_t byte)
381 if(byte & 0x02) { byte &= 0x0f; byte |= 0x00; }
382 if(byte & 0x04) { byte &= 0x0f; byte |= 0x10; }
383 if(byte & 0x08) { byte &= 0x0f; byte |= 0x20; }
387 static uint8_t get_linkn_last_count(uint8_t byte)
390 if(byte & 0x02) { byte &= 0xcf; byte |= 0x00; byte+=0x40; }
391 if(byte & 0x04) { byte &= 0xcf; byte |= 0x10; byte+=0x40; }
392 if(byte & 0x08) { byte &= 0xcf; byte |= 0x20; byte+=0x40; }
396 static void setup_row_local(u8 source, u8 row) /* source will be 7 when it is for temp use*/
401 for(linkn = 0; linkn<3; linkn++) {
404 regpos = 0x98 + 0x20 * linkn;
405 reg = pci_read_config32(NODE_HT(source), regpos);
406 if ((reg & 0x17) != 3) continue; /* it is not conherent or not connected*/
411 fill_row(source,row, val);
414 static void setup_row_direct_x(u8 temp, u8 source, u8 dest, u8 linkn)
419 val |= 1<<(linkn+1+8); /*for direct connect response route should equal to request table*/
421 if(((source &1)!=(dest &1))
423 && ( (source<4)||(source>5) ) //(6,7) (7,6) should still be here
424 //(6,5) (7,4) should be here
429 /*for CROSS_BAR_47_56 47, 56, should be here too
430 and for 47, 56, 57, 75, 46, 64 we need to substract another link to
433 val_s = get_row(temp, source);
434 val |= ((val_s>>16) - (1<<(linkn+1)))<<16;
437 fill_row(temp,dest, val );
441 static void opt_broadcast_rt(u8 source, u8 dest, u8 kickout) {
443 val = get_row(source, dest);
444 val -= link_connection(source, kickout)<<16;
445 fill_row(source, dest, val);
448 static void opt_broadcast_rt_group(const u8 *conn, int num) {
451 for(i=0; i<num; i+=3) {
452 opt_broadcast_rt(conn[i], conn[i+1],conn[i+2]);
455 static void opt_broadcast_rt_plus(u8 source, u8 dest, u8 kickout) {
457 val = get_row(source, dest);
458 val += link_connection(source, kickout)<<16;
459 fill_row(source, dest, val);
462 static void opt_broadcast_rt_plus_group(const u8 *conn, int num) {
465 for(i=0; i<num; i+=3) {
466 opt_broadcast_rt_plus(conn[i], conn[i+1],conn[i+2]);
471 static void setup_row_direct(u8 source, u8 dest, u8 linkn){
472 setup_row_direct_x(source, source, dest, linkn);
475 static void setup_remote_row_direct(u8 source, u8 dest, u8 linkn){
476 setup_row_direct_x(7, source, dest, linkn);
479 static void setup_temp_row(u8 source, u8 dest)
481 /* copy val from (source, dest) to (source,7) */
482 fill_row(source,7,get_row(source,dest));
485 static void clear_temp_row(u8 source)
487 fill_row(source, 7, DEFAULT);
490 static void setup_remote_node(u8 node)
492 static const uint8_t pci_reg[] = {
493 0x44, 0x4c, 0x54, 0x5c, 0x64, 0x6c, 0x74, 0x7c,
494 0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78,
495 0x84, 0x8c, 0x94, 0x9c, 0xa4, 0xac, 0xb4, 0xbc,
496 0x80, 0x88, 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8,
497 0xc4, 0xcc, 0xd4, 0xdc,
498 0xc0, 0xc8, 0xd0, 0xd8,
499 0xe0, 0xe4, 0xe8, 0xec,
503 print_spew("setup_remote_node: ");
505 /* copy the default resource map from node 0 */
506 for(i = 0; i < sizeof(pci_reg)/sizeof(pci_reg[0]); i++) {
510 value = pci_read_config32(NODE_MP(0), reg);
511 pci_write_config32(NODE_MP(7), reg, value);
514 print_spew("done\r\n");
517 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 1*/
520 #if CONFIG_MAX_PHYSICAL_CPUS > 2
522 static void setup_row_indirect_x(u8 temp, u8 source, u8 dest)
524 static void setup_row_indirect_x(u8 temp, u8 source, u8 dest, u8 gateway, u8 diff)
527 /*for indirect connection, we need to compute the val from val_s(source, source), and val_g(source, gateway) */
534 gateway = source + 2;
536 gateway = source - 2;
539 val_s = get_row(temp, source);
540 val = get_row(temp, gateway);
547 diff = ((source&1)!=(dest &1));
550 if(diff && (val_s!=(val&0xff)) ) { /* use another connect as response*/
552 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
554 /* Some node have two links left
555 * don't worry we only have (2, (3 as source need to handle
558 byte = get_linkn_last_count(byte);
559 if((byte>>2)>1) { /* make sure not the corner*/
561 val_s-=link_connection(temp, source-2); /* -down*/
566 val_s-=link_connection(temp, 6); // for 7,2 via 5
567 } else if (source==6){
568 val_s-=link_connection(temp, 7); // for 6,3 via 4
571 if (source < gateway) { // for 5, 4 via 7
572 val_s-=link_connection(temp, source-2);
575 val_s-=link_connection(temp, source+2); /* -up*/
583 if(diff) { /* cross rung?*/
587 val_s = get_row(temp, source);
588 val |= ((val_s>>16) - link_connection(temp, gateway))<<16;
591 fill_row(temp, dest, val);
596 static void setup_row_indirect(u8 source, u8 dest)
598 setup_row_indirect_x(source, source, dest);
601 static void setup_row_indirect(u8 source, u8 dest, u8 gateway, u8 diff)
603 setup_row_indirect_x(source, source, dest, gateway, diff);
607 static void setup_row_indirect_group(const u8 *conn, int num)
612 for(i=0; i<num; i+=2) {
613 setup_row_indirect(conn[i], conn[i+1]);
615 for(i=0; i<num; i+=4) {
616 setup_row_indirect(conn[i], conn[i+1],conn[i+2], conn[i+3]);
623 static void setup_remote_row_indirect(u8 source, u8 dest)
625 setup_row_indirect_x(7, source, dest);
628 static void setup_remote_row_indirect(u8 source, u8 dest, u8 gateway, u8 diff)
630 setup_row_indirect_x(7, source, dest, gateway, diff);
634 static void setup_remote_row_indirect_group(const u8 *conn, int num)
639 for(i=0; i<num; i+=2) {
640 setup_remote_row_indirect(conn[i], conn[i+1]);
642 for(i=0; i<num; i+=4) {
643 setup_remote_row_indirect(conn[i], conn[i+1],conn[i+2], conn[i+3]);
648 #endif /*CONFIG_MAX_PHYSICAL_CPUS > 2*/
651 static void setup_uniprocessor(void)
653 print_spew("Enabling UP settings\r\n");
654 #if CONFIG_LOGICAL_CPUS==1
655 unsigned tmp = (pci_read_config32(NODE_MC(0), 0xe8) >> 12) & 3;
661 struct setup_smp_result {
666 #if CONFIG_MAX_PHYSICAL_CPUS > 2
667 static int optimize_connection_group(const u8 *opt_conn, int num) {
670 for(i=0; i<num; i+=2) {
671 needs_reset = optimize_connection(
672 NODE_HT(opt_conn[i]), 0x80 + link_to_register(link_connection(opt_conn[i],opt_conn[i+1])),
673 NODE_HT(opt_conn[i+1]), 0x80 + link_to_register(link_connection(opt_conn[i+1],opt_conn[i])) );
679 #if CONFIG_MAX_PHYSICAL_CPUS > 1
680 static struct setup_smp_result setup_smp2(void)
682 struct setup_smp_result result;
686 result.needs_reset = 0;
688 setup_row_local(0, 0); /* it will update the broadcast RT*/
691 byte = (val>>16) & 0xfe;
692 if(byte<0x2) { /* no coherent connection so get out.*/
697 /* Setup and check a temporary connection to node 1 */
698 #if TRY_HIGH_FIRST == 1
699 byte = get_linkn_last(byte); /* Max Link to node1 */
701 byte = get_linkn_first(byte); /*Min Link to node1 --- according to AMD*/
703 print_linkn("(0,1) link=", byte);
704 setup_row_direct(0,1, byte);
705 setup_temp_row(0, 1);
707 verify_connection(7);
709 /* We found 2 nodes so far */
710 val = pci_read_config32(NODE_HT(7), 0x6c);
711 byte = (val>>2) & 0x3; /*get default link on node7 to node0*/
712 print_linkn("(1,0) link=", byte);
713 setup_row_local(7,1);
714 setup_remote_row_direct(1, 0, byte);
716 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
718 byte = (val>>16) & 0xfe;
719 byte = get_linkn_last_count(byte);
720 if((byte>>2)==3) { /* Oh! we need to treat it as node2. So use another link*/
722 byte = (val>>16) & 0xfe;
723 #if TRY_HIGH_FIRST == 1
724 byte = get_linkn_first(byte); /* Min link to Node1 */
726 byte = get_linkn_last(byte); /* Max link to Node1*/
728 print_linkn("\t-->(0,1) link=", byte);
729 setup_row_direct(0,1, byte);
730 setup_temp_row(0, 1);
732 verify_connection(7);
734 /* We found 2 nodes so far */
735 val = pci_read_config32(NODE_HT(7), 0x6c);
736 byte = (val>>2) & 0x3; /* get default link on node7 to node0*/
737 print_linkn("\t-->(1,0) link=", byte);
738 setup_row_local(7,1);
739 setup_remote_row_direct(1, 0, byte);
743 setup_remote_node(1); /* Setup the regs on the remote node */
744 rename_temp_node(1); /* Rename Node 7 to Node 1 */
745 enable_routing(1); /* Enable routing on Node 1 */
747 /*don't need and it is done by clear_dead_links */
751 result.needs_reset |= optimize_connection(
752 NODE_HT(0), 0x80 + link_to_register(link_connection(0,1)),
753 NODE_HT(1), 0x80 + link_to_register(link_connection(1,0)) );
757 #endif /*CONFIG_MAX_PHYSICAL_CPUS > 1 */
759 #if CONFIG_MAX_PHYSICAL_CPUS > 2
761 static struct setup_smp_result setup_smp4(int needs_reset)
763 struct setup_smp_result result;
768 result.needs_reset = needs_reset;
770 /* Setup and check temporary connection from Node 0 to Node 2 */
772 byte = ((val>>16) & 0xfe) - link_connection(0,1);
773 byte = get_linkn_last_count(byte);
775 if((byte>>2)==0) { /* We should have two coherent for 4p and above*/
780 byte &= 3; /* bit [3,2] is count-1*/
781 print_linkn("(0,2) link=", byte);
782 setup_row_direct(0, 2, byte); /*(0,2) direct link done*/
784 /* We found 3 nodes so far. Now setup a temporary
785 * connection from node 0 to node 3 via node 1
787 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
788 /* here should setup_row_direct(1,3) at first, before that we should find the link in node 1 to 3*/
790 byte = ((val>>16) & 0xfe) - link_connection(1,0);
791 byte = get_linkn_first(byte);
792 print_linkn("(1,3) link=", byte);
793 setup_row_direct(1,3,byte); /* (1, 3) direct link done*/
795 /* We found 4 nodes so far. Now setup all nodes for 4p */
796 // We need to make sure 0,2 and 1,3 link is set already
798 static const u8 conn4_1[] = {
803 static const u8 conn4_1[] = {
809 setup_row_indirect_group(conn4_1, sizeof(conn4_1)/sizeof(conn4_1[0]));
812 verify_connection(7);
813 val = pci_read_config32(NODE_HT(7), 0x6c);
814 byte = (val>>2) & 0x3; /* get default link on 7 to 0*/
815 print_linkn("(2,0) link=", byte);
817 setup_row_local(7,2);
818 setup_remote_row_direct(2, 0, byte); /* node 2 to node 0 direct link done */
819 setup_remote_node(2); /* Setup the regs on the remote node */
821 rename_temp_node(2); /* Rename Node 7 to Node 2 */
822 enable_routing(2); /* Enable routing on Node 2 */
826 verify_connection(7);
828 val = pci_read_config32(NODE_HT(7), 0x6c);
829 byte = (val>>2) & 0x3; /* get default link on 7 to 1*/
830 print_linkn("(3,1) link=", byte);
832 setup_row_local(7,3);
833 setup_remote_row_direct(3, 1, byte); /* node 3 to node 1 direct link done */
834 setup_remote_node(3); /* Setup the regs on the remote node */
836 /* We need to init link between 2, and 3 direct link */
838 byte = ((val>>16) & 0xfe) - link_connection(2,0);
839 byte = get_linkn_last_count(byte);
840 print_linkn("(2,3) link=", byte & 3);
842 setup_row_direct(2,3, byte & 0x3);
845 verify_connection(7); /* to 3*/
847 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
848 /* We need to find out which link is to node3 */
849 if((byte>>2)==2) { /* one to node3, one to node0, one to node4*/
851 if((val>>16) == 1) { /* that link is to node4, because via node1 it has been set, recompute it*/
853 byte = ((val>>16) & 0xfe) - link_connection(2,0);
854 byte = get_linkn_first(byte);
855 print_linkn("\t-->(2,3) link=", byte);
856 setup_row_direct(2,3,byte);
858 verify_connection(7); /* to 3*/
863 val = pci_read_config32(NODE_HT(7), 0x6c);
864 byte = (val>>2) & 0x3; /* get default link on 7 to 2*/
865 print_linkn("(3,2) link=", byte);
866 setup_remote_row_direct(3,2, byte);
868 #if (CONFIG_MAX_PHYSICAL_CPUS > 4) || (CONFIG_MAX_PHYSICAL_CPUS_4_BUT_MORE_INSTALLED == 1)
869 /* set link from 3 to 5 before enable it*/
871 byte = ((val>>16) & 0xfe) - link_connection(7,2) - link_connection(7,1);
872 byte = get_linkn_last_count(byte);
873 if((byte>>2)==1) { /* We should have three coherent links on node 3 for 6p and above*/
874 byte &= 3; /*bit [3,2] is count-2*/
875 print_linkn("(3,5) link=", byte);
876 setup_remote_row_direct(3, 5, byte);
880 byte = ((val>>16) & 0xfe) - link_connection(2,3) - link_connection(2,0);
881 byte = get_linkn_last_count(byte);
883 if((byte>>2)==1) { /* We should have three coherent link on node 2 for 6p and above*/
884 byte &= 3; /* bit [3,2] is count-2*/
885 print_linkn("(2,4) link=", byte);
886 setup_row_direct(2, 4, byte);
890 //Beside 3, 1 is set, We need to make sure 3, 5 is set already in case has three link in 3
892 static const u8 conn4_3[] = {
896 static const u8 conn4_3[] = {
900 setup_remote_row_indirect_group(conn4_3, sizeof(conn4_3)/sizeof(conn4_3[0]));
902 /* ready to enable RT for Node 3 */
904 enable_routing(3); /* enable routing on node 3 (temp.) */
906 // beside 2, 0 is set, We need to make sure 2, 4 link is set already in case has three link in 2
908 static const u8 conn4_2[] = {
912 static const u8 conn4_2[] = {
916 setup_row_indirect_group(conn4_2, sizeof(conn4_2)/sizeof(conn4_2[0]));
919 /*We need to do sth to reverse work for setup_temp_row (0,1) (1,3) */
920 /* it will be done by clear_dead_links */
925 /* optimize physical connections - by LYH */
926 static const u8 opt_conn4[] = {
932 result.needs_reset |= optimize_connection_group(opt_conn4, sizeof(opt_conn4)/sizeof(opt_conn4[0]));
938 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 2 */
940 #if CONFIG_MAX_PHYSICAL_CPUS > 4
942 static struct setup_smp_result setup_smp6(int needs_reset)
944 struct setup_smp_result result;
949 result.needs_reset = needs_reset;
951 /* Setup and check temporary connection from Node 0 to Node 4 through 2*/
953 byte = ((val>>16) & 0xfe) - link_connection(2,3) - link_connection(2,0);
954 byte = get_linkn_last_count(byte);
956 if((byte>>2)==0) { /* We should have three coherent link on node 2 for 6p and above*/
961 /* Setup and check temporary connection from Node 0 to Node 5 through 1, 3*/
962 /* set link from 3 to 5 before enable it*/
964 byte = ((val>>16) & 0xfe) - link_connection(3,2) - link_connection(3,1);
965 byte = get_linkn_last_count(byte);
966 if((byte>>2)==0) { /* We should have three coherent links on node 3 for 6p and above*/
971 /* We found 6 nodes so far. Now setup all nodes for 6p */
972 #warning "FIXME we need to find out the correct gateway for 6p"
973 static const u8 conn6_1[] = {
991 setup_row_indirect_group(conn6_1, sizeof(conn6_1)/sizeof(conn6_1[0]));
993 for(byte=0; byte<4; byte+=2) {
994 setup_temp_row(byte,byte+2);
996 verify_connection(7);
997 val = pci_read_config32(NODE_HT(7), 0x6c);
998 byte = (val>>2) & 0x3; /*get default link on 7 to 2*/
999 print_linkn("(4,2) link=", byte);
1001 setup_row_local(7,4);
1002 setup_remote_row_direct(4, 2, byte);
1003 setup_remote_node(4); /* Setup the regs on the remote node */
1005 /* Set indirect connection to 0, to 3 */
1006 //we only need to set 4,0 here
1007 static const u8 conn6_2[] = {
1008 #if !CROSS_BAR_47_56
1015 setup_remote_row_indirect_group(conn6_2, sizeof(conn6_2)/sizeof(conn6_2[0]));
1017 rename_temp_node(4);
1020 setup_temp_row(0,1);
1021 for(byte=0; byte<4; byte+=2) {
1022 setup_temp_row(byte+1,byte+3);
1024 verify_connection(7);
1026 val = pci_read_config32(NODE_HT(7), 0x6c);
1027 byte = (val>>2) & 0x3; /* get default link on 7 to 3*/
1028 print_linkn("(5,3) link=", byte);
1029 setup_row_local(7,5);
1030 setup_remote_row_direct(5, 3, byte);
1031 setup_remote_node(5); /* Setup the regs on the remote node */
1033 #if !CROSS_BAR_47_56
1034 /* We need to init link between 4, and 5 direct link */
1036 byte = ((val>>16) & 0xfe) - link_connection(4,2);
1037 byte = get_linkn_last_count(byte);
1038 print_linkn("(4,5) link=", byte & 3);
1040 setup_row_direct(4,5, byte & 0x3);
1041 setup_temp_row(0,2);
1042 setup_temp_row(2,4);
1043 setup_temp_row(4,5);
1044 verify_connection(7); /* to 5*/
1046 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1047 /* We need to find out which link is to node5 */
1049 if((byte>>2)==2) { /* one to node5, one to node2, one to node6*/
1051 if((val>>16) == 1) { /* that link is to node6, because via node 3 node 5 has been set*/
1053 byte = ((val>>16) & 0xfe) - link_connection(4,2);
1054 byte = get_linkn_first(byte);
1055 print_linkn("\t-->(4,5) link=", byte);
1056 setup_row_direct(4,5,byte);
1057 setup_temp_row(4,5);
1058 verify_connection(7); /* to 5*/
1063 val = pci_read_config32(NODE_HT(7), 0x6c);
1064 byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
1065 print_linkn("(5,4) link=", byte);
1066 setup_remote_row_direct(5,4, byte);
1070 byte = ((val>>16) & 0xfe) - link_connection(7,4) - link_connection(7,3);
1071 byte = get_linkn_last_count(byte);
1072 if((byte>>2)==1) { /* We should have three coherent links on node 5 for 6p and above*/
1073 byte &= 3; /*bit [3,2] is count-2*/
1074 print_linkn("(5,7) link=", byte);
1075 setup_remote_row_direct(5, 7, byte);
1080 byte = ((val>>16) & 0xfe) - link_connection(4,5) - link_connection(4,2);
1081 byte = get_linkn_last_count(byte);
1083 if((byte>>2)==1) { /* We should have three coherent link on node 4 for 6p and above*/
1084 byte &= 3; /* bit [3,2] is count-2*/
1085 print_linkn("(4,6) link=", byte);
1086 setup_row_direct(4, 6, byte);
1091 //We need to set 5,0 here only, We need to set up 5, 7 to make 5,0
1092 /* Set indirect connection to 0, to 3 for indirect we will use clockwise routing */
1093 static const u8 conn6_3[] = {
1094 #if !CROSS_BAR_47_56
1101 setup_remote_row_indirect_group(conn6_3, sizeof(conn6_3)/sizeof(conn6_3[0]));
1103 /* ready to enable RT for 5 */
1104 rename_temp_node(5);
1105 enable_routing(5); /* enable routing on node 5 (temp.) */
1107 static const u8 conn6_4[] = {
1108 #if !CROSS_BAR_47_56
1127 setup_row_indirect_group(conn6_4, sizeof(conn6_4)/sizeof(conn6_4[0]));
1130 /* We need to do sth about reverse about setup_temp_row (0,1), (2,4), (1, 3), (3,5)
1131 * It will be done by clear_dead_links
1133 for(byte=0; byte<4; byte++) {
1134 clear_temp_row(byte);
1138 /* optimize physical connections - by LYH */
1139 static const uint8_t opt_conn6[] ={
1142 #if !CROSS_BAR_47_56
1146 result.needs_reset |= optimize_connection_group(opt_conn6, sizeof(opt_conn6)/sizeof(opt_conn6[0]));
1152 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 4 */
1154 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1156 static struct setup_smp_result setup_smp8(int needs_reset)
1158 struct setup_smp_result result;
1163 result.needs_reset = needs_reset;
1165 /* Setup and check temporary connection from Node 0 to Node 6 via 2 and 4 to 7 */
1168 byte = ((val>>16) & 0xfe) - link_connection(4,2);
1170 byte = ((val>>16) & 0xfe) - link_connection(4,5) - link_connection(4,2);
1171 byte = get_linkn_last_count(byte); /* Max link to 6*/
1172 if((byte>>2)==0) { /* We should have two or three coherent links on node 4 for 8p*/
1179 byte = get_linkn_last_count(byte); /* Max link to 6*/
1180 if((byte>>2)<2) { /* We should have two or three coherent links on node 4 for 8p*/
1184 #if TRY_HIGH_FIRST == 1
1185 byte = ((val>>16) & 0xfe) - link_connection(4,2);
1186 byte = get_linkn_first(byte); /*Min link to 6*/
1188 byte &= 3; /* bit [3,2] is count-1 or 2*/
1190 print_linkn("(4,6) link=", byte);
1191 setup_row_direct(4, 6, byte);
1194 #if !CROSS_BAR_47_56
1195 /* Setup and check temporary connection from Node 0 to Node 7 through 1, 3, 5*/
1197 byte = ((val>>16) & 0xfe) - link_connection(5,4) - link_connection(5,3);
1198 byte = get_linkn_last_count(byte);
1199 if((byte>>2)==0) { /* We should have three coherent links on node 5 for 6p and above*/
1205 /* We found 8 nodes so far. Now setup all nodes for 8p */
1206 static const u8 conn8_1[] = {
1207 #if !CROSS_BAR_47_56
1229 setup_row_indirect_group(conn8_1,sizeof(conn8_1)/sizeof(conn8_1[0]));
1231 for(byte=0; byte<6; byte+=2) {
1232 setup_temp_row(byte,byte+2);
1234 verify_connection(7);
1235 val = pci_read_config32(NODE_HT(7), 0x6c);
1236 byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
1237 print_linkn("(6,4) link=", byte);
1239 setup_row_local(7,6);
1240 setup_remote_row_direct(6, 4, byte);
1241 setup_remote_node(6); /* Setup the regs on the remote node */
1242 /* Set indirect connection to 0, to 3 */
1243 #warning "FIXME we need to find out the correct gateway for 8p"
1244 static const u8 conn8_2[] = {
1245 #if !CROSS_BAR_47_56
1252 setup_remote_row_indirect_group(conn8_2, sizeof(conn8_2)/sizeof(conn8_2[0]));
1256 /* here init 5, 6 */
1257 /* Setup and check temporary connection from Node 0 to Node 5 through 1, 3, 5*/
1259 byte = ((val>>16) & 0xfe) - link_connection(5,3);
1260 #if TRY_HIGH_FIRST == 1
1261 byte = get_linkn_first(byte);
1263 byte = get_linkn_last(byte);
1265 print_linkn("(5,6) link=", byte);
1266 setup_row_direct(5, 6, byte);
1268 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
1269 for(byte=0; byte<4; byte+=2) {
1270 setup_temp_row(byte+1,byte+3);
1272 setup_temp_row(5,6);
1274 verify_connection(7);
1276 val = get_row(7,6); // to chect it if it is node6 before renaming
1277 if( (val>>16) == 1) { // it is real node 7 so swap it
1278 /* We need to recompute link to 6 */
1280 byte = ((val>>16) & 0xfe) - link_connection(5,3);
1281 #if TRY_HIGH_FIRST == 1
1282 byte = get_linkn_first(byte);
1284 byte = get_linkn_last(byte);
1286 print_linkn("\t-->(5,6) link=", byte);
1287 setup_row_direct(5, 6, byte);
1289 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
1290 for(byte=0; byte<4; byte+=2) {
1291 setup_temp_row(byte+1,byte+3);
1294 setup_temp_row(5,6);
1296 verify_connection(7);
1298 val = pci_read_config32(NODE_HT(7), 0x6c);
1299 byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
1300 print_linkn("(6,5) link=", byte);
1301 setup_remote_row_direct(6, 5, byte);
1302 /*Till now 56, 65 done */
1305 rename_temp_node(6);
1308 #if !CROSS_BAR_47_56
1309 setup_temp_row(0,1);
1310 for(byte=0; byte<6; byte+=2) {
1311 setup_temp_row(byte+1,byte+3);
1314 verify_connection(7);
1316 val = pci_read_config32(NODE_HT(7), 0x6c);
1317 byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
1318 print_linkn("(7,5) link=", byte);
1319 setup_row_local(7,7);
1320 setup_remote_row_direct(7, 5, byte);
1324 byte = ((val>>16) & 0xfe) - link_connection(4,2) - link_connection(4,6);
1325 byte = get_linkn_first(byte);
1326 print_linkn("(4,7) link=", byte);
1327 setup_row_direct(4, 7, byte);
1329 /* Setup and check temporary connection from Node 0 to Node 7 through 2, and 4*/
1330 for(byte=0; byte<4; byte+=2) {
1331 setup_temp_row(byte,byte+2);
1334 verify_connection(7);
1336 val = pci_read_config32(NODE_HT(7), 0x6c);
1337 byte = (val>>2) & 0x3; /* get default link on 7 to 4*/
1338 print_linkn("(7,4) link=", byte);
1339 setup_row_local(7,7);
1340 setup_remote_row_direct(7, 4, byte);
1341 /* till now 4-7, 7-4 done. */
1343 setup_remote_node(7); /* Setup the regs on the remote node */
1346 /* here init 5, 7 */
1347 /* Setup and check temporary connection from Node 0 to Node 5 through 1, 3, 5*/
1349 byte = ((val>>16) & 0xfe) - link_connection(5,3) - link_connection(5,6);
1350 byte = get_linkn_first(byte);
1351 print_linkn("(5,7) link=", byte);
1352 setup_row_direct(5, 7, byte);
1354 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */
1355 for(byte=0; byte<4; byte+=2) {
1356 setup_temp_row(byte+1,byte+3);
1359 verify_connection(7);
1361 val = pci_read_config32(NODE_HT(7), 0x6c);
1362 byte = (val>>2) & 0x3; /* get default link on 7 to 5*/
1363 print_linkn("(7,5) link=", byte);
1364 setup_remote_row_direct(7, 5, byte);
1365 /*Till now 57, 75 done */
1369 /* We need to init link between 6, and 7 direct link */
1371 #if !CROSS_BAR_47_56
1372 byte = ((val>>16) & 0xfe) - link_connection(6,4);
1374 byte = ((val>>16) & 0xfe) - link_connection(6,4) - link_connection(6,5);
1376 byte = get_linkn_first(byte);
1377 print_linkn("(6,7) link=", byte);
1378 setup_row_direct(6,7, byte);
1381 #if !CROSS_BAR_47_56
1382 byte = ((val>>16) & 0xfe) - link_connection(7,5);
1384 byte = ((val>>16) & 0xfe) - link_connection(7,5) - link_connection(7,4);
1386 byte = get_linkn_first(byte);
1387 print_linkn("(7,6) link=", byte);
1388 setup_row_direct(7,6, byte);
1390 /* Set indirect connection to 0, to 3 for indirect we will use clockwise routing */
1391 static const u8 conn8_3[] = {
1392 #if !CROSS_BAR_47_56
1393 0, 7, /* restore it*/
1415 6, 1, 5, 0, // or 4, 1
1417 6, 3, 5, 0, // or 4, 1
1419 7, 0, 4, 0, // or 5, 1
1421 7, 2, 4, 0, // or 5, 1
1424 0, 7, 2, 0, /* restore it*/
1429 2, 5, 4, 1, /* reset it */
1432 4, 1, 2, 1, /* reset it */
1435 5, 2, 3, 1, /* reset it */
1441 setup_row_indirect_group(conn8_3, sizeof(conn8_3)/sizeof(conn8_3[0]));
1444 /* for 47, 56, 57, 75, 46, 64 we need to substract another link to
1446 static const u8 conn8_4[] = {
1469 6, 1, 7, // needed for via 5
1472 6, 3, 7, // needed for via 5
1474 7, 0, 6, // needed for via 4
1477 7, 2, 6, // needed for via 4
1482 opt_broadcast_rt_group(conn8_4, sizeof(conn8_4)/sizeof(conn8_4[0]));
1484 static const u8 conn8_5[] = {
1490 opt_broadcast_rt_plus_group(conn8_5, sizeof(conn8_5)/sizeof(conn8_5[0]));
1495 /* ready to enable RT for Node 7 */
1496 enable_routing(7); /* enable routing on node 7 (temp.) */
1498 static const uint8_t opt_conn8[] ={
1507 /* optimize physical connections - by LYH */
1508 result.needs_reset |= optimize_connection_group(opt_conn8, sizeof(opt_conn8)/sizeof(opt_conn8[0]));
1513 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 6 */
1516 #if CONFIG_MAX_PHYSICAL_CPUS > 1
1518 static struct setup_smp_result setup_smp(void)
1520 struct setup_smp_result result;
1522 print_spew("Enabling SMP settings\r\n");
1524 result = setup_smp2();
1525 #if CONFIG_MAX_PHYSICAL_CPUS > 2
1526 if(result.nodes == 2)
1527 result = setup_smp4(result.needs_reset);
1530 #if CONFIG_MAX_PHYSICAL_CPUS > 4
1531 if(result.nodes == 4)
1532 result = setup_smp6(result.needs_reset);
1535 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1536 if(result.nodes == 6)
1537 result = setup_smp8(result.needs_reset);
1541 printk_debug("%02x nodes initialized.\r\n", result.nodes);
1543 print_debug_hex8(result.nodes);
1544 print_debug(" nodes initialized.\r\n");
1550 static unsigned verify_mp_capabilities(unsigned nodes)
1552 unsigned node, mask;
1554 mask = 0x06; /* BigMPCap */
1556 for (node=0; node<nodes; node++) {
1557 mask &= pci_read_config32(NODE_MC(node), 0xe8);
1561 #if CONFIG_MAX_PHYSICAL_CPUS > 2
1562 case 0x02: /* MPCap */
1564 print_err("Going back to DP\r\n");
1569 case 0x00: /* Non SMP */
1571 print_err("Going back to UP\r\n");
1582 static void clear_dead_routes(unsigned nodes)
1586 #if CONFIG_MAX_PHYSICAL_CPUS > 6
1587 if(nodes==8) return;/* don't touch (7,7)*/
1593 for(node = 7; node >= 0; node--) {
1594 for(row = 7; row >= last_row; row--) {
1595 fill_row(node, row, DEFAULT);
1599 /* Update the local row */
1600 for( node=0; node<nodes; node++) {
1602 for(row =0; row<nodes; row++) {
1603 val |= get_row(node, row);
1605 fill_row(node, node, (((val & 0xff) | ((val >> 8) & 0xff)) << 16) | 0x0101);
1608 #endif /* CONFIG_MAX_PHYSICAL_CPUS > 1 */
1610 static unsigned count_cpus(unsigned nodes)
1612 #if CONFIG_LOGICAL_CPUS==1
1613 unsigned node, totalcpus, tmp;
1616 for (node=0; node<nodes; node++) {
1617 tmp = (pci_read_config32(NODE_MC(node), 0xe8) >> 12) & 3 ;
1618 totalcpus += (tmp + 1);
1628 static void coherent_ht_finalize(unsigned nodes)
1630 unsigned total_cpus;
1631 unsigned cpu_node_count;
1634 total_cpus = count_cpus(nodes);
1635 cpu_node_count = ((total_cpus -1)<<16)|((nodes - 1) << 4);
1637 /* set up cpu count and node count and enable Limit
1638 * Config Space Range for all available CPUs.
1639 * Also clear non coherent hypertransport bus range
1640 * registers on Hammer A0 revision.
1643 print_spew("coherent_ht_finalize\r\n");
1644 rev_a0 = is_cpu_rev_a0();
1645 for (node = 0; node < nodes; node++) {
1648 dev = NODE_HT(node);
1650 /* Set the Total CPU and Node count in the system */
1651 val = pci_read_config32(dev, 0x60);
1652 val &= (~0x000F0070);
1653 val |= cpu_node_count;
1654 pci_write_config32(dev, 0x60, val);
1656 /* Only respond to real cpu pci configuration cycles
1657 * and optimize the HT settings
1659 val=pci_read_config32(dev, HT_TRANSACTION_CONTROL);
1660 val &= ~((HTTC_BUF_REL_PRI_MASK << HTTC_BUF_REL_PRI_SHIFT) |
1661 (HTTC_MED_PRI_BYP_CNT_MASK << HTTC_MED_PRI_BYP_CNT_SHIFT) |
1662 (HTTC_HI_PRI_BYP_CNT_MASK << HTTC_HI_PRI_BYP_CNT_SHIFT));
1663 val |= HTTC_LIMIT_CLDT_CFG |
1664 (HTTC_BUF_REL_PRI_8 << HTTC_BUF_REL_PRI_SHIFT) |
1665 (3 << HTTC_MED_PRI_BYP_CNT_SHIFT) |
1666 (3 << HTTC_HI_PRI_BYP_CNT_SHIFT);
1667 pci_write_config32(dev, HT_TRANSACTION_CONTROL, val);
1670 pci_write_config32(dev, 0x94, 0);
1671 pci_write_config32(dev, 0xb4, 0);
1672 pci_write_config32(dev, 0xd4, 0);
1676 print_spew("done\r\n");
1679 static int apply_cpu_errata_fixes(unsigned nodes, int needs_reset)
1682 for(node = 0; node < nodes; node++) {
1685 dev = NODE_MC(node);
1686 if (is_cpu_pre_c0()) {
1689 * Limit the number of downstream posted requests to 1
1691 cmd = pci_read_config32(dev, 0x70);
1692 if ((cmd & (3 << 0)) != 2) {
1695 pci_write_config32(dev, 0x70, cmd );
1698 cmd = pci_read_config32(dev, 0x7c);
1699 if ((cmd & (3 << 4)) != 0) {
1702 pci_write_config32(dev, 0x7c, cmd );
1705 /* Clock Power/Timing Low */
1706 cmd = pci_read_config32(dev, 0xd4);
1707 if (cmd != 0x000D0001) {
1709 pci_write_config32(dev, 0xd4, cmd);
1710 needs_reset = 1; /* Needed? */
1714 else if (is_cpu_pre_d0()) { // d0 later don't need it
1717 * Set Clk Ramp Hystersis to 7
1718 * Clock Power/Timing Low
1720 cmd_ref = 0x04e20707; /* Registered */
1721 cmd = pci_read_config32(dev, 0xd4);
1722 if(cmd != cmd_ref) {
1723 pci_write_config32(dev, 0xd4, cmd_ref );
1724 needs_reset = 1; /* Needed? */
1731 static int optimize_link_read_pointers(unsigned nodes, int needs_reset)
1734 for(node = 0; node < nodes; node++) {
1735 device_t f0_dev, f3_dev;
1736 uint32_t cmd_ref, cmd;
1738 f0_dev = NODE_HT(node);
1739 f3_dev = NODE_MC(node);
1740 cmd_ref = cmd = pci_read_config32(f3_dev, 0xdc);
1741 for(link = 0; link < 3; link++) {
1744 /* This works on an Athlon64 because unimplemented links return 0 */
1745 reg = 0x98 + (link * 0x20);
1746 link_type = pci_read_config32(f0_dev, reg);
1747 /* Only handle coherent links */
1748 if ((link_type & (LinkConnected | InitComplete|NonCoherent)) ==
1749 (LinkConnected|InitComplete))
1751 cmd &= ~(0xff << (link *8));
1752 cmd |= 0x25 << (link *8);
1755 if (cmd != cmd_ref) {
1756 pci_write_config32(f3_dev, 0xdc, cmd);
1763 static void startup_other_cores(unsigned nodes)
1766 for(node = 0; node < nodes; node++) {
1769 dev = NODE_MC(node);
1770 siblings = (pci_read_config32(dev, 0xe8) >> 12) & 0x3;
1775 /* Redirect all MC4 accesses and error logging to core0 */
1776 val = pci_read_config32(dev, 0x44);
1777 val |= (1 << 27); //NbMcaToMstCpuEn bit
1778 pci_write_config32(dev, 0x44, val);
1780 /* Enable the second core */
1781 dev_f0 = NODE_HT(node);
1782 val = pci_read_config32(dev_f0, 0x68);
1784 pci_write_config32(dev_f0, 0x68, val);
1790 static int setup_coherent_ht_domain(void)
1792 struct setup_smp_result result;
1794 result.needs_reset = 0;
1796 #if K8_HT_CHECK_PENDING_LINK == 1
1800 enable_bsp_routing();
1802 #if CONFIG_MAX_PHYSICAL_CPUS > 1
1803 result = setup_smp();
1805 result.nodes = verify_mp_capabilities(result.nodes);
1806 clear_dead_routes(result.nodes);
1807 if (result.nodes == 1) {
1808 setup_uniprocessor();
1810 coherent_ht_finalize(result.nodes);
1811 startup_other_cores(result.nodes);
1812 result.needs_reset = apply_cpu_errata_fixes(result.nodes, result.needs_reset);
1813 result.needs_reset = optimize_link_read_pointers(result.nodes, result.needs_reset);
1814 return result.needs_reset;