gpt4 book ai didi

c - PCIE 区域未对齐,且不一致

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:18:41 31 4
gpt4 key购买 nike

我正在为 openwrt 开发一个 PCIE 设备驱动程序,在尝试访问定时器中断中的 io 内存时遇到了数据总线错误,我在 last question 中提到过.经过大量研究,我想我可能找到了原因,但我无法解决。以下是我的烦恼。

上周我发现 pcie 区域大小可能在系统启动期间发生了变化。 bar0 的区域大小在我的驱动程序中是 4096(从 pci_resource_len 返回),在 lspci -vv 中区域大小是 4097,这打破了 linux 内核的页面大小。通过阅读 pciutil 的源代码,我发现 lspci 命令从 /sys/devices/pci0000:00/0000:00:00.0/resouce 文件中获取 pcie 信息。所以我删除了所有自定义组件并在我的路由器上运行原始的 openwrt。通过cat/sys/devices/pci0000:00/0000:00:00.0/resouce,结果第一行(bar0)为

0x0000000010008000 0x0000000010009000 0x0000000000040200

另外,我还查看了/proc/iomem的内容,与PCIE相关的内容是

10000000-13ffffff : mem_base
10000000-13ffffff : PCI memory space
10000000-10007fff : 0000:00:00.0
10008000-10008fff : 0000:00:00.0

super 奇怪,上面两个文件指示的bar0的区域大小不一样!按照PCIE的机制,region size应该是2的次方,region size怎么变成4097了?

最佳答案

在花了数周阅读 linux 内核源代码后,我发现这是 linux 内核 4.4.14 的一个错误。

/sys/devices/pci0000:00/0000:00:00.0/resouce的内容是通过文件drivers/pci/中的函数resource_show生成的pci-sysfs.c。相关代码为

for (i = 0; i < max; i++) {
struct resource *res = &pci_dev->resource[i];
pci_resource_to_user(pci_dev, i, res, &start, &end);
str += sprintf(str, "0x%016llx 0x%016llx 0x%016llx\n",
(unsigned long long)start,
(unsigned long long)end,
(unsigned long long)res->flags);
}

实际调用的函数pci_resource_to_user位于arch/mips/include/asm/pci.h

static inline void pci_resource_to_user(const struct pci_dev *dev, int bar,
const struct resource *rsrc, resource_size_t *start,
resource_size_t *end)
{
phys_addr_t size = resource_size(rsrc);

*start = fixup_bigphys_addr(rsrc->start, size);
*end = rsrc->start + size;
}

*end计算错误,应替换为

*end = rsrc->start + size - (size ? 1 : 0)

关于c - PCIE 区域未对齐,且不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47087713/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com