Under SeaBIOS, I'm noticing that not all of the PCIe-related area is marked uncachable in the MTRR settings, at least in the Q35 platform (QEMU).
I feel like this is a bug, but I'm not familar with the lore behind Q35 and MTRRs, feedback would be appreciated.
The MCFG table contains an entry starting at Q35_HOST_BRIDGE_PCIEXBAR_ADDR (0xb0000000) corresponding to a 256MB area. Later, the mch_mem_addr_setup() routine defines the PCIe window (pcimem_start) starting at 0xc0000000 (Q35_HOST_BRIDGE_PCIEXBAR_ADDR + Q35_HOST_BRIDGE_PCIEXBAR_SIZE).
I see in mtrr_setup(), that only a single variable MTRR is configured based solely on pcimem_start and extends to the end of the 4GB boundary. It looks to me that this is probably fine for 440fx, but seems insufficient for Q35.
Q35 - original SeaBIOS 1.15.0: # cat /proc/mtrr reg00: base=0x0c0000000 ( 3072MB), size= 1024MB, count=1: uncachable
Q35 - original EFI (ovmf 2202.02) # cat /proc/mtrr reg00: base=0x0c0000000 ( 3072MB), size= 1024MB, count=1: uncachable reg01: base=0x0b0000000 ( 2816MB), size= 256MB, count=1: uncachable reg02: base=0x800000000 (32768MB), size=32768MB, count=1: uncachable
Thus, for Q35, there is no explict attempt to configure the Q35_HOST_BRIDGE_PCIEXBAR_ADDR area nor any potential the >4GB area used for PCIe I/O. The inherent size restrictions on MTRR mask definitions make a completely generic solution a bit tricky.
Attached is a simple patch that enables use of the other variable MTRR registers. I believe solves the issue, but I'm not sure how to test it with a 64-bit PCIe window. In a simple setup, it results in the following:
# cat /proc/mtrr reg00: base=0x0c0000000 ( 3072MB), size= 1024MB, count=1: uncachable reg01: base=0x0b0000000 ( 2816MB), size= 256MB, count=1: uncachable
Is this type of change appropriate? Would it make sense to remove direct use of pcimem_start from the mtrr.c code and just like the PCI code directly register the related range using the new mechanism?