What is the Base Address Register (BAR) in PCIe?

假如想象 提交于 2020-01-10 22:10:16

问题


After going through some basics documents what I understood is, Base Address Register is Address space which can be accessed by PCIe IP. PCIe IP can either transmit data in Base Address Register or it can write received data on to it.

Am I right? Or missing anything?


回答1:


I think this is a very basic question and I would suggest to read:

  • PCI Express Base 3.1 Specification (pcisig.com) or
  • PCI Express Technology 3.0 (MindShare Press) book

A Base Address Register (BAR) is used to:
- specify how much memory a device wants to be mapped into main memory, and
- after device enumeration, it holds the (base) address, where the mapped memory block begins.

A device can have up to six 32-bit BARs or combine two BARs to a 64-bit BAR.




回答2:


Linux kernel point of view

A good way to learn something is to interact with it, so let's use the Linux kernel for that.

Here is a minimal PCI example on a QEMU emulated device: https://github.com/cirosantilli/linux-kernel-module-cheat/blob/366b1c1af269f56d6a7e6464f2862ba2bc368062/kernel_module/pci.c

The first 64 bytes of the PCI configuration are standardized as:

Image from LDD3.

So we can see that there are 6 BARs. The wiki page then shows the contents of each BAR:

The region width requires a magic write however: How is a PCI / PCIe BAR size determined?

This memory is setup by the PCI device, and gives information to the kernel.

Each BAR corresponds to an address range that serves as a separate communication channel to the PCI device.

The length of each region is defined by the hardware, and communicated to software via the configuration registers.

Each region also has further hardware defined properties besides length, notably the memory type:

  • IORESOURCE_IO: must be accessed with inX and outX
  • IORESOURCE_MEM: must be accessed with ioreadX and iowriteX

Several Linux kernel PCI functions take the BAR as a parameter to identify which communication channel is to be used, e.g.:

mmio = pci_iomap(pdev, BAR, pci_resource_len(pdev, BAR));
pci_resource_flags(dev, BAR);
pci_resource_start(pdev, BAR);
pci_resource_end(pdev, BAR);

By looking into the QEMU device source code, we see that QEMU devices register those regions with:

memory_region_init_io(&edu->mmio, OBJECT(edu), &edu_mmio_ops, edu,
                "edu-mmio", 1 << 20);
pci_register_bar(pdev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &edu->mmio);

and it is clear that properties of the BAR are hardware defined, e.g. the BAR number 0, has type memory PCI_BASE_ADDRESS_SPACE_MEMORY, and the memory region is 1MiB long 1 << 20.

See also: http://wiki.osdev.org/PCI#Base_Address_Registers of course.




回答3:


BAR is record of the device address starting at memory.

root@Ubuntu:~$ lspci -s 00:04.0 -x
00:04.0 USB controller: Intel Corporation 82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (rev 10)
00: 86 80 cd 24 06 00 00 00 10 20 03 0c 10 00 00 00
10: 00 10 02 f3 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 f4 1a 00 11
30: 00 00 00 00 00 00 00 00 00 00 00 00 05 04 00 00

root@Ubuntu:~$ lspci -s 00:04.0 -v
00:04.0 USB controller: Intel Corporation 82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller (rev 10) (prog-if 20 [EHCI])
        Subsystem: Red Hat, Inc QEMU Virtual Machine
        Physical Slot: 4
        Flags: bus master, fast devsel, latency 0, IRQ 35
        Memory at f3021000 (32-bit, non-prefetchable) [size=4K]
        Kernel driver in use: ehci-pci
root@Ubuntu:~$ grep  00:04.0 /proc/iomem
  f3021000-f3021fff : 0000:00:04.0

0xfff equals to 4095, which is 4K. Memory starts at 0xf3021000 is this USB device seen by CPU. This address is init during BIOS and in this example it is on BAR0. Why is BAR0?

Before that, one need to understand PCI spec, especially the below, type 0 and type 1:

Notice the header type is both defined at 0x0c third field, that is how BARs differ. In this example, it is 00, which means it is type 0. Thus BAR0 stores the address, which is 00 10 02 f3.

One may wonder why this is not exactly f3021000, this is because lspci goes with Little Endian. What is Endian? One may need to read "Gulliver's Travels".

BAR0 generally has three states, uninitialized, all 1s, and written address. And we now in the third since the device already init. Bit 11 ~ 4 is set to 0 at uninitialized state; Bit 3 means NP when set to 0, P when set to 1; Bit 2 ~ 1 means 32 bit when set to 00, 64 bit when set to 10; Bit 0 means memory request when set to 0, IO request when set to 1.

0xf3021000
====>>>>
11110011000000100001000000000000

From this, we can know this device is 32-bit, non-prefetchable, memory request. The uninitialized address is 32 ~ 12, since 2 ^ 12 = 4K.

For more device and vendor, one can find via https://pcilookup.com/



来源:https://stackoverflow.com/questions/30190050/what-is-the-base-address-register-bar-in-pcie

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!