YhLu YhLu@tyan.com writes:
Eric,
I change amdk8_scan_root_bus to:
unsigned int amdk8_scan_root_bus(device_t root, unsigned int max) { unsigned reg; uint32_t value; /* Unmap all of the other pci busses */ printk_debug("\nbefore pci_scan_bus\n"); for(reg = 0xe0; reg <= 0xec; reg += 4) { value = f1_read_config32(reg); printk_debug("amdk8_scan_root_bus %0x = %0x max = %0x\n", reg,value,max); if((value>>24)>max) f1_write_config32(reg, 0); } for(reg = 0xe0; reg <= 0xec; reg += 4) { value = f1_read_config32(reg); printk_debug("amdk8_scan_root_bus %0x = %0x max = %0x\n", reg,value,max); }
max = pci_scan_bus(&root->link[0], PCI_DEVFN(0x18, 0), 0xff, max); printk_debug("after pci_scan_bus\n"); for(reg = 0xe0; reg <= 0xec; reg += 4) { value = f1_read_config32(reg); printk_debug("amdk8_scan_root_bus %0x = %0x max = %0x\n",
reg,value,max); }
return max;
}
I think as least you only need to clear the regs that contain bigger bus number than the next bus for scanning.
The result will be in the end.
The problems:
- It can not access 8151 on CPU link0 and so can not scan it
- The HT scan seems can not figure out and set the link and read/write
enable bit in e0. It set the e0 to 0x05050000
Doh. The Opteron is too forgiving when you only have one link. It makes this kind of debugging a pain. What I am doing should not work but it does in that case... My apologies, for missing this.
In amdk8_scan_chains() there is the snippet:
config_busses &= 0x0000ffff; config_busses |= ((dev->link[link].secondary) << 16) | ((dev->link[link].subordinate) << 24); f1_write_config32(config_reg, config_busses);
Which is the offending piece of code. It neither sets the link that we are supposed to go out, nor does it set the r/w enable bits. Ouch. It only works if those registers are pre programmed. So I think this should be:
config_busses &= 0x000fc88; config_busses |= (3 << 0) | /* rw enable, no device compare */ (( nodeid & 7) << 4) | (( link & 3 ) << 8) | ((dev->link[link].secondary) << 16) | ((dev->link[link].subordinate) << 24); f1_write_config32(config_reg, config_busses);
Eric