From 1bc5654957dee91bbc20bcbd9484fce09db77a4a Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 6 Jan 2005 02:23:31 +0000 Subject: [PATCH] clear dead link bug fix and opt_link_read for non coherent link git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1842 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- src/northbridge/amd/amdk8/coherent_ht.c | 72 ++++++------- src/northbridge/amd/amdk8/incoherent_ht.c | 119 ++++++++++++++++------ 2 files changed, 126 insertions(+), 65 deletions(-) diff --git a/src/northbridge/amd/amdk8/coherent_ht.c b/src/northbridge/amd/amdk8/coherent_ht.c index 905d980f9..e056f53da 100644 --- a/src/northbridge/amd/amdk8/coherent_ht.c +++ b/src/northbridge/amd/amdk8/coherent_ht.c @@ -623,7 +623,7 @@ static struct setup_smp_result setup_smp2(void) #else byte = get_linkn_first(byte); /*Min Link to node1 --- according to AMD*/ #endif - print_linkn("(0,1) byte=", byte); + print_linkn("(0,1) link=", byte); setup_row_direct(0,1, byte); setup_temp_row(0, 1); @@ -636,7 +636,7 @@ static struct setup_smp_result setup_smp2(void) /* We found 2 nodes so far */ val = pci_read_config32(NODE_HT(7), 0x6c); byte = (val>>2) & 0x3; /*get default link on node7 to node0*/ - print_linkn("(1,0) byte=", byte); + print_linkn("(1,0) link=", byte); setup_row_local(7,1); setup_remote_row_direct(1, 0, byte); @@ -652,7 +652,7 @@ static struct setup_smp_result setup_smp2(void) #else byte = get_linkn_last(byte); /* Max link to Node1*/ #endif - print_linkn("-->(0,1) byte=", byte); + print_linkn("-->(0,1) link=", byte); setup_row_direct(0,1, byte); setup_temp_row(0, 1); @@ -665,7 +665,7 @@ static struct setup_smp_result setup_smp2(void) /* We found 2 nodes so far */ val = pci_read_config32(NODE_HT(7), 0x6c); byte = (val>>2) & 0x3; /* get default link on node7 to node0*/ - print_linkn("-->(1,0) byte=", byte); + print_linkn("-->(1,0) link=", byte); setup_row_local(7,1); setup_remote_row_direct(1, 0, byte); } @@ -710,7 +710,7 @@ static struct setup_smp_result setup_smp4(int needs_reset) } byte &= 3; /* bit [3,2] is count-1*/ - print_linkn("(0,2) byte=", byte); + print_linkn("(0,2) link=", byte); setup_row_direct(0, 2, byte); /*(0,2) direct link done*/ setup_temp_row(0, 2); @@ -728,7 +728,7 @@ static struct setup_smp_result setup_smp4(int needs_reset) val = get_row(1,1); byte = ((val>>16) & 0xfe) - link_connection(1,0); byte = get_linkn_first(byte); - print_linkn("(1,3) byte=", byte); + print_linkn("(1,3) link=", byte); setup_row_direct(1,3,byte); /* (1, 3) direct link done*/ setup_temp_row(1,3); /* temp. link between nodes 1 and 3 */ @@ -757,7 +757,7 @@ static struct setup_smp_result setup_smp4(int needs_reset) val = pci_read_config32(NODE_HT(7), 0x6c); byte = (val>>2) & 0x3; /* get default link on 7 to 0*/ - print_linkn("(2,0) byte=", byte); + print_linkn("(2,0) link=", byte); setup_row_local(7,2); setup_remote_row_direct(2, 0, byte); @@ -781,7 +781,7 @@ static struct setup_smp_result setup_smp4(int needs_reset) val = pci_read_config32(NODE_HT(7), 0x6c); byte = (val>>2) & 0x3; /* get default link on 7 to 1*/ - print_linkn("(3,1) byte=", byte); + print_linkn("(3,1) link=", byte); setup_row_local(7,3); setup_remote_row_direct(3, 1, byte); @@ -802,7 +802,7 @@ static struct setup_smp_result setup_smp4(int needs_reset) val = get_row(2,2); byte = ((val>>16) & 0xfe) - link_connection(2,0); byte = get_linkn_last_count(byte); - print_linkn("(2,3) byte=", byte & 3); + print_linkn("(2,3) link=", byte & 3); setup_row_direct(2,3, byte & 0x3); setup_temp_row(0,2); @@ -818,7 +818,7 @@ static struct setup_smp_result setup_smp4(int needs_reset) val = get_row(2,2); byte = ((val>>16) & 0xfe) - link_connection(2,0); byte = get_linkn_first(byte); - print_linkn("-->(2,3) byte=", byte); + print_linkn("-->(2,3) link=", byte); setup_row_direct(2,3,byte); setup_temp_row(2,3); check_connection(7); /* to 3*/ @@ -828,7 +828,7 @@ static struct setup_smp_result setup_smp4(int needs_reset) val = pci_read_config32(NODE_HT(7), 0x6c); byte = (val>>2) & 0x3; /* get default link on 7 to 2*/ - print_linkn("(3,2) byte=", byte); + print_linkn("(3,2) link=", byte); setup_remote_row_direct(3,2, byte); /* ready to enable RT for Node 3 */ @@ -878,7 +878,7 @@ static struct setup_smp_result setup_smp6(int needs_reset) return result; } byte &= 3; /* bit [3,2] is count-2*/ - print_linkn("(2,4) byte=", byte); + print_linkn("(2,4) link=", byte); setup_row_direct(2, 4, byte); /* Setup and check temporary connection from Node 0 to Node 4 through 2*/ @@ -902,7 +902,7 @@ static struct setup_smp_result setup_smp6(int needs_reset) } byte &= 3; /*bit [3,2] is count-2*/ - print_linkn("(3,5) byte=", byte); + print_linkn("(3,5) link=", byte); setup_row_direct(3, 5, byte); setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */ @@ -943,7 +943,7 @@ static struct setup_smp_result setup_smp6(int needs_reset) } val = pci_read_config32(NODE_HT(7), 0x6c); byte = (val>>2) & 0x3; /*get default link on 7 to 2*/ - print_linkn("(4,2) byte=", byte); + print_linkn("(4,2) link=", byte); setup_row_local(7,4); setup_remote_row_direct(4, 2, byte); @@ -974,7 +974,7 @@ static struct setup_smp_result setup_smp6(int needs_reset) val = pci_read_config32(NODE_HT(7), 0x6c); byte = (val>>2) & 0x3; /* get default link on 7 to 3*/ - print_linkn("(5,3) byte=", byte); + print_linkn("(5,3) link=", byte); setup_row_local(7,5); setup_remote_row_direct(5, 3, byte); setup_remote_node(5); /* Setup the regs on the remote node */ @@ -984,7 +984,7 @@ static struct setup_smp_result setup_smp6(int needs_reset) val = get_row(4,4); byte = ((val>>16) & 0xfe) - link_connection(4,2); byte = get_linkn_last_count(byte); - print_linkn("(4,5) byte=", byte & 3); + print_linkn("(4,5) link=", byte & 3); setup_row_direct(4,5, byte & 0x3); setup_temp_row(0,2); @@ -1001,7 +1001,7 @@ static struct setup_smp_result setup_smp6(int needs_reset) val = get_row(4,4); byte = ((val>>16) & 0xfe) - link_connection(4,2); byte = get_linkn_first(byte); - print_linkn("-->(4,5) byte=", byte); + print_linkn("-->(4,5) link=", byte); setup_row_direct(4,5,byte); setup_temp_row(4,5); check_connection(7); /* to 5*/ @@ -1011,7 +1011,7 @@ static struct setup_smp_result setup_smp6(int needs_reset) val = pci_read_config32(NODE_HT(7), 0x6c); byte = (val>>2) & 0x3; /* get default link on 7 to 4*/ - print_linkn("(5,4) byte=", byte); + print_linkn("(5,4) link=", byte); setup_remote_row_direct(5,4, byte); #endif @@ -1089,7 +1089,7 @@ static struct setup_smp_result setup_smp8(int needs_reset) #else byte = get_linkn_first(byte); /*Min link to 6*/ #endif - print_linkn("(4,6) byte=", byte); + print_linkn("(4,6) link=", byte); setup_row_direct(4, 6, byte); /* Setup and check temporary connection from Node 0 to Node 6 through 2, and 4*/ @@ -1107,7 +1107,7 @@ static struct setup_smp_result setup_smp8(int needs_reset) val = get_row(5,5); byte = ((val>>16) & 0xfe) - link_connection(5,4) - link_connection(5,3); byte = get_linkn_first(byte); - print_linkn("(5,7) byte=", byte); + print_linkn("(5,7) link=", byte); setup_row_direct(5, 7, byte); setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */ @@ -1118,7 +1118,7 @@ static struct setup_smp_result setup_smp8(int needs_reset) val = get_row(4,4); byte = ((val>>16) & 0xfe) - link_connection(4,2) - link_connection(4,6); byte = get_linkn_first(byte); - print_linkn("(4,7) byte=", byte); + print_linkn("(4,7) link=", byte); setup_row_direct(4, 7, byte); /* Setup and check temporary connection from Node 0 to Node 7 through 2, and 4*/ @@ -1167,7 +1167,7 @@ static struct setup_smp_result setup_smp8(int needs_reset) } val = pci_read_config32(NODE_HT(7), 0x6c); byte = (val>>2) & 0x3; /* get default link on 7 to 4*/ - print_linkn("(6,4) byte=", byte); + print_linkn("(6,4) link=", byte); setup_row_local(7,6); setup_remote_row_direct(6, 4, byte); @@ -1202,7 +1202,7 @@ static struct setup_smp_result setup_smp8(int needs_reset) val = pci_read_config32(NODE_HT(7), 0x6c); byte = (val>>2) & 0x3; /* get default link on 7 to 5*/ - print_linkn("(7,5) byte=", byte); + print_linkn("(7,5) link=", byte); setup_row_local(7,7); setup_remote_row_direct(7, 5, byte); @@ -1213,7 +1213,7 @@ static struct setup_smp_result setup_smp8(int needs_reset) setup_temp_row(4,7); val = pci_read_config32(NODE_HT(7), 0x6c); byte = (val>>2) & 0x3; /* get default link on 7 to 4*/ - print_linkn("(7,4) byte=", byte); + print_linkn("(7,4) link=", byte); setup_row_local(7,7); setup_remote_row_direct(7, 4, byte); /* till now 4-7, 7-4 done. */ @@ -1226,7 +1226,7 @@ static struct setup_smp_result setup_smp8(int needs_reset) val = get_row(5,5); byte = ((val>>16) & 0xfe) - link_connection(5,3); byte = get_linkn_last(byte); - print_linkn("(5,7) byte=", byte); + print_linkn("(5,7) link=", byte); setup_row_direct(5, 7, byte); setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */ @@ -1240,7 +1240,7 @@ static struct setup_smp_result setup_smp8(int needs_reset) byte = ((val>>16) & 0xfe) - link_connection(5,3); byte = get_linkn_first(byte); - print_linkn("-->(5,7) byte=", byte); + print_linkn("-->(5,7) link=", byte); setup_row_direct(5, 7, byte); #if 0 setup_temp_row(0,1); /* temp. link between nodes 0 and 1 */ @@ -1254,7 +1254,7 @@ static struct setup_smp_result setup_smp8(int needs_reset) } val = pci_read_config32(NODE_HT(7), 0x6c); byte = (val>>2) & 0x3; /* get default link on 7 to 5*/ - print_linkn("(7,5) byte=", byte); + print_linkn("(7,5) link=", byte); setup_remote_row_direct(7, 5, byte); /*Till now 57, 75 done */ @@ -1262,14 +1262,14 @@ static struct setup_smp_result setup_smp8(int needs_reset) val = get_row(5,5); byte = ((val>>16) & 0xfe) - link_connection(5,3) - link_connection(5,7); byte = get_linkn_first(byte); - print_linkn("(5,6) byte=", byte); + print_linkn("(5,6) link=", byte); setup_row_direct(5, 6, byte); /* init 6,7 */ val = get_row(6,6); byte = ((val>>16) & 0xfe) - link_connection(6,4); byte = get_linkn_last(byte); - print_linkn("(6,7) byte=", byte); + print_linkn("(6,7) link=", byte); setup_row_direct(6, 7, byte); for(byte=0; byte<6; byte+=2) { @@ -1282,7 +1282,7 @@ static struct setup_smp_result setup_smp8(int needs_reset) val = get_row(6,6); byte = ((val>>16) & 0xfe) - link_connection(6,4); byte = get_linkn_first(byte); - print_linkn("-->(6,7) byte=", byte); + print_linkn("-->(6,7) link=", byte); setup_row_direct(6, 7, byte); #if 0 @@ -1295,7 +1295,7 @@ static struct setup_smp_result setup_smp8(int needs_reset) } val = pci_read_config32(NODE_HT(7), 0x6c); byte = (val>>2) & 0x3; /* get default link on 7 to 6*/ - print_linkn("(7,6) byte=", byte); + print_linkn("(7,6) link=", byte); setup_remote_row_direct(7, 6, byte); /* Till now 67, 76 done*/ @@ -1304,7 +1304,7 @@ static struct setup_smp_result setup_smp8(int needs_reset) val = get_row(6,6); byte = ((val>>16) & 0xfe) - link_connection(6,4) - link_connection(6,7); byte = get_linkn_first(byte); - print_linkn("(6,5) byte=", byte); + print_linkn("(6,5) link=", byte); setup_row_direct(6, 5, byte); #endif @@ -1314,13 +1314,13 @@ static struct setup_smp_result setup_smp8(int needs_reset) val = get_row(6,6); byte = ((val>>16) & 0xfe) - link_connection(6,4); byte = get_linkn_first(byte); - print_linkn("(6,7) byte=", byte); + print_linkn("(6,7) link=", byte); setup_row_direct(6,7, byte); val = get_row(7,7); byte = ((val>>16) & 0xfe) - link_connection(7,5); byte = get_linkn_first(byte); - print_linkn("(7,6) byte=", byte); + print_linkn("(7,6) link=", byte); setup_row_direct(7,6, byte); #endif @@ -1463,7 +1463,7 @@ static void clear_dead_routes(unsigned nodes) for(row =0; row> 8) & 0xff)) << 16) | 0x0101); + fill_row(node, node, (((val & 0xff) | ((val >> 8) & 0xff)) << 16) | 0x0101); } } #endif /* CONFIG_MAX_CPUS > 1 */ @@ -1585,7 +1585,7 @@ static int optimize_link_read_pointers(unsigned nodes, int needs_reset) /* This works on an Athlon64 because unimplemented links return 0 */ reg = 0x98 + (link * 0x20); link_type = pci_read_config32(f0_dev, reg); - if ((link_type & 3) == 3) { + if ((link_type & 7) == 3) { cmd &= ~(0xff << (link *8)); cmd |= 0x25 << (link *8); } diff --git a/src/northbridge/amd/amdk8/incoherent_ht.c b/src/northbridge/amd/amdk8/incoherent_ht.c index 3255a0387..d947ea3d4 100644 --- a/src/northbridge/amd/amdk8/incoherent_ht.c +++ b/src/northbridge/amd/amdk8/incoherent_ht.c @@ -1,12 +1,16 @@ -/* - This should be done by Eric - 2004.12 yhlu add multi ht chain dynamically support -*/ - +/* + This should be done by Eric + 2004.12 yhlu add multi ht chain dynamically support +*/ #include #include #include +static inline void print_linkn_in (const char *strval, uint8_t byteval) +{ + print_debug(strval); print_debug_hex8(byteval); print_debug("\r\n"); +} + static unsigned ht_lookup_slave_capability(device_t dev) { unsigned pos; @@ -44,7 +48,7 @@ static void ht_collapse_previous_enumeration(unsigned bus) { device_t dev; uint32_t id; - + /* Check if is already collapsed */ dev = PCI_DEV(bus, 0, 0); id = pci_read_config32(dev, PCI_VENDOR_ID); @@ -310,6 +314,65 @@ static int ht_setup_chainx(device_t udev, unsigned upos, unsigned bus) return reset_needed; } +static int optimize_link_read_pointer(unsigned node, unsigned linkn, uint8_t linkt, unsigned val) +{ + uint32_t dword, dword_old; + uint8_t link_type; + + /* This works on an Athlon64 because unimplemented links return 0 */ + dword = pci_read_config32(PCI_DEV(0,0x18+node,0), 0x98 + (linkn * 0x20)); + link_type = dword & 0xff; + + dword_old = dword = pci_read_config32(PCI_DEV(0,0x18+node,3), 0xdc); + + if ( (link_type & 7) == linkt ) { /* Coherent Link only linkt = 3, ncoherent = 7*/ + dword &= ~( 0xff<<(linkn *8) ); + dword |= val << (linkn *8); + } + + if (dword != dword_old) { + pci_write_config32(PCI_DEV(0,0x18+node,3), 0xdc, dword); + return 1; + } + + return 0; +} + +static int optimize_link_in_coherent(int ht_c_num) +{ + int reset_needed; + int i; + + reset_needed = 0; + + for (i = 0; i < ht_c_num; i++) { + uint32_t reg; + unsigned nodeid, linkn; + unsigned busn; + unsigned val; + + reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4); + + nodeid = ((reg & 0xf0)>>4); // nodeid + linkn = ((reg & 0xf00)>>8); // link n + busn = (reg & 0xff0000)>>16; //busn + + reg = pci_read_config32( PCI_DEV(busn, 1, 0), PCI_VENDOR_ID); + if ( (reg & 0xffff) == PCI_VENDOR_ID_AMD) { + val = 0x25; + } else if ( (reg & 0xffff) == 0x10de ) { + val = 0x25;//??? + } else { + continue; + } + + reset_needed |= optimize_link_read_pointer(nodeid, linkn, 0x07, val); + + } + + return reset_needed; +} + static int ht_setup_chains(int ht_c_num) { /* Assumption the HT chain that is bus 0 has the HT I/O Hub on it. @@ -342,25 +405,19 @@ static int ht_setup_chains(int ht_c_num) dword &= ~(0xffff<<8); dword |= (reg & 0xffff0000)>>8; pci_write_config32( PCI_DEV(0, devpos,0), regpos , dword); - -#if 0 - dump_pci_devices_on_bus(busn); -#endif /* Make certain the HT bus is not enumerated */ ht_collapse_previous_enumeration(busn); upos = ((reg & 0xf00)>>8) * 0x20 + 0x80; udev = PCI_DEV(0, devpos, 0); - -#if 0 - dump_pci_devices_on_bus(busn); -#endif reset_needed |= ht_setup_chainx(udev,upos,busn ); } + reset_needed |= optimize_link_in_coherent(ht_c_num); + return reset_needed; } @@ -372,20 +429,22 @@ static int ht_setup_chains_x(void) unsigned next_busn; int ht_c_num; int nodes; - - // read PCI_DEV(0,0x18,0) 0x64 bit [8:9] to find out SbLink m + + /* read PCI_DEV(0,0x18,0) 0x64 bit [8:9] to find out SbLink m */ reg = pci_read_config32(PCI_DEV(0, 0x18, 0), 0x64); - //update PCI_DEV(0, 0x18, 1) 0xe0 to 0x05000m03, and next_busn=5+1; + /* update PCI_DEV(0, 0x18, 1) 0xe0 to 0x05000m03, and next_busn=5+1 */ + print_linkn_in("SBLink=", ((reg>>8) & 3) ); tempreg = 3 | ( 0<<4) | (((reg>>8) & 3)<<8) | (0<<16)| (5<<24); pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0, tempreg); - next_busn=5+1; // 0 will be used ht chain with SB we need to keep SB in bus0 in auto stage - // clean others + + next_busn=5+1; /* 0 will be used ht chain with SB we need to keep SB in bus0 in auto stage*/ + /* clean others */ for(ht_c_num=1;ht_c_num<4; ht_c_num++) { pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4, 0); } - - nodes = ((pci_read_config32(PCI_DEV(0, 0x18, 0), 0x60)>>4) & 7) + 1; + nodes = ((pci_read_config32(PCI_DEV(0, 0x18, 0), 0x60)>>4) & 7) + 1; + for(nodeid=0; nodeid