On Tue, Jan 14, 2025, at 20:10, Maciej W. Rozycki wrote: > On Tue, 14 Jan 2025, Arnd Bergmann wrote: > >> Ideally that should allow using the generic inb/outb and >> ioread/iowrite helpers from include/asm-generic/io.h, but >> unfortunately those don't support the address swizzling required >> on SGI and Octeon platforms. > > Address swizzling should be generic: for an endianness boundary crossing > depending on its wiring there's always either a byte-lane or a bit-lane > matching policy (of course both may be implemented in the same system via > different mapping windows, such as with the Broadcom SiByte BCM1250 SoC > though we only use one in Linux, or with some kind of a bus configuration > register) and either byte swapping or address swizzling is required > accordingly for the relevant use cases. But I guess for just a bunch of > systems that implement the bit-lane matching policy there's little > incentive for complicating the generic helpers. I checked the other architectures as well now, and I'm fairly sure we had some architectures in the past that implemented the same swizzling, but it seems that those all got removed over time, and now it's literally just MIPS with SGI (ip27/ip30/ip32, not ip22) and Octeon. From the comment above octeon_should_swizzle_table[] it appears that this is actually configurable in a register but was set up at the time to do SGI-compatible address swizzling, when it could have just use a software byteswap (CONFIG_SWAP_IO_SPACE) like the rest of the world. I double-checked the setting of CONFIG_SWAP_IO_SPACE, and found that it's mostly consistent in setting this for all big-endian platforms, the exceptions are: - ath79 is big-endian but does not set SWAP_IO_SPACE. I assume it works because there is a very limited set of PCIe cards actually in use on this platform, notably ath9k wireless. If readl()/writel()/inl()/outl() don't do a software byteswap, there is probably similar hardware logic in place as on octeon and SGI, and the lack of address swizzling may mean sub-word access to PCI registers is broken. The ath9k driver only uses ioread32()/iowrite32(), which works regardless of the address swizzling, but many other devices would be broken. - eyeq and rb532 are always little-endian, so SWAP_IO_SPACE does nothing despite being selected. - nintendo64 has no PCI, and I guess the readl()/writel() in drivers/block/n64cart.c, sound/mips/snd-n64.c etc end up using readl()/writel() as native on-chip register accessors instead of byteswapping ones. Arnd