UefiCpuPkg: Add RISC-V IOMMU driver#12314
UefiCpuPkg: Add RISC-V IOMMU driver#12314benjamindoron wants to merge 10 commits intotianocore:masterfrom
Conversation
|
Okay, so, the CI encounters errors for:
Those aren't a big deal. But it also won't allow EmbeddedPkg to be depended upon by UefiCpuPkg, but I need it to know whether the platform uses FDT or ACPI ( |
Merge Queue Status
This pull request spent 12 hours 16 minutes 42 seconds in the queue, with no time running CI. ReasonThe pull request can't be updated
HintYou should update or rebase your pull request manually. If you do, this pull request will automatically be requeued once the queue conditions match again. |
Merge Queue Status
This pull request spent 1 hour 4 minutes 34 seconds in the queue, with no time running CI. ReasonThe pull request can't be updated
HintYou should update or rebase your pull request manually. If you do, this pull request will automatically be requeued once the queue conditions match again. |
8ee83b3 to
2df3385
Compare
Entries with the 'valid' bit set and RWX bits cleared are considered "table entries" (non-leaves). With the page table in this state, future map operations will trigger assertions when they reach the final level, and encounter what looks like a valid non-leaf entry. Signed-off-by: Benjamin Doron <benjamin.doron@9elements.com>
This driver follows the RISC-V IOMMU Architecture Spec v1.0 and detects IOMMUs declared in either an FDT or ACPI RIMT table, then performs the basic initialisation steps on them. It also installs the EDK2 IOMMU protocol and implements the boilerplate to be compatible with the spec (such as the location of device buffers). The central function, `IoMmuSetAttribute`, is stubbed at this time. Signed-off-by: Benjamin Doron <benjamin.doron@9elements.com>
TODO: Implement command queue Signed-off-by: Benjamin Doron <benjamin.doron@9elements.com>
This information is useful to see in the IOMMU driver, and there's no need to raise our debug level. For testing only. Signed-off-by: Benjamin Doron <benjamin.doron@9elements.com>
This driver is now capable of mapping an NVMe device, enabling commands to be delivered to it. However, the driver soon asserts on a later command (when we again call the MMU library), due to some apparent device page table corruption. Signed-off-by: Benjamin Doron <benjamin.doron@9elements.com>
This works. QEMU's virt board with an attached NVMe controller and IOMMU successfully boots to the UEFI shell. Signed-off-by: Benjamin Doron <benjamin.doron@9elements.com>
This commit also implements tear-down at exit BootServices for hand-off. Signed-off-by: Benjamin Doron <benjamin.doron@9elements.com>
Implement support for tearing down the IOMMUs at ExitBootServices to prepare them for handoff to the OS. This patch also contains some WIP code to detect the needed device_id width (for PCI devices only, at this time). However, using PciIo protocols requires *unconditionally* making initialisation wait on PCI enumeration, and we'd rather be moving initialisation earlier, not later. So, it's likely that - along with platform device support - we'll use the ACPI/FDT information for this purpose. Signed-off-by: Benjamin Doron <benjamin.doron@9elements.com>
This allows platforms to return an IOMMU device_id themselves, which is required for platform devices. When using this functionality, the platform code must return the base address of the upstream IOMMU. Signed-off-by: Benjamin Doron <benjamin.doron@9elements.com>
Signed-off-by: Benjamin Doron <benjamin.doron@9elements.com>
Merge Queue Status
This pull request spent 3 minutes 42 seconds in the queue, with no time running CI. ReasonThe pull request can't be updated
HintYou should update or rebase your pull request manually. If you do, this pull request will automatically be requeued once the queue conditions match again. |
Merge Queue Status
This pull request spent 1 minute 19 seconds in the queue, with no time running CI. ReasonThe pull request can't be updated
HintYou should update or rebase your pull request manually. If you do, this pull request will automatically be requeued once the queue conditions match again. |
Merge Queue Status
This pull request spent 2 minutes 6 seconds in the queue, with no time running CI. ReasonThe pull request can't be updated
HintYou should update or rebase your pull request manually. If you do, this pull request will automatically be requeued once the queue conditions match again. |
Description
This driver follows the RISC-V IOMMU Architecture Spec v1.0[1] and detects IOMMUs
declared in either an FDT or ACPI RIMT[2] table, then installs the EDK2 IOMMU protocol
on them. It handles PCI and system IOMMUs, as well as PCI and system devices
(for a system device, the platform policy protocol is needed to match DeviceHandle).
The driver may need some cleanup, but is otherwise ready.
Other commits are included to show what's needed, but may not be suited for merging.
For example, this requires
UefiCpuPkg/BaseRiscVMmuLib: Force entry to 0 when clearing all attributes,or successive attempts to map some device memory (after the previous operation finished with unmapping)
will fail in the library's loop, detecting that some bits are still set and apparently assume that this means
that the encountered entry is a non-leaf (and, being that we're on the last level, it
ASSERTs for this).I don't fully understand RISC-V page tables, so I don't know if I've written a fix or a workaround.
We may also now want to discuss the best way to integrate BaseRiscVMmuLib with its consumers
in light of the new driver. I recommend some context object: is this good?
How This Was Tested
This was built against https://github.com/9elements/rise-riscv-iommu-edk2-platforms
and executed with the following:
Integration Instructions
All platforms with IOMMUs must include this driver, and either FDT or ACPI support.
They must publish which of these is in use using the module for this.
To support PCIe IOMMUs and PCIe devices, a platform must implement PCIe support,
including any parsing of PCIe data from a previous firmware, and it must include the base PCIe
stack of modules (CpuIo2Dxe, PciHostBridgeDxe and PciBusDxe).
To support system devices, a platform must implement the new RISC-V IOMMU platform policy
protocol. For any
DeviceHandle, it shall return itsdevice_idas in the IOMMU spec,and it shall return the base address of its upstream IOMMU.
To developers of system devices that will need IOMMU support: be aware that map operations
need to go through the IOMMU. With PCIe devices, that's done for you by the PCIe module stack,
but the
PciIoprotocol calls cannot be dropped for a system devices, only replaced by a call here.