diff options
Diffstat (limited to 'src/northbridge/amd/amdk8/incoherent_ht.c')
-rw-r--r-- | src/northbridge/amd/amdk8/incoherent_ht.c | 571 |
1 files changed, 287 insertions, 284 deletions
diff --git a/src/northbridge/amd/amdk8/incoherent_ht.c b/src/northbridge/amd/amdk8/incoherent_ht.c index 58f06468ed..2514084250 100644 --- a/src/northbridge/amd/amdk8/incoherent_ht.c +++ b/src/northbridge/amd/amdk8/incoherent_ht.c @@ -8,7 +8,7 @@ #include <device/hypertransport_def.h> #ifndef K8_HT_FREQ_1G_SUPPORT - #define K8_HT_FREQ_1G_SUPPORT 0 + #define K8_HT_FREQ_1G_SUPPORT 0 #endif #ifndef K8_SCAN_PCI_BUS @@ -16,20 +16,20 @@ #endif #ifndef K8_ALLOCATE_IO_RANGE - #define K8_ALLOCATE_IO_RANGE 0 + #define K8_ALLOCATE_IO_RANGE 0 #endif -// Do we need allocate MMIO? Current We direct last 64M to sblink only, We can not lose access to last 4M range to ROM +// Do we need allocate MMIO? Current We direct last 64M to sblink only, We can not lose access to last 4M range to ROM #ifndef K8_ALLOCATE_MMIO_RANGE - #define K8_ALLOCATE_MMIO_RANGE 0 + #define K8_ALLOCATE_MMIO_RANGE 0 #endif static inline void print_linkn_in (const char *strval, uint8_t byteval) { #if CONFIG_USE_PRINTK_IN_CAR - printk_debug("%s%02x\r\n", strval, byteval); + printk_debug("%s%02x\r\n", strval, byteval); #else - print_debug(strval); print_debug_hex8(byteval); print_debug("\r\n"); + print_debug(strval); print_debug_hex8(byteval); print_debug("\r\n"); #endif } @@ -67,13 +67,13 @@ static uint8_t ht_lookup_capability(device_t dev, uint16_t val) } static uint8_t ht_lookup_slave_capability(device_t dev) -{ +{ return ht_lookup_capability(dev, 0); // Slave/Primary Interface Block Format } static uint8_t ht_lookup_host_capability(device_t dev) { - return ht_lookup_capability(dev, 1); // Host/Secondary Interface Block Format + return ht_lookup_capability(dev, 1); // Host/Secondary Interface Block Format } static void ht_collapse_previous_enumeration(uint8_t bus, unsigned offset_unitid) @@ -91,12 +91,12 @@ static void ht_collapse_previous_enumeration(uint8_t bus, unsigned offset_unitid /* Check if is already collapsed */ if((!offset_unitid) || (offset_unitid && (!((HT_CHAIN_END_UNITID_BASE == 0) && (HT_CHAIN_END_UNITID_BASE <HT_CHAIN_UNITID_BASE))))) { dev = PCI_DEV(bus, 0, 0); - id = pci_read_config32(dev, PCI_VENDOR_ID); - if ( ! ( (id == 0xffffffff) || (id == 0x00000000) || - (id == 0x0000ffff) || (id == 0xffff0000) ) ) { - return; - } - } + id = pci_read_config32(dev, PCI_VENDOR_ID); + if (!((id == 0xffffffff) || (id == 0x00000000) || + (id == 0x0000ffff) || (id == 0xffff0000))) { + return; + } + } /* Spin through the devices and collapse any previous * hypertransport enumeration. @@ -105,13 +105,13 @@ static void ht_collapse_previous_enumeration(uint8_t bus, unsigned offset_unitid uint32_t id; uint8_t pos; uint16_t flags; - + id = pci_read_config32(dev, PCI_VENDOR_ID); if ((id == 0xffffffff) || (id == 0x00000000) || (id == 0x0000ffff) || (id == 0xffff0000)) { continue; } - + pos = ht_lookup_slave_capability(dev); if (!pos) { continue; @@ -145,23 +145,24 @@ static uint16_t ht_read_freq_cap(device_t dev, uint8_t pos) if (id == (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_AMD_8151_SYSCTRL << 16))) { freq_cap &= ~(1 << HT_FREQ_800Mhz); return freq_cap; - } - + } + /* AMD K8 Unsupported 1Ghz? */ if (id == (PCI_VENDOR_ID_AMD | (0x1100 << 16))) { - #if K8_HT_FREQ_1G_SUPPORT == 1 - #if K8_REV_F_SUPPORT == 0 - if (is_cpu_pre_e0()) { // only E0 later support 1GHz + #if K8_HT_FREQ_1G_SUPPORT == 1 + #if K8_REV_F_SUPPORT == 0 + if (is_cpu_pre_e0()) { // only E0 later support 1GHz freq_cap &= ~(1 << HT_FREQ_1000Mhz); } #endif - #else - freq_cap &= ~(1 << HT_FREQ_1000Mhz); + #else + freq_cap &= ~(1 << HT_FREQ_1000Mhz); #endif } return freq_cap; } + static uint8_t ht_read_width_cap(device_t dev, uint8_t pos) { uint8_t width_cap = pci_read_config8(dev, pos); @@ -176,12 +177,13 @@ static uint8_t ht_read_width_cap(device_t dev, uint8_t pos) width_cap &= 0x88; } } - + return width_cap; - + } + #define LINK_OFFS(CTRL, WIDTH,FREQ,FREQ_CAP) \ - (((CTRL & 0xff) << 24) | ((WIDTH & 0xff) << 16) | ((FREQ & 0xff) << 8) | (FREQ_CAP & 0xFF)) + (((CTRL & 0xff) << 24) | ((WIDTH & 0xff) << 16) | ((FREQ & 0xff) << 8) | (FREQ_CAP & 0xFF)) #define LINK_CTRL(OFFS) ((OFFS >> 24) & 0xFF) #define LINK_WIDTH(OFFS) ((OFFS >> 16) & 0xFF) @@ -189,19 +191,19 @@ static uint8_t ht_read_width_cap(device_t dev, uint8_t pos) #define LINK_FREQ_CAP(OFFS) ((OFFS) & 0xFF) #define PCI_HT_HOST_OFFS LINK_OFFS( \ - PCI_HT_CAP_HOST_CTRL, \ + PCI_HT_CAP_HOST_CTRL, \ PCI_HT_CAP_HOST_WIDTH, \ PCI_HT_CAP_HOST_FREQ, \ PCI_HT_CAP_HOST_FREQ_CAP) #define PCI_HT_SLAVE0_OFFS LINK_OFFS( \ - PCI_HT_CAP_SLAVE_CTRL0, \ + PCI_HT_CAP_SLAVE_CTRL0, \ PCI_HT_CAP_SLAVE_WIDTH0, \ PCI_HT_CAP_SLAVE_FREQ0, \ PCI_HT_CAP_SLAVE_FREQ_CAP0) #define PCI_HT_SLAVE1_OFFS LINK_OFFS( \ - PCI_HT_CAP_SLAVE_CTRL1, \ + PCI_HT_CAP_SLAVE_CTRL1, \ PCI_HT_CAP_SLAVE_WIDTH1, \ PCI_HT_CAP_SLAVE_FREQ1, \ PCI_HT_CAP_SLAVE_FREQ_CAP1) @@ -280,22 +282,23 @@ static int ht_optimize_link( return needs_reset; } + #if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1) #if RAMINIT_SYSINFO == 1 static void ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned offset_unitid, struct sys_info *sysinfo); -static int scan_pci_bus( unsigned bus , struct sys_info *sysinfo) +static int scan_pci_bus( unsigned bus , struct sys_info *sysinfo) #else static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned offset_unitid); static int scan_pci_bus( unsigned bus) #endif { - /* - here we already can access PCI_DEV(bus, 0, 0) to PCI_DEV(bus, 0x1f, 0x7) - So We can scan these devices to find out if they are bridge - If it is pci bridge, We need to set busn in bridge, and go on - For ht bridge, We need to set the busn in bridge and ht_setup_chainx, and the scan_pci_bus - */ + /* + here we already can access PCI_DEV(bus, 0, 0) to PCI_DEV(bus, 0x1f, 0x7) + So We can scan these devices to find out if they are bridge + If it is pci bridge, We need to set busn in bridge, and go on + For ht bridge, We need to set the busn in bridge and ht_setup_chainx, and the scan_pci_bus + */ unsigned int devfn; unsigned new_bus; unsigned max_bus; @@ -314,85 +317,85 @@ static int scan_pci_bus( unsigned bus) new_bus = bus; - for (devfn = 0; devfn <= 0xff; devfn++) { - uint8_t hdr_type; - uint16_t class; + for (devfn = 0; devfn <= 0xff; devfn++) { + uint8_t hdr_type; + uint16_t class; uint32_t buses; device_t dev; uint16_t cr; dev = PCI_DEV((bus & 0xff), ((devfn>>3) & 0x1f), (devfn & 0x7)); - hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE); - class = pci_read_config16(dev, PCI_CLASS_DEVICE); + hdr_type = pci_read_config8(dev, PCI_HEADER_TYPE); + class = pci_read_config16(dev, PCI_CLASS_DEVICE); switch(hdr_type & 0x7f) { /* header type */ - case PCI_HEADER_TYPE_BRIDGE: - if (class != PCI_CLASS_BRIDGE_PCI) goto bad; + case PCI_HEADER_TYPE_BRIDGE: + if (class != PCI_CLASS_BRIDGE_PCI) goto bad; /* set the bus range dev */ - /* Clear all status bits and turn off memory, I/O and master enables. */ - cr = pci_read_config16(dev, PCI_COMMAND); - pci_write_config16(dev, PCI_COMMAND, 0x0000); - pci_write_config16(dev, PCI_STATUS, 0xffff); + /* Clear all status bits and turn off memory, I/O and master enables. */ + cr = pci_read_config16(dev, PCI_COMMAND); + pci_write_config16(dev, PCI_COMMAND, 0x0000); + pci_write_config16(dev, PCI_STATUS, 0xffff); - buses = pci_read_config32(dev, PCI_PRIMARY_BUS); + buses = pci_read_config32(dev, PCI_PRIMARY_BUS); - buses &= 0xff000000; + buses &= 0xff000000; new_bus++; - buses |= (((unsigned int) (bus & 0xff) << 0) | - ((unsigned int) (new_bus & 0xff) << 8) | - ((unsigned int) max_bus << 16)); - pci_write_config32(dev, PCI_PRIMARY_BUS, buses); - + buses |= (((unsigned int) (bus & 0xff) << 0) | + ((unsigned int) (new_bus & 0xff) << 8) | + ((unsigned int) max_bus << 16)); + pci_write_config32(dev, PCI_PRIMARY_BUS, buses); + /* here we need to figure out if dev is a ht bridge if it is ht bridge, we need to call ht_setup_chainx at first - Not verified --- yhlu + Not verified --- yhlu */ uint8_t upos; - upos = ht_lookup_host_capability(dev); // one func one ht sub - if (upos) { // sub ht chain + upos = ht_lookup_host_capability(dev); // one func one ht sub + if (upos) { // sub ht chain uint8_t busn; busn = (new_bus & 0xff); - /* Make certain the HT bus is not enumerated */ - ht_collapse_previous_enumeration(busn, 0); + /* Make certain the HT bus is not enumerated */ + ht_collapse_previous_enumeration(busn, 0); /* scan the ht chain */ #if RAMINIT_SYSINFO == 1 - ht_setup_chainx(dev,upos,busn, 0, sysinfo); // don't need offset unitid + ht_setup_chainx(dev,upos,busn, 0, sysinfo); // don't need offset unitid #else new_bus |= (ht_setup_chainx(dev, upos, busn, 0)<<16); // store reset_needed to upword #endif - } - - #if RAMINIT_SYSINFO == 1 + } + + #if RAMINIT_SYSINFO == 1 new_bus = scan_pci_bus(new_bus, sysinfo); #else new_bus = scan_pci_bus(new_bus); #endif /* set real max bus num in that */ - buses = (buses & 0xff00ffff) | - ((unsigned int) (new_bus & 0xff) << 16); - pci_write_config32(dev, PCI_PRIMARY_BUS, buses); + buses = (buses & 0xff00ffff) | + ((unsigned int) (new_bus & 0xff) << 16); + pci_write_config32(dev, PCI_PRIMARY_BUS, buses); pci_write_config16(dev, PCI_COMMAND, cr); - break; - default: - bad: + break; + default: + bad: ; - } - - /* if this is not a multi function device, - * or the device is not present don't waste - * time probing another function. - * Skip to next device. - */ - if ( ((devfn & 0x07) == 0x00) && ((hdr_type & 0x80) != 0x80)) - { - devfn += 0x07; - } - } - - return new_bus; + } + + /* if this is not a multi function device, + * or the device is not present don't waste + * time probing another function. + * Skip to next device. + */ + if ( ((devfn & 0x07) == 0x00) && ((hdr_type & 0x80) != 0x80)) + { + devfn += 0x07; + } + } + + return new_bus; } #endif @@ -412,9 +415,9 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned of #endif #if HT_CHAIN_END_UNITID_BASE != 0x20 - //let't record the device of last ht device, So we can set the Unitid to HT_CHAIN_END_UNITID_BASE - unsigned real_last_unitid; - uint8_t real_last_pos; + //let't record the device of last ht device, So we can set the Unitid to HT_CHAIN_END_UNITID_BASE + unsigned real_last_unitid; + uint8_t real_last_pos; int ht_dev_num = 0; uint8_t end_used = 0; #endif @@ -428,50 +431,50 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned of uint16_t flags, ctrl; uint8_t count; unsigned offs; - + /* Wait until the link initialization is complete */ do { ctrl = pci_read_config16(udev, upos + LINK_CTRL(uoffs)); /* Is this the end of the hypertransport chain? */ if (ctrl & (1 << 6)) { - goto end_of_chain; + goto end_of_chain; } if (ctrl & ((1 << 4) | (1 << 8))) { - /* - * Either the link has failed, or we have - * a CRC error. - * Sometimes this can happen due to link - * retrain, so lets knock it down and see - * if its transient - */ + /* + * Either the link has failed, or we have + * a CRC error. + * Sometimes this can happen due to link + * retrain, so lets knock it down and see + * if its transient + */ ctrl |= ((1 << 4) | (1 <<8)); // Link fail + Crc - pci_write_config16(udev, upos + LINK_CTRL(uoffs), ctrl); - ctrl = pci_read_config16(udev, upos + LINK_CTRL(uoffs)); - if (ctrl & ((1 << 4) | (1 << 8))) { - print_err("Detected error on Hypertransport Link\n"); + pci_write_config16(udev, upos + LINK_CTRL(uoffs), ctrl); + ctrl = pci_read_config16(udev, upos + LINK_CTRL(uoffs)); + if (ctrl & ((1 << 4) | (1 << 8))) { + print_err("Detected error on Hypertransport Link\n"); break; - } + } } } while((ctrl & (1 << 5)) == 0); - + device_t dev = PCI_DEV(bus, 0, 0); last_unitid = next_unitid; id = pci_read_config32(dev, PCI_VENDOR_ID); /* If the chain is enumerated quit */ - if ( (id == 0xffffffff) || (id == 0x00000000) || - (id == 0x0000ffff) || (id == 0xffff0000)) + if ((id == 0xffffffff) || (id == 0x00000000) || + (id == 0x0000ffff) || (id == 0xffff0000)) { break; } pos = ht_lookup_slave_capability(dev); if (!pos) { - print_err("udev="); print_err_hex32(udev); - print_err("\tupos="); print_err_hex32(upos); - print_err("\tuoffs="); print_err_hex32(uoffs); + print_err("udev="); print_err_hex32(udev); + print_err("\tupos="); print_err_hex32(upos); + print_err("\tuoffs="); print_err_hex32(uoffs); print_err("\tHT link capability not found\r\n"); break; } @@ -481,17 +484,17 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned of if(offset_unitid) { if(next_unitid>= (bus ? 0x20:0x18) ) { if(!end_used) { - next_unitid = HT_CHAIN_END_UNITID_BASE; + next_unitid = HT_CHAIN_END_UNITID_BASE; end_used = 1; } else { goto out; } - - } - real_last_pos = pos; + + } + real_last_pos = pos; real_last_unitid = next_unitid; ht_dev_num++; - } + } #endif /* Update the Unitid of the current device */ flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS); @@ -499,23 +502,23 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned of flags |= next_unitid & 0x1f; pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags); - /* Compute the number of unitids consumed */ - count = (flags >> 5) & 0x1f; + /* Compute the number of unitids consumed */ + count = (flags >> 5) & 0x1f; /* Note the change in device number */ dev = PCI_DEV(bus, next_unitid, 0); - next_unitid += count; + next_unitid += count; /* Find which side of the ht link we are on, * by reading which direction our last write to PCI_CAP_FLAGS * came from. */ flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS); - offs = ((flags>>10) & 1) ? PCI_HT_SLAVE1_OFFS : PCI_HT_SLAVE0_OFFS; - + offs = ((flags>>10) & 1) ? PCI_HT_SLAVE1_OFFS : PCI_HT_SLAVE0_OFFS; + #if RAMINIT_SYSINFO == 1 - /* store the link pair here and we will Setup the Hypertransport link later, after we get final FID/VID */ + /* store the link pair here and we will Setup the Hypertransport link later, after we get final FID/VID */ { struct link_pair_st *link_pair = &sysinfo->link_pair[sysinfo->link_pair_num]; link_pair->udev = udev; @@ -539,32 +542,32 @@ static int ht_setup_chainx(device_t udev, uint8_t upos, uint8_t bus, unsigned of out: end_of_chain: ; - + #if HT_CHAIN_END_UNITID_BASE != 0x20 - if(offset_unitid && (ht_dev_num>1) && (real_last_unitid != HT_CHAIN_END_UNITID_BASE) && !end_used ) { - uint16_t flags; + if(offset_unitid && (ht_dev_num>1) && (real_last_unitid != HT_CHAIN_END_UNITID_BASE) && !end_used ) { + uint16_t flags; int i; - flags = pci_read_config16(PCI_DEV(bus,real_last_unitid,0), real_last_pos + PCI_CAP_FLAGS); - flags &= ~0x1f; - flags |= HT_CHAIN_END_UNITID_BASE & 0x1f; - pci_write_config16(PCI_DEV(bus, real_last_unitid, 0), real_last_pos + PCI_CAP_FLAGS, flags); + flags = pci_read_config16(PCI_DEV(bus,real_last_unitid,0), real_last_pos + PCI_CAP_FLAGS); + flags &= ~0x1f; + flags |= HT_CHAIN_END_UNITID_BASE & 0x1f; + pci_write_config16(PCI_DEV(bus, real_last_unitid, 0), real_last_pos + PCI_CAP_FLAGS, flags); - #if RAMINIT_SYSINFO == 1 + #if RAMINIT_SYSINFO == 1 // Here need to change the dev in the array for(i=0;i<sysinfo->link_pair_num;i++) - { - struct link_pair_st *link_pair = &sysinfo->link_pair[i]; - if(link_pair->udev == PCI_DEV(bus, real_last_unitid, 0)) { + { + struct link_pair_st *link_pair = &sysinfo->link_pair[i]; + if(link_pair->udev == PCI_DEV(bus, real_last_unitid, 0)) { link_pair->udev = PCI_DEV(bus, HT_CHAIN_END_UNITID_BASE, 0); continue; } - if(link_pair->dev == PCI_DEV(bus, real_last_unitid, 0)) { - link_pair->dev = PCI_DEV(bus, HT_CHAIN_END_UNITID_BASE, 0); - } - } + if(link_pair->dev == PCI_DEV(bus, real_last_unitid, 0)) { + link_pair->dev = PCI_DEV(bus, HT_CHAIN_END_UNITID_BASE, 0); + } + } #endif - } + } #endif #if RAMINIT_SYSINFO == 0 @@ -581,55 +584,55 @@ static int ht_setup_chain(device_t udev, unsigned upos) { unsigned offset_unitid = 0; #if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20)) - offset_unitid = 1; + offset_unitid = 1; #endif - /* Assumption the HT chain that is bus 0 has the HT I/O Hub on it. - * On most boards this just happens. If a cpu has multiple - * non Coherent links the appropriate bus registers for the - * links needs to be programed to point at bus 0. - */ + /* Assumption the HT chain that is bus 0 has the HT I/O Hub on it. + * On most boards this just happens. If a cpu has multiple + * non Coherent links the appropriate bus registers for the + * links needs to be programed to point at bus 0. + */ - /* Make certain the HT bus is not enumerated */ - ht_collapse_previous_enumeration(0, 0); + /* Make certain the HT bus is not enumerated */ + ht_collapse_previous_enumeration(0, 0); #if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20)) - offset_unitid = 1; + offset_unitid = 1; #endif #if RAMINIT_SYSINFO == 1 ht_setup_chainx(udev, upos, 0, offset_unitid, sysinfo); #else - return ht_setup_chainx(udev, upos, 0, offset_unitid); + return ht_setup_chainx(udev, upos, 0, offset_unitid); #endif } static int optimize_link_read_pointer(uint8_t node, uint8_t linkn, uint8_t linkt, uint8_t 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; - - + + if ( (link_type & 7) == linkt ) { /* Coherent Link only linkt = 3, ncoherent = 7*/ dword_old = dword = pci_read_config32(PCI_DEV(0,0x18+node,3), 0xdc); 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_read_pointers_chain(uint8_t ht_c_num) { - int reset_needed; + int reset_needed; uint8_t i; reset_needed = 0; @@ -642,14 +645,14 @@ static int optimize_link_read_pointers_chain(uint8_t ht_c_num) unsigned devn = 1; #if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20)) - #if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1 - if(i==0) // to check if it is sb ht chain - #endif - devn = HT_CHAIN_UNITID_BASE; - #endif + #if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1 + if(i==0) // to check if it is sb ht chain + #endif + devn = HT_CHAIN_UNITID_BASE; + #endif 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 @@ -672,59 +675,59 @@ static int optimize_link_read_pointers_chain(uint8_t ht_c_num) static int set_ht_link_buffer_count(uint8_t node, uint8_t linkn, uint8_t linkt, unsigned val) { - uint32_t dword; - uint8_t link_type; + uint32_t dword; + uint8_t link_type; unsigned regpos; device_t dev; - /* This works on an Athlon64 because unimplemented links return 0 */ + /* This works on an Athlon64 because unimplemented links return 0 */ regpos = 0x98 + (linkn * 0x20); dev = PCI_DEV(0,0x18+node,0); - dword = pci_read_config32(dev, regpos); - link_type = dword & 0xff; + dword = pci_read_config32(dev, regpos); + link_type = dword & 0xff; - if ( (link_type & 0x7) == linkt ) { /* Coherent Link only linkt = 3, ncoherent = 7*/ + if ( (link_type & 0x7) == linkt ) { /* Coherent Link only linkt = 3, ncoherent = 7*/ regpos = 0x90 + (linkn * 0x20); - dword = pci_read_config32(dev, regpos ); + dword = pci_read_config32(dev, regpos ); - if (dword != val) { - pci_write_config32(dev, regpos, val); - return 1; - } + if (dword != val) { + pci_write_config32(dev, regpos, val); + return 1; + } } - return 0; + return 0; } static int set_ht_link_buffer_counts_chain(uint8_t ht_c_num, unsigned vendorid, unsigned val) { - int reset_needed; - uint8_t i; + int reset_needed; + uint8_t i; - reset_needed = 0; + reset_needed = 0; - for (i = 0; i < ht_c_num; i++) { - uint32_t reg; - uint8_t nodeid, linkn; - uint8_t busn; - unsigned devn; + for (i = 0; i < ht_c_num; i++) { + uint32_t reg; + uint8_t nodeid, linkn; + uint8_t busn; + unsigned devn; - reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4); - if((reg & 3) != 3) continue; // not enabled + reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4); + if((reg & 3) != 3) continue; // not enabled - nodeid = ((reg & 0xf0)>>4); // nodeid - linkn = ((reg & 0xf00)>>8); // link n - busn = (reg & 0xff0000)>>16; //busn + nodeid = ((reg & 0xf0)>>4); // nodeid + linkn = ((reg & 0xf00)>>8); // link n + busn = (reg & 0xff0000)>>16; //busn for(devn = 0; devn < 0x20; devn++) { - reg = pci_read_config32( PCI_DEV(busn, devn, 0), PCI_VENDOR_ID); //1? - if ( (reg & 0xffff) == vendorid ) { - reset_needed |= set_ht_link_buffer_count(nodeid, linkn, 0x07,val); + reg = pci_read_config32( PCI_DEV(busn, devn, 0), PCI_VENDOR_ID); //1? + if ( (reg & 0xffff) == vendorid ) { + reset_needed |= set_ht_link_buffer_count(nodeid, linkn, 0x07,val); break; - } + } } - } + } - return reset_needed; + return reset_needed; } @@ -734,13 +737,13 @@ static void ht_setup_chains(uint8_t ht_c_num, struct sys_info *sysinfo) static int ht_setup_chains(uint8_t ht_c_num) #endif { - /* Assumption the HT chain that is bus 0 has the HT I/O Hub on it. + /* Assumption the HT chain that is bus 0 has the HT I/O Hub on it. * On most boards this just happens. If a cpu has multiple * non Coherent links the appropriate bus registers for the * links needs to be programed to point at bus 0. */ - uint8_t upos; - device_t udev; + uint8_t upos; + device_t udev; uint8_t i; #if RAMINIT_SYSINFO == 0 @@ -760,29 +763,29 @@ static int ht_setup_chains(uint8_t ht_c_num) unsigned bus; #endif unsigned offset_unitid = 0; - + reg = pci_read_config32(PCI_DEV(0,0x18,1), 0xe0 + i * 4); //We need setup 0x94, 0xb4, and 0xd4 according to the reg devpos = ((reg & 0xf0)>>4)+0x18; // nodeid; it will decide 0x18 or 0x19 regpos = ((reg & 0xf00)>>8) * 0x20 + 0x94; // link n; it will decide 0x94 or 0xb4, 0x0xd4; busn = (reg & 0xff0000)>>16; - + dword = pci_read_config32( PCI_DEV(0, devpos, 0), regpos) ; dword &= ~(0xffff<<8); dword |= (reg & 0xffff0000)>>8; pci_write_config32( PCI_DEV(0, devpos,0), regpos , dword); - + #if ((HT_CHAIN_UNITID_BASE != 1) || (HT_CHAIN_END_UNITID_BASE != 0x20)) - #if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1 - if(i==0) // to check if it is sb ht chain - #endif - offset_unitid = 1; - #endif - - /* Make certain the HT bus is not enumerated */ - ht_collapse_previous_enumeration(busn, offset_unitid); + #if SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1 + if(i==0) // to check if it is sb ht chain + #endif + offset_unitid = 1; + #endif + + /* Make certain the HT bus is not enumerated */ + ht_collapse_previous_enumeration(busn, offset_unitid); upos = ((reg & 0xf00)>>8) * 0x20 + 0x80; udev = PCI_DEV(0, devpos, 0); @@ -794,10 +797,10 @@ static int ht_setup_chains(uint8_t ht_c_num) #endif #if (USE_DCACHE_RAM == 1) && (K8_SCAN_PCI_BUS == 1) - /* You can use use this in romcc, because there is function call in romcc, recursive will kill you */ - bus = busn; // we need 32 bit + /* You can use use this in romcc, because there is function call in romcc, recursive will kill you */ + bus = busn; // we need 32 bit #if RAMINIT_SYSINFO == 1 - scan_pci_bus(bus, sysinfo); + scan_pci_bus(bus, sysinfo); #else reset_needed |= (scan_pci_bus(bus)>>16); // take out reset_needed that stored in upword #endif @@ -821,30 +824,30 @@ static void ht_setup_chains_x(struct sys_info *sysinfo) #else static int ht_setup_chains_x(void) #endif -{ - uint8_t nodeid; - uint32_t reg; +{ + uint8_t nodeid; + uint32_t reg; uint32_t tempreg; - uint8_t next_busn; - uint8_t ht_c_num; + uint8_t next_busn; + uint8_t ht_c_num; uint8_t nodes; -#if K8_ALLOCATE_IO_RANGE == 1 +#if K8_ALLOCATE_IO_RANGE == 1 unsigned next_io_base; #endif - nodes = get_nodes(); - - /* 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=0x3f+1 */ + nodes = get_nodes(); + + /* 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=0x3f+1 */ print_linkn_in("SBLink=", ((reg>>8) & 3) ); #if RAMINIT_SYSINFO == 1 sysinfo->sblk = (reg>>8) & 3; sysinfo->sbbusn = 0; sysinfo->nodes = nodes; #endif - tempreg = 3 | ( 0<<4) | (((reg>>8) & 3)<<8) | (0<<16)| (0x3f<<24); - pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0, tempreg); + tempreg = 3 | ( 0<<4) | (((reg>>8) & 3)<<8) | (0<<16)| (0x3f<<24); + pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0, tempreg); next_busn=0x3f+1; /* 0 will be used ht chain with SB we need to keep SB in bus0 in auto stage*/ @@ -858,95 +861,95 @@ static int ht_setup_chains_x(void) #endif /* 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); + 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); #if K8_ALLOCATE_IO_RANGE == 1 /* io range allocation */ pci_write_config32(PCI_DEV(0, 0x18, 1), 0xc4 + ht_c_num * 8, 0); pci_write_config32(PCI_DEV(0, 0x18, 1), 0xc0 + ht_c_num * 8, 0); #endif - } - - for(nodeid=0; nodeid<nodes; nodeid++) { - device_t dev; - uint8_t linkn; - dev = PCI_DEV(0, 0x18+nodeid,0); - for(linkn = 0; linkn<3; linkn++) { - unsigned regpos; - regpos = 0x98 + 0x20 * linkn; - reg = pci_read_config32(dev, regpos); - if ((reg & 0x17) != 7) continue; /* it is not non conherent or not connected*/ + } + + for(nodeid=0; nodeid<nodes; nodeid++) { + device_t dev; + uint8_t linkn; + dev = PCI_DEV(0, 0x18+nodeid,0); + for(linkn = 0; linkn<3; linkn++) { + unsigned regpos; + regpos = 0x98 + 0x20 * linkn; + reg = pci_read_config32(dev, regpos); + if ((reg & 0x17) != 7) continue; /* it is not non conherent or not connected*/ print_linkn_in("NC node|link=", ((nodeid & 0xf)<<4)|(linkn & 0xf)); - tempreg = 3 | (nodeid <<4) | (linkn<<8); - /*compare (temp & 0xffff), with (PCI(0, 0x18, 1) 0xe0 to 0xec & 0xfffff) */ - for(ht_c_num=0;ht_c_num<4; ht_c_num++) { - reg = pci_read_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4); - if(((reg & 0xffff) == (tempreg & 0xffff)) || ((reg & 0xffff) == 0x0000)) { /*we got it*/ - break; - } - } - if(ht_c_num == 4) break; /*used up only 4 non conherent allowed*/ - /*update to 0xe0...*/ + tempreg = 3 | (nodeid <<4) | (linkn<<8); + /*compare (temp & 0xffff), with (PCI(0, 0x18, 1) 0xe0 to 0xec & 0xfffff) */ + for(ht_c_num=0;ht_c_num<4; ht_c_num++) { + reg = pci_read_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4); + if(((reg & 0xffff) == (tempreg & 0xffff)) || ((reg & 0xffff) == 0x0000)) { /*we got it*/ + break; + } + } + if(ht_c_num == 4) break; /*used up only 4 non conherent allowed*/ + /*update to 0xe0...*/ if((reg & 0xf) == 3) continue; /*SbLink so don't touch it */ print_linkn_in("\tbusn=", next_busn); - tempreg |= (next_busn<<16)|((next_busn+0x3f)<<24); - pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4, tempreg); + tempreg |= (next_busn<<16)|((next_busn+0x3f)<<24); + pci_write_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4, tempreg); next_busn+=0x3f+1; -#if K8_ALLOCATE_IO_RANGE == 1 +#if K8_ALLOCATE_IO_RANGE == 1 /* io range allocation */ - tempreg = nodeid | (linkn<<4) | ((next_io_base+0x3)<<12); //limit - pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC4 + ht_c_num * 8, tempreg); - tempreg = 3 /*| ( 3<<4)*/ | (next_io_base<<12); //base :ISA and VGA ? - pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC0 + ht_c_num * 8, tempreg); - next_io_base += 0x3+0x1; -#endif - - } - } - /*update 0xe0, 0xe4, 0xe8, 0xec from PCI_DEV(0, 0x18,1) to PCI_DEV(0, 0x19,1) to PCI_DEV(0, 0x1f,1);*/ - - for(nodeid = 1; nodeid<nodes; nodeid++) { - int i; - device_t dev; - dev = PCI_DEV(0, 0x18+nodeid,1); - for(i = 0; i< 4; i++) { - unsigned regpos; - regpos = 0xe0 + i * 4; - reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos); - pci_write_config32(dev, regpos, reg); - } + tempreg = nodeid | (linkn<<4) | ((next_io_base+0x3)<<12); //limit + pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC4 + ht_c_num * 8, tempreg); + tempreg = 3 /*| ( 3<<4)*/ | (next_io_base<<12); //base :ISA and VGA ? + pci_write_config32(PCI_DEV(0, 0x18, 1), 0xC0 + ht_c_num * 8, tempreg); + next_io_base += 0x3+0x1; +#endif + + } + } + /*update 0xe0, 0xe4, 0xe8, 0xec from PCI_DEV(0, 0x18,1) to PCI_DEV(0, 0x19,1) to PCI_DEV(0, 0x1f,1);*/ + + for(nodeid = 1; nodeid<nodes; nodeid++) { + int i; + device_t dev; + dev = PCI_DEV(0, 0x18+nodeid,1); + for(i = 0; i< 4; i++) { + unsigned regpos; + regpos = 0xe0 + i * 4; + reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos); + pci_write_config32(dev, regpos, reg); + } #if K8_ALLOCATE_IO_RANGE == 1 /* io range allocation */ - for(i = 0; i< 4; i++) { - unsigned regpos; - regpos = 0xc4 + i * 8; - reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos); - pci_write_config32(dev, regpos, reg); - } - for(i = 0; i< 4; i++) { - unsigned regpos; - regpos = 0xc0 + i * 8; - reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos); - pci_write_config32(dev, regpos, reg); - } -#endif - } - + for(i = 0; i< 4; i++) { + unsigned regpos; + regpos = 0xc4 + i * 8; + reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos); + pci_write_config32(dev, regpos, reg); + } + for(i = 0; i< 4; i++) { + unsigned regpos; + regpos = 0xc0 + i * 8; + reg = pci_read_config32(PCI_DEV(0, 0x18, 1), regpos); + pci_write_config32(dev, regpos, reg); + } +#endif + } + /* recount ht_c_num*/ uint8_t i=0; - for(ht_c_num=0;ht_c_num<4; ht_c_num++) { + for(ht_c_num=0;ht_c_num<4; ht_c_num++) { reg = pci_read_config32(PCI_DEV(0, 0x18, 1), 0xe0 + ht_c_num * 4); - if(((reg & 0xf) != 0x0)) { + if(((reg & 0xf) != 0x0)) { i++; } - } + } #if RAMINIT_SYSINFO == 1 sysinfo->ht_c_num = i; - ht_setup_chains(i, sysinfo); + ht_setup_chains(i, sysinfo); sysinfo->sbdn = get_sbdn(sysinfo->sbbusn); #else return ht_setup_chains(i); @@ -960,10 +963,10 @@ static int optimize_link_incoherent_ht(struct sys_info *sysinfo) // We need to use recorded link pair info to optimize the link int i; int reset_needed = 0; - + unsigned link_pair_num = sysinfo->link_pair_num; - for(i=0; i< link_pair_num; i++) { + for(i=0; i< link_pair_num; i++) { struct link_pair_st *link_pair= &sysinfo->link_pair[i]; reset_needed |= ht_optimize_link(link_pair->udev, link_pair->upos, link_pair->uoffs, link_pair->dev, link_pair->pos, link_pair->offs); } |