The Kernel pci_read_bases in drivers/pci/probe.c. has problem when size if bigger than 4G.
It will first check the 32 bit SPACE_ADDRESS, and pci_size will return 0, So it will skip that resource. And the pre-set values is ignored.
And later, it will try to allocate the value. It will fail.
I will produce one patch for you.
YH
-----Original Message----- From: linuxbios-bounces@linuxbios.org [mailto:linuxbios-bounces@linuxbios.org] On Behalf Of Lu, Yinghai Sent: Friday, November 03, 2006 11:46 AM To: myles@mouselemur.cs.byu.edu; LinuxBIOS Subject: Re: [LinuxBIOS] Disabled device help
Boot log?
In LinuxBIOS, there is CONFIG_PCI_64BIT_PREF_MEM, did you try to enable it in you MB Options.lb
In the kernel, there is pci_assign_unassigned_resources that try to allocate resource for some devices, and it could cause problem because Opteron could bave multi ht chain, Aka peer root bus, and every root bus need to have its own ioport_resource, and iomem_resource. But that only happen when BIOS is not allocating resource correctly. And LinuxBIOS does a good job, and every device have be handled properly.
In case, you have werid pci devices, you still can use pci_quirks in kernel to do some fix up.
YH
-----Original Message----- From: linuxbios-bounces@linuxbios.org [mailto:linuxbios-bounces@linuxbios.org] On Behalf Of Myles Watson Sent: Friday, November 03, 2006 11:02 AM To: 'LinuxBIOS' Subject: [LinuxBIOS] Disabled device help
My large device gets disabled somewhere in LinuxBIOS or the kernel. This is the encouraging line from LinuxBIOS telling me that the registers are indeed set correctly.
PCI: 05:01.0 18 <- [8000000000 - bfffffffff] prefmem64
Unfortunately, Linux sees something different and fails to allocate this region because it sees it at 00000080-000000bf and that conflicts with other things.
Does anyone have a pointer to where I should look for this problem? Has anyone else had problems with devices larger than 4GB?
Thanks, Myles
Please check the patch.
YH
-----Original Message----- From: linuxbios-bounces@linuxbios.org on behalf of Lu, Yinghai Sent: Fri 11/3/2006 5:01 PM To: myles@mouselemur.cs.byu.edu; LinuxBIOS Subject: Re: [LinuxBIOS] Disabled device help
The Kernel pci_read_bases in drivers/pci/probe.c. has problem when size if bigger than 4G.
It will first check the 32 bit SPACE_ADDRESS, and pci_size will return 0, So it will skip that resource. And the pre-set values is ignored.
And later, it will try to allocate the value. It will fail.
I will produce one patch for you.
YH
-----Original Message----- From: linuxbios-bounces@linuxbios.org [mailto:linuxbios-bounces@linuxbios.org] On Behalf Of Lu, Yinghai Sent: Friday, November 03, 2006 11:46 AM To: myles@mouselemur.cs.byu.edu; LinuxBIOS Subject: Re: [LinuxBIOS] Disabled device help
Boot log?
In LinuxBIOS, there is CONFIG_PCI_64BIT_PREF_MEM, did you try to enable it in you MB Options.lb
In the kernel, there is pci_assign_unassigned_resources that try to allocate resource for some devices, and it could cause problem because Opteron could bave multi ht chain, Aka peer root bus, and every root bus need to have its own ioport_resource, and iomem_resource. But that only happen when BIOS is not allocating resource correctly. And LinuxBIOS does a good job, and every device have be handled properly.
In case, you have werid pci devices, you still can use pci_quirks in kernel to do some fix up.
YH
-----Original Message----- From: linuxbios-bounces@linuxbios.org [mailto:linuxbios-bounces@linuxbios.org] On Behalf Of Myles Watson Sent: Friday, November 03, 2006 11:02 AM To: 'LinuxBIOS' Subject: [LinuxBIOS] Disabled device help
My large device gets disabled somewhere in LinuxBIOS or the kernel. This is the encouraging line from LinuxBIOS telling me that the registers are indeed set correctly.
PCI: 05:01.0 18 <- [8000000000 - bfffffffff] prefmem64
Unfortunately, Linux sees something different and fails to allocate this region because it sees it at 00000080-000000bf and that conflicts with other things.
Does anyone have a pointer to where I should look for this problem? Has anyone else had problems with devices larger than 4GB?
Thanks, Myles
Myles,
I can not commit the patch directly, So please apply that in your own tree.
YH
* Lu, Yinghai yinghai.lu@amd.com [061104 03:31]:
Myles,
I can not commit the patch directly, So please apply that in your own tree.
Is a similar patch required for amd 8xxx?
Content-Description: ck804_64bit_pref_mem.diff
ck804 64bit pref mem support
Signed-off-by: Yinghai Lu yinghai.lu@amd.com
Acked-by: Stefan Reinauer stepan@coresystems.de
Index: ck804_pci.c
--- ck804_pci.c (revision 2486) +++ ck804_pci.c (working copy) @@ -14,6 +14,10 @@ {
uint32_t dword; +#if CONFIG_PCI_64BIT_PREF_MEM == 1
- device_t pci_domain_dev;
- struct resource *mem1, *mem2;
+#endif
/* System error enable */ dword = pci_read_config32(dev, 0x04); @@ -34,8 +38,27 @@ pci_write_config32(dev, 0x4c, dword); #endif
+#if CONFIG_PCI_64BIT_PREF_MEM == 1
- pci_domain_dev = dev->bus->dev;
- while(pci_domain_dev) {
if(pci_domain_dev->path.type == DEVICE_PATH_PCI_DOMAIN) break;
pci_domain_dev = pci_domain_dev->bus->dev;
- }
- if(!pci_domain_dev) return; // impossiable
It should read "impossible" or better "impossible because we need a PCI domain"
but how can we end up without a pci domain on a ck804 mainboard? I would think this can only happen if the mainboard config file is wrong?
- mem1 = find_resource(pci_domain_dev, 1); // prefmem, it could be 64bit
- mem2 = find_resource(pci_domain_dev, 2); // mem
- if(mem1->base > mem2->base) {
dword = mem2->base & (0xffff0000UL);
printk_debug("PCI DOMAIN mem2 base = 0x%010Lx\n", mem2->base);
- } else {
dword = mem1->base & (0xffff0000UL);
printk_debug("PCI DOMAIN mem1 (prefmem) base = 0x%010Lx\n", mem1->base);
- }
+#else dword = dev_root.resource[1].base & (0xffff0000UL);
- printk_debug("dev_root mem base = 0x%010Lx\n", dev_root.resource[1].base);
- printk_debug("dev_root mem base = 0x%010Lx\n", dev_root.resource[1].base);
+#endif
printk_debug("[0x50] <-- 0x%08x\n", dword); pci_write_config32(dev, 0x50, dword); //TOM
amd8111, don't need that.
YH
Thanks a lot! It worked fine, except it missed the last 4GB of the allocation. This is an ugly way of getting it back. I'm not sure what the elegant way would be. The lower 32-bits need to be filled with ones in order for the space to be allocated correctly. Otherwise a 4GB allocation would show up as a one byte allocation.
Now /proc/iomem shows my device at 8000000000-bfffffffff
Myles
--- drivers/pci/probe.c 2006-11-06 09:23:03.000000000 -0700 +++ drivers/pci/probe_new.c 2006-11-06 10:17:08.000000000 -0700 @@ -203,7 +203,7 @@ res->end = res->start + sz; if (szhi) { /* This BAR needs > 4GB? Wow. */ - res->end |= (unsigned long)szhi<<32; + res->end |= ((unsigned long)szhi<<32|0xffffffffUL); } #else if (szhi) {
Please check the patch.
YH
The Kernel pci_read_bases in drivers/pci/probe.c. has problem when size if bigger than 4G.
It will first check the 32 bit SPACE_ADDRESS, and pci_size will return 0, So it will skip that resource. And the pre-set values is ignored.
And later, it will try to allocate the value. It will fail.
I will produce one patch for you.
YH
My large device gets disabled somewhere in LinuxBIOS or the kernel. This is the encouraging line from LinuxBIOS telling me that the registers are indeed set correctly.
PCI: 05:01.0 18 <- [8000000000 - bfffffffff] prefmem64
Unfortunately, Linux sees something different and fails to allocate this region because it sees it at 00000080-000000bf and that conflicts with other things.
Does anyone have a pointer to where I should look for this problem? Has anyone else had problems with devices larger than 4GB?
Thanks, Myles
res->end |= (unsigned long)szhi<<32;
res->end |= ((unsigned
long)szhi<<32|0xffffffffUL);
Should read
res->end |= ((uint64_t)szhi << 32) | 0xffffffff;
("long" is 32-bits on many platforms).
Segher