Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arm gic mmio mapping #10690

Merged
merged 9 commits into from
Jan 30, 2025
Merged

Conversation

ardbiesheuvel
Copy link
Member

Refactor the CPU and GIC DXE drivers so that the latter can invoke the CPU arch protocol exposed by the former to map the MMIO control registers explicitly.

@ardbiesheuvel
Copy link
Member Author

@AjanZhong

Failure to install the CPU arch protocol is a fatal error, so treat it
as such, rather than ignore it, even though we won't get very far if
this driver fails to dispatch - at least, we will get an error in a
DEBUG build rather than a mysterious failure due to unsatisfied DEPEXes.

Failure to install the idle loop event handler is not a fatal error, and
it should not cause the driver to exit with an error, as this will
unload the driver and keep the installed CPU arch protocol pointer
dangling. So keep the ASSERT() on the return value, but return
EFI_SUCCESS once we're past the point where the CPU arch protocol has
been installed.

Since the protocol is never uninstalled, make the CPU handle function
local, as there is no point in keeping its value around.

Signed-off-by: Ard Biesheuvel <[email protected]>
Use static linkage for variables and routines that are not referenced
from other objects. This is generally preferred, because it gives the
compiler more freedom for optimization.

Signed-off-by: Ard Biesheuvel <[email protected]>
There is some fossilized code in the CpuDxe driver startup code that
permits a vector table to be inherited from the PEI stage, but this code
is essentially dead on ARM platforms, given that the VectorInfo argument
passed to InitializeCpuExceptionHandlers() is ignored, and no code
appears to exist that would result in the gEfiVectorHandoffTableGuid
configuration table ever being populated.

Also, due to prior refactoring, the code that disables and re-enables
IRQs and FIQs is completely pointless, and can simply be removed. That,
in turn, allows the CPU arch protocol parameter to be dropped from the
prototype of InitializeExceptions().

Signed-off-by: Ard Biesheuvel <[email protected]>
Currently, ArmPkg's CpuDxe DEPEXes on the hardware interrupt protocol,
to ensure that it is not dispatched before the GIC driver. This way, the
CpuDxe driver is guaranteed not to enable interrupts on the CPU side
before the GIC driver has had the opportunity to configure the
interrupts on the distribution side.

However, this prevents the GIC driver from using any of the CPU arch
protocol interfaces, such as mapping memory, which it may need to do on
platforms where the GIC MMIO regions are not mapped yet when the driver
is started.

So instead, use a protocol notification on the hardware interrupt
protocol, which is installed by the GIC driver (as well as other
existing interrupt controller drivers for platforms that do not
implement a GIC) after it starts up and deasserts and disables all
incoming interrupts. Manipulate the interrupt state as usual only after
this notification has been received. Before that, keep track of the
caller's intent regarding the interrupt enabled state in a shadow
variable, but do not actually enable interrupt delivery to the CPU just
yet.

Signed-off-by: Ard Biesheuvel <[email protected]>
Instead of relying on a protocol notification event to register the core IRQ
interrupt handler with CPU arch protocol once it becomes available, use
a DEPEX to ensure that the GIC driver is not dispatched at all until the
CPU arch protocol has turned up.

This will allow the GIC driver to use other CPU arch protocol methods,
such as the ones needed to map the GIC MMIO regions at driver startup.

Signed-off-by: Ard Biesheuvel <[email protected]>
The GIC DXE driver only runs on the boot CPU, and so there is really no
point in iterating over all the redistributor frames every time an
interrupt is enabled, disabled or its state tested. Instead, do this
only at load time.

Signed-off-by: Ard Biesheuvel <[email protected]>
The GIC distributor and redistributor addresses that are passed into the
interrupt enable and disable routines are always the same, so just use
the global variables directly.

Signed-off-by: Ard Biesheuvel <[email protected]>
The GIC driver itself has intimate knowledge of the hardware, and so it
is the best suited to create the mappings of the MMIO control regions,
in case they have not been mapped yet by the platform code.

So call in the the CPU arch protocol to map the CPU interface,
distributor and redistributor regions as they are discovered by the GIC
driver startup code.

Note that creating these mappings has no effect if the regions in
question have already been mapped with the correct attributes.

Signed-off-by: Ard Biesheuvel <[email protected]>
Currently, the ArmVirtQemu startup code maps a 128 MiB of MMIO space, as
it knows that the UART, GIC and RTC live there. Now that the GIC driver
maps its MMIO registers itself, there is no need for this region to
cover its MMIO space. And there are other regions here that don't need
to be mapped by default: the only ones that need to be mapped are the
UARTS, the RTC, the fw_cfg MMIO interface and the virtio-mmio regions,
all of which live in a 32 MiB window starting at address 0x900_0000.

Signed-off-by: Ard Biesheuvel <[email protected]>
@ardbiesheuvel ardbiesheuvel added the push Auto push patch series in PR if all checks pass label Jan 30, 2025
@mergify mergify bot merged commit 43233ff into tianocore:master Jan 30, 2025
126 checks passed
@ardbiesheuvel ardbiesheuvel deleted the arm-gic-mmio-mapping branch January 30, 2025 14:29
@kraxel
Copy link
Member

kraxel commented Jan 31, 2025

Last patch in this series breaks my guests.
Exception after loading the TPM PEI.
Removing the TPM from the guest config makes the VM boot.
I guess the TPM needs to map MMIO address ranges itself too?

@ardbiesheuvel
Copy link
Member Author

If you send a revert pr I'll merge it right away - it's not that important

@kraxel
Copy link
Member

kraxel commented Jan 31, 2025

#10708

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
push Auto push patch series in PR if all checks pass
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants