在2025年1月15日一月 上午7:38,Arnd Bergmann写道: [...]
Where "range->cpu_addr" is the phys_addr_t location of the MMIO window that maps the host controllers port ranges, i.e. the fully translated address from the "ranges" property.
This is valid for MIPS's PCI_DRIVERS_GENERIC, but not for PCI_DRIVERS_LEGACY, which have it's own implementation of various functions. See arch/mips/pci/pci-legacy.c, pci_load_of_ranges. The address translation is handled by io_map_base, which usually comes from mips_io_port_base.
The point of the pci_address_to_pio() function is to convert this into the Linux-internal virtual port number that gets used as an argument to inb()/outb() and reported in /proc/ioports and that may or may not be the same as the address on the bus itself, depending on the how the translation gets set up.
On loongson, we seem to have two port ranges that are set up like
isa@18000000 { compatible = "isa"; ranges = <1 0x0 0x0 0x18000000 0x4000>; }; pci@1a000000 { ranges = <0x01000000 0x0 0x00020000 0x0
0x18020000 0x0 0x00020000>, <0x02000000 0x0 0x40000000 0x0 0x40000000 0x0 0x40000000>; }
Here, the cpu_addr is 0x18000000 for the isa bus and 0x18020000 for the PCI bus, apparently the intention being that these are consecutive in physical space, though Linux is free to rearrange the logical port numbers in a different way, e.g. to ensure that the PCI bus can use port numbers below 0x10000.
On Malta, I see a very strange
isa { compatible = "isa"; ranges = <1 0 0 0x1000>; };
which maps the first 4096 port numbers into cpu_addr=0x0. The actual port window appears to be at a board specific location
#define MALTA_GT_PORT_BASE get_gt_port_base(GT_PCI0IOLD_OFS) #define MALTA_BONITO_PORT_BASE ((unsigned long)ioremap (0x1fd00000, 0x10000)) #define MALTA_MSC_PORT_BASE get_msc_port_base(MSC01_PCI_SC2PIOBASL)
So e.g. on Bonito, the ranges property would have to be
ranges = <1 0 0x1fd00000 0x1000>;
Not sure if this is patched in by the bootloader, or where the corresponding window for PCI gets defined, but I suspect that the reason for the regression is that the caller of pci_address_to_pio() accidentally passed in '0' instead of the physical address, and it happened to work because of the missing PCI_IOBASE definition but broke after that got defined.
Many other pci-legacy drivers are also working this way, PCI core is not aware of virtual port to physical MMIO address mapping. PCI core just see it as x86 style port.
Thanks
Arnd