IO window parse analysis
In an ACPI based system, we parse the IO window configured in DSDT table, as
showed in this link.
We can see in pci_acpi_root_prepare_resources:
1 | pci_acpi_root_prepare_resources |
in acpi_pci_root_remap_iospace, CPU address of one PCIe IO window will be
mapped to PCI_IOBASE based system IO space, like below picture:
1 | PCI_IOBASE PCI_IOBASE + PCIE_IO_SIZE - 1 |
and offset between CPU VA and PCI_IOBASE will be stored in resource_entry,
which will be passed to PCI enumeration. The offset in resource_entry will be
offset(above) - PCI address. In the process of the enumeration, IO BAR will
be allocated in related IO window.
the base of IO BAR will be stored in (pci_dev -> resource[IO BAR].start), which
is the offset to PCI_IOBASE in CPU VA.
How to use in PCIe device driver
In one hardware arch, we use inb/outb, inw/outw … function to access IO
space. In ARM64, these functions are defined in linux/include/asm-generic/io.h,
like:
1 | #ifndef outb |
So when we want to read/write IO BAR in PCIe device driver, we should:
- get the base of one IO BAR by: addr = pci_resource_start(dev, bar)
- use outb(value, addr) for an example to do port input by byte-width.