Eric,
Great, it works. Even normal scan it can find out 8151.
But the bus number is funny, I may need to update bus number mptable.c and irq_table.c and reset.c
I wonder if 8151 on CPU 1 and 8131/8111 on CPU0. is the amdk8_scan_root_bus called two times? If so, you may keep the
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); }
Regards
YH.
-----邮件原件----- 发件人: ebiederman@lnxi.com [mailto:ebiederman@lnxi.com] 发送时间: 2003年12月5日 15:26 收件人: YhLu 抄送: ron minnich; Stefan Reinauer; linuxbios@clustermatic.org 主题: Re: Tyan S2885
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
YhLu YhLu@tyan.com writes:
Eric,
Great, it works. Even normal scan it can find out 8151.
But the bus number is funny, I may need to update bus number mptable.c and irq_table.c and reset.c
I wonder if 8151 on CPU 1 and 8131/8111 on CPU0. is the amdk8_scan_root_bus called two times? If so, you may keep the
amdk8_scan_root_bus is always only called once. It just finds the cpus.
It recurses into amdk8_scan_chains which actually finds all of the busses.
So it is ok to zap everything in amdk8_scan_root_bus. But it may be a little more elegant to zap just what we need in amdk8_scan_root_bus.
Eric