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(a)lnxi.com [mailto:ebiederman@lnxi.com]
发送时间: 2003年12月5日 15:26
收件人: YhLu
抄送: ron minnich; Stefan Reinauer; linuxbios(a)clustermatic.org
主题: Re: Tyan S2885
YhLu <YhLu(a)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:
> 1. It can not access 8151 on CPU link0 and so can not scan it
> 2. 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