Dear all,
We are porting the PCIe driver into the SG2042 platform. To solve the Cache Coherence problem between the PCIe and the CPU, we have enabled the MMU to allocate non-cacheable memory for the PCIe device. There are some questions:
Q0:
UEFI mandates a 1:1 mapping between the physical address and the virtual address. How to deal with the situation where the mapping between the two fails to meet the above prerequisites.
Take Sv39 for example, if the 38-bit of a device's physical address is 1, e.g. 0x40 0000 0000, the mapped virtual address is 0xFFFF FFFC 0000 0000 according to RISC-V Privileged Spec.
Q1:
Case 1. Set the PageAttributes as (readable, writable, bufferable, sharable, weak-order, non-cacheable) or (readable, writable, non-bufferable, strong-order, non-cacheable) according to the RISC-V privilege and the C920 Core IP spec, then the NVMe SSD over PCIe doesn't work, the data in SQ and CQ is not right, still has been cached. It seems that the non-cacheable PTEs have no effect.
Case 2. Then we try to override the PciRootBridgeIoAllocateBuffer, PciRootBridgeIoFreeBuffer, PciRootBridgeIoMap, and PciRootBridgeIoUnMap functions with the reference to NonCoherentDmaLib. For each buffer allocation, modify the GcdAttributes to non-cacheable, and then update the page tables. Still, the NVMe DXE also needs to flush or invalidate the cache to pass the NVMe DXE initializing phase. It seems that the ready-to-use update page tables also have no effect.
So how do we keep the cache coherence between PCIe and CPU in edk2 by using MMU reasonably and appropriately?
Q2:
When the code about cache maintenance (e.g. CpuFlushCpuDataCache) will be implemented?
Q3:When the Svpbmt Extension will be implemented? Will be only a reference implementation given?
Thanks!Best Regards,Jingyu--
You received this message because you are subscribed to the Google Groups "RISC-V Firmware Exchange" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fw-exchange...@riscv.org.
To view this discussion on the web visit https://groups.google.com/a/riscv.org/d/msgid/fw-exchange/ce3ad5d6-4cf3-4b2f-849f-982a1e991176n%40riscv.org.
To view this discussion on the web visit https://groups.google.com/a/riscv.org/d/msgid/fw-exchange/CABYABGTYgPE5kVg84LEHwa7sa2%2BNFqzgL-Mp3ictjGN2rQ1ZBA%40mail.gmail.com.
Wrt Q0:
SG2042 is an Sv39 chip. Can you share what kind of devices are decoding bit 38? Are these platform (MMIO) devices or is that where you have set up the PCIe apertures?
The current RV calling convention in UEFI sadly says nothing about 1:1 mapping, but the current draft being reviewed (and soon approved) by the UEFI Forum has the following text, which is similar to other architectures. In fact, it is very similar to the ia32 – it /allows/ the MMU to be configured, but if it is, then the 1:1 mapping must hold true for /memory spaces/.
E.g.:
--------->
Address translation may be enabled. If enabled, any memory space defined by the UEFI memory map is identity mapped (virtual address equals physical address), although the attributes of certain regions may not have all read, write and execute attributes or be unmarked for purposes of platform protection. The mappings to other regions are undefined and may vary from implementation to implementation.
--------->
(UEFI memory maps don’t contain I/O, unless it’s a region used by runtime services code… that’s the only exception, since the OS has to map all regions used by RT).
So in your situation, where a device is physically at 0x40 0000 0000 but in Sv39 world is 0xFFFF FFFC 0000 0000, you could:
If you happen to have RAM at bit 38, then such RAM literally can’t be used by UEFI if you use the MMU, because memory must be 1:1. You’d have to reserve such ranges away from Tiano.
Q1) Is there a non-architected cache somewhere in the system? “For each buffer allocation, modify the GcdAttributes to non-cacheable, and then update the page tables.” – you’d also want to flush the buffers… Is your PCIe DMA non-coherent?
Q2) Does SG2042 implement CMO or is there a non-architected cache somewhere in the system, that requires custom MMIO-based operations?
Q3) Does SG2042 implement Svpbmt? I want to add a stronger requirement around MMU use to the UEFI calling conv. for RISC-V – mandate it for systems with Svpbmt (because presumably, you’d want to use MMU on such systems anyway to deal with UC overrides to regular memory PMA for supporting non-coherent I/O implementations.)
A
--
Wrt Q0:
SG2042 is an Sv39 chip. Can you share what kind of devices are decoding bit 38? Are these platform (MMIO) devices or is that where you have set up the PCIe apertures?
The current RV calling convention in UEFI sadly says nothing about 1:1 mapping, but the current draft being reviewed (and soon approved) by the UEFI Forum has the following text, which is similar to other architectures. In fact, it is very similar to the ia32 – it /allows/ the MMU to be configured, but if it is, then the 1:1 mapping must hold true for /memory spaces/.
E.g.:
--------->
Address translation may be enabled. If enabled, any memory space defined by the UEFI memory map is identity mapped (virtual address equals physical address), although the attributes of certain regions may not have all read, write and execute attributes or be unmarked for purposes of platform protection. The mappings to other regions are undefined and may vary from implementation to implementation.
--------->
(UEFI memory maps don’t contain I/O, unless it’s a region used by runtime services code… that’s the only exception, since the OS has to map all regions used by RT).
So in your situation, where a device is physically at 0x40 0000 0000 but in Sv39 world is 0xFFFF FFFC 0000 0000, you could:
- Not enable the MMU. Not ideal (e.g., you can forget about MultiArchUefiPkg as it relies on page protection to intercept execution of non-native code)
- Make drivers aware that physical address of a device’s registers != actual address to use. For platform devices, e.g, passing the virtual address to RegisterNonDiscoverableMmioDevice instead of physical. For PCIe devices, you might need to hack up the PCI stack so that the reported BAR values are sign extended ones, not physical ones.
- For PCIe, move the aperture lower.
If you happen to have RAM at bit 38, then such RAM literally can’t be used by UEFI if you use the MMU, because memory must be 1:1. You’d have to reserve such ranges away from Tiano.
Q1) Is there a non-architected cache somewhere in the system? “For each buffer allocation, modify the GcdAttributes to non-cacheable, and then update the page tables.” – you’d also want to flush the buffers… Is your PCIe DMA non-coherent?
Q2) Does SG2042 implement CMO or is there a non-architected cache somewhere in the system, that requires custom MMIO-based operations?

Q3) Does SG2042 implement Svpbmt? I want to add a stronger requirement around MMU use to the UEFI calling conv. for RISC-V – mandate it for systems with Svpbmt (because presumably, you’d want to use MMU on such systems anyway to deal with UC overrides to regular memory PMA for supporting non-coherent I/O implementations.)
te

Jingyu,
A few follow up Qs:
1) Did my comments on the handling of your device I/O regions (with bit 38) make sense? Do you acknowledge that a non-1:1 mapping of MMIO regions is not a violation of the identity mapping requirements seen in UEFI spec?
2) Do you acknowledge that you must perform cache maintenance, as part of allocating a non-coherent buffer, to avoid stale state from the cache to accidentally getting flushed back to RAM (and I suppose, depending on how the cache is implemented, to avoid cache hits on stale data, too...).
Do you have the code up somewhere? Perhaps we can eyeball the issue...