PCI配置空间寄存器 - 写值



我正在为自我制作的操作系统开发网络驱动程序(RTL8139),并在为PCI配置空间寄存器编写值时存在问题。

我想更改中断线(Offset 0x3c)的值以获取另一个IRQ号码,并启用命令寄存器的总线主(设置位2)(Offset 0x04)。
当我回复值时,我会发现我的值正确编写。但是,而不是使用新的IRQ号码(在我的情况6中)使用旧值(11)。
也无法使用DMA的总线大师(我想发送的数据包具有正确的尺寸(由IO-PORT设置),但它们没有内容(所有值只有0个值0,perceceive Buffer都在物理内存上,并且有非零值)。在我仔细检查物理地址后,这总是按照预期的方式使用。我需要让网络控制器访问我的物理内存,而我的接收/接收缓冲区则为。对于RTL8139)

我必须做其他事情以确认我对PCI设备的更改吗?

作为仿真器,我使用qemu。

用于阅读/写作,我写了以下功能:

uint16_t pci_read_word(uint16_t bus, uint16_t slot, uint16_t func, uint16_t offset)
{
 uint64_t address;
 uint64_t lbus = (uint64_t)bus;
 uint64_t lslot = (uint64_t)slot;
 uint64_t lfunc = (uint64_t)func;
 uint16_t tmp = 0;
 address = (uint64_t)((lbus << 16) | (lslot << 11) |
                   (lfunc << 8) | (offset & 0xfc) | ((uint32_t)0x80000000));
 outportl (0xCF8, address);
 tmp = (uint16_t)((inportl (0xCFC) >> ((offset & 2) * 8)) & 0xffff);
 return (tmp);
}
uint16_t pci_write_word(uint16_t bus, uint16_t slot, uint16_t func, uint16_t offset, uint16_t data)
{
 uint64_t address;
 uint64_t lbus = (uint64_t)bus;
 uint64_t lslot = (uint64_t)slot;
 uint64_t lfunc = (uint64_t)func;
 uint32_t tmp = 0;
 address = (uint64_t)((lbus << 16) | (lslot << 11) |
                   (lfunc << 8) | (offset & 0xfc) | ((uint32_t)0x80000000));
 outportl (0xCF8, address);
 tmp = (inportl (0xCFC));
 tmp &= ~(0xFFFF << ((offset & 0x2)*8)); // reset the word at the offset
 tmp |= data << ((offset & 0x2)*8); // write the data at the offset
 outportl (0xCF8, address); // set address again just to be sure
 outportl(0xCFC,tmp); // write data
 return pci_read_word(bus,slot,func,offset); // read back data;
}

我希望有人可以帮助我。

"中断线"字段(在PCI配置空间中的Offset 0x03c)实际上无能为力。

全文

PCI卡最多可以在PCI插槽上使用4个" PCI IRQ";并使用它们(因此,如果您有十个PCI卡,所有的PCI卡都有一个IRQ,那么它们都将在插槽中使用第一个PCI IRQ)。

有一个棘手的"理发杆"布置,可以将"插槽的pci irq"连接到"主机控制器处的pci irq",旨在减少IRQ共享。如果您有10张PCI卡,它们都有一个IRQ,则它们都将在插槽上使用第一个PCI IRQ,但是每个PCI插槽的第一个IRQ将连接到主机控制器的其他PCI IRQ。所有这些都是坚硬的,无法通过软件更改。

使事情变得更复杂;为了将PCI IRQ(从PCI主机控制器)连接到旧版PIC芯片,添加了一种特殊的" PCI IRQ路由器"。从理论上讲,可以通过软件更改" PCI IRQ路由器"的配置(如果您可以找到描述描述" PCI IRQ路由器"位置,功能和限制的表格的文档。

)。 )。

如果没有固件的帮助,则操作系统将不可能找出PCI设备实际使用的PIC芯片输入。因此,该固件在启动过程中将其弄清楚,然后将" PIC芯片输入号"存储在某个地方以供操作系统找到。这就是"中断线"寄存器的内容 - 它只是一个8位寄存器,可以存储您喜欢的任何东西(BIOS/固件用于存储" PIC芯片输入号码")。

最新更新