Commit Graph

246 Commits

Author SHA1 Message Date
Jeff Brasen 559a07d84e ArmPkg/ArmScmiDxe: Add clock enable function
Add function to allow enabling and disabling of the clock using the SCMI
interface. Add gArmScmiClock2ProtocolGuid to distinguish platforms that
support new API from those that just have the older protocol.

SCMI_CLOCK2_PROTOCOL also adds a version parameter to allow for future
changes. It is placed after the functions that are present in the
existing protocol to allow SCMI_CLOCK2_PROTOCOL to be cast to
SCMI_CLOCK_PROTOCOL so that only a single implementation of those
function are needed.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jeff Brasen <jbrasen@nvidia.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2018-12-21 18:30:46 +01:00
Ard Biesheuvel ba808d11f6 ArmPkg/GenericWatchdogDxe: implement RegisterHandler() method
Even though UEFI does not appear to use it, let's implement the
complete PI watchdog protocol, including handler registration,
which will be invoked before the ResetSystem() runtime service
when the watchdog timer expires.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2018-12-20 12:41:21 +01:00
Ard Biesheuvel d3b05936d9 ArmPkg/GenericWatchdogDxe: clean up the code
Clean up the code, by adding missing STATIC modifiers, drop
redundant casts, and get rid of the 'success handling' anti
pattern in the entry point code.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2018-12-20 12:41:21 +01:00
Ard Biesheuvel 36a87fec68 ArmPkg/ArmMmuLib ARM: handle unmapped section in GetMemoryRegion()
GetMemoryRegion() is used to obtain the attributes of an existing
mapping, to permit permission attribute changes to be optimized
away if the attributes don't actually change.

The current ARM code assumes that a section mapping or a page mapping
exists for any region passed into GetMemoryRegion(), but the region
may be unmapped entirely, in which case the code will crash. So check
if a section mapping exists before dereferencing it.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
2018-12-03 15:54:39 +01:00
Ard Biesheuvel a3b6537144 ArmPkg/CpuPei: base GCD memory space size on CPU's PA range
Derive the size of the GCD memory space map directly from the CPU's
information registers rather than from the PcdPrePiCpuMemorySize PCD,
which will be removed.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2018-11-29 18:55:08 +01:00
Achin Gupta 4c2f32ed1a ArmPkg/Drivers: Add EFI_MM_COMMUNICATION_PROTOCOL DXE driver.
PI v1.5 Specification Volume 4 defines Management Mode Core Interface
and defines EFI_MM_COMMUNICATION_PROTOCOL. This protocol provides a
means of communicating between drivers outside of MM and MMI
handlers inside of MM.

This patch implements the EFI_MM_COMMUNICATION_PROTOCOL DXE runtime
driver for AARCH64 platforms. It uses SMCs allocated from the standard
SMC range defined in DEN0060A_ARM_MM_Interface_Specification.pdf
to communicate with the standalone MM environment in the secure world.

This patch also adds the MM Communication driver (.inf) file to
define entry point for this driver and other compile
related information the driver needs.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sughosh Ganu <sughosh.ganu@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2018-11-27 13:05:57 +01:00
Ard Biesheuvel 66127011a5 ArmPkg/ArmGicDxe ARM: fix encoding for GICv3 interrupt acknowledge
Fix a typo in the 32-bit ARM version of the GICv3 driver, which uses
the wrong system register encoding to access ICC_IAR1, and attempted
to access ICC_IAR0 instead. This results in boot time hangs both
under QEMU emulation and on real hardware.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2018-11-15 04:33:07 -08:00
Ming Huang b66e38b501 ArmPkg/ArmGicDxe: Fix GICv3 interrupt routing mode bug
Setting GICD_IROUTERn.IRM and GICD_IROUTERn.{Aff3,Aff2,Aff1,Aff0}
at the same time is nonsensical (see 8.9.13 in the GICv3 spec, which
says of GICD_IROUTERn.IRM that "When this bit is set to 1,
GICD_IROUTER<n>.{Aff3,Aff2,Aff1,Aff0} are UNKNOWN"). There is also no
guarantee that IRM is implemented (see GICD_TYPER.No1N which indicates
whether the implementation supports this or not).

Let's thus not set this bit, as we want all SPIs to be delivered to the
same CPU, and not be broadcast to all of them.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ming Huang <ming.huang@linaro.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
2018-11-07 16:19:22 +01:00
Sami Mujawar 301402fa47 ArmPkg: Add support for GICv4
Updated Redistributor base calculation to allow for the fact that
GICv4 has 2 additional 64KB frames (for VLPI and a reserved frame).
The code now tests the VLPIS bit in the GIC Redistributor Type
Register (GICR_TYPER) and calculates the Redistributor granularity
accordingly.

The code changes are:
  GICR_TYPER register fields, etc, added to the header.
  Loop updated to pay attention to GICR_TYPER.Last.
  Derive frame "stride" size from GICR_TYPER.VLPIS.

Note: The assumption is that the redistributors are adjacent for
all CPUs. However this may not be the case for NUMA systems.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2018-10-12 17:40:33 +02:00
Marcin Wojtas dd4cae4d82 ArmPkg/GenericWatchdogDxe: Split 64bit register write to 2x32bit
According to the SBSA specification the Watchdog Compare
Register is split into two separate 32bit registers.
EDK2 code uses a single 64bit transaction to update
them, which can be problematic, depending on the SoC
implementation and could result in unpredictable behavior.

Fix this by modifying WatchdogWriteCompareRegister routine to
use two consecutive 32bit writes to the Watchdog Compare Register
Low and High, using new dedicated macros.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Marcin Wojtas <mw@semihalf.com>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2018-08-03 09:29:14 +02:00
Girish Pathak 3b03b5e990 ArmPkg/ArmScmiDxe: Dynamically allocate buffer for protocol ids
Dynamically allocate the buffer to receive the SCMI protocol list.
This makes MAX_PROTOCOLS redundant, so it is removed.
It also fixes one minor code alignment issue and removes an unused
macro PROTOCOL_MASK.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Girish Pathak <girish.pathak@arm.com>
Tested-by: Sudeep Holla <sudeep.holla@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2018-06-22 08:22:04 +02:00
Girish Pathak 889cf68c3c ArmPkg/ArmScmiDxe: Fix ASSERT error in SCMI DXE
This change fixes a bug in the SCMI DXE which is observed with the
upcoming release of the SCP firmware.

The PROTOCOL_ID_MASK (0xF) which is used to generate an index in
the ProtocolInitFxns is wrong because protocol ids can be
anywhere in 0x10 - 15 or 0x80 - FF range. This mask generates
the same index for two different protocols e.g. for protocol ids
0x10 and 0x90, which causes duplicate initialization of a protocol
resulting in a failure.

This change removes the use of PROTOCOL_ID_MASK and instead
uses a list of protocol ids and their initialization functions
to identify a supported protocol and initialize it.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Girish Pathak <girish.pathak@arm.com>
Tested-by: Sudeep Holla <sudeep.holla@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2018-06-22 08:21:30 +02:00
AlexeiFedorov 8fe18cba76 ArmPkg: Fix bug in Generic Watchdog driver
In ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.c, the following
functions:

  WatchdogWriteOffsetRegister()
  WatchdogWriteCompareRegister()
  WatchdogEnable()
  WatchdogDisable()

provide write access to ARM Generic Watchdog registers and use the values
returned by MmioWrite32() and MmioWrite64() as EFI_STATUS return codes.

Because MmioWriteXY() return the value passed as its write parameter,
Generic Watchdog access functions can spuriously return error codes which
are different from EFI_SUCCESS, e.g. the following call

    Status = WatchdogWriteOffsetRegister (MAX_UINT32);
    if (EFI_ERROR (Status)) {
      return Status;
    }

will return MAX_UINT32 defined in MdePkg/Include/Base.h as

 #define MAX_UINT32  ((UINT32)0xFFFFFFFF)

This commit declares all the functions listed above as VOID
and removes the code for checking their return values.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Alexei Fedorov <alexei.fedorov@arm.com>
Reviewed-by: Evan Lloyd <evan.lloyd@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2018-04-30 11:38:54 +02:00
Ard Biesheuvel 5853e2e450 ArmPkg: add reenable hook to ArmGenericTimerCounterLib
In preparation of selectively reinstating the timer enable quirk for Xen
that we removed in commit 411a373ed6 ("ArmPkg/TimerDxe: remove workaround
for KVM timer handling"), add a ArmGenericTimerReenableTimer() library
function to ArmGenericTimerCounterLib that we will populate for Xen only.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Julien Grall <julien.grall@arm.com>
Acked-by: Julien Grall <julien.grall@arm.com>
2018-04-26 08:31:12 +02:00
Girish Pathak 4f2494cf53 ArmPkg: Introduce SCMI protocol
This change introduces a new SCMI protocol driver for
Arm systems. The driver currently supports only clock
and performance management protocols. Other protocols
will be added as and when needed.

Clock management protocol is used to configure various clocks
available on the platform e.g. HDLCD clock on the Juno platforms.

Whereas performance management protocol allows adjustment
of various performance domains. Currently this is used to evaluate
performance of the Juno platform.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Girish Pathak <girish.pathak@arm.com>
Signed-off-by: Evan Lloyd <evan.lloyd@arm.com>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2018-04-23 17:58:28 +01:00
Ard Biesheuvel 411a373ed6 ArmPkg/TimerDxe: remove workaround for KVM timer handling
When we first ported EDK2 to KVM/arm, we implemented a workaround for
the quirky timer handling on the KVM side. This has been fixed in
Linux commit f120cd6533d2 ("KVM: arm/arm64: timer: Allow the timer to
control the active state") dated 23 June 2014, which was incorporated
into Linux release 4.3.

So almost 4 years later, it should be safe to drop this workaround on
the EDK2 side.

This reverts commit b1a633434d.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2018-04-19 10:15:37 +02:00
Laszlo Ersek bacfd6ed8c ArmPkg/CpuDxe: order CpuDxe after ArmGicDxe via protocol depex
Commit 61a7b0ec63 ("ArmPkg/Gic: force GIC driver to run before CPU arch
protocol driver", 2018-02-06) explains why CpuDxe should be dispatched
after ArmGicDxe.

To implement the ordering, we should use a regular protocol depex rather
than the less flexible AFTER opcode. ArmGicDxe installs
gHardwareInterruptProtocolGuid and gHardwareInterrupt2ProtocolGuid as one
of the last actions on its entry point stack; either of those is OK for
CpuDxe to wait for.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Steve Capper <steve.capper@linaro.org>
Cc: Supreeth Venkatesh <Supreeth.Venkatesh@arm.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Steve Capper <steve.capper@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2018-04-12 21:24:29 +02:00
Laszlo Ersek 04f6b66b5e ArmPkg/ArmGicDxe: annotate protocol usage in "ArmGicDxe.inf"
"ArmGicDxe.inf" currently does not document how the protocols in the
[Protocols] section are used. Such comments help us analyze behavior, so
let's add them now.

- gHardwareInterruptProtocolGuid and gHardwareInterrupt2ProtocolGuid are
  always produced on the InterruptDxeInitialize() -> (GicV2DxeInitialize()
  | GicV3DxeInitialize()) -> InstallAndRegisterInterruptService() call
  path.

- gEfiCpuArchProtocolGuid is consumed in the CpuArchEventProtocolNotify()
  protocol notify callback. (Technically this is "conditional"; however
  the firmware cannot work without architectural protocols, so we can call
  it unconditional.)

While at it, drop the gArmGicDxeFileGuid comment from FILE_GUID; we're
going to make that GUID uninteresting soon.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Steve Capper <steve.capper@linaro.org>
Cc: Supreeth Venkatesh <Supreeth.Venkatesh@arm.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Steve Capper <steve.capper@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2018-04-12 21:24:26 +02:00
Heyi Guo ac9b530e6b ArmPkg/TimerDxe: Add ISB for timer compare value reload
If timer interrupt is level sensitive, reloading timer compare
register has a side effect of clearing GIC pending status, so a "ISB"
is needed to make sure this instruction is executed before enabling
CPU IRQ, or else we may get spurious timer interrupts.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2018-03-15 08:07:14 +00:00
Marc Zyngier 5e3719aeae ArmPkg/TimerDxe: Always perform an EOI, even for spurious interrupts
The generic timer driver only EOIs the timer interrupt if
the ISTATUS bit is set. This is completely fine if you pretend
that spurious interrupts do not exist. But as a matter of fact,
they do, and the first one will leave the interrupt activated
at the GIC level, making sure that no other interrupt can make
it anymore.

Making sure that each interrupt Ack is paired with an EOI is the
way to go. Oh, and enabling the interrupt each time it is taken
is completely pointless. We entered this function for a good
reason...

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2018-03-06 14:37:39 +00:00
Ard Biesheuvel 61a7b0ec63 ArmPkg/Gic: force GIC driver to run before CPU arch protocol driver
Currently, the GIC driver has a static dependency on the CPU arch protocol
driver, so it can register its IRQ handler at init time. This means there
is a window between dispatch of the CPU driver and dispatch of the GIC
driver where any unexpected GIC state may trigger an interrupt which we
are not set up to handle yet. Note that this is even the case if we enter
UEFI with interrupts disabled at the CPU, given that any TPL manipulation
involving TPL_HIGH_LEVEL will unconditionally enable IRQs at the CPU side
regardless of whether they were enabled to begin with (but only as soon as
the CPU arch protocol is actually installed)

So let's reorder the GIC driver with the CPU driver, and let it run its
initialization that puts the GIC into a known state before enabling
interrupts. Move its installation of its IRQ handler to a protocol notify
callback on the CPU arch protocol so that it runs as soon as it becomes
available.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
Tested-by: Marc Zyngier <marc.zyngier@arm.com>
2018-02-06 18:59:34 +00:00
Leif Lindholm 09c3c69cfd ArmPkg: delete references to unused guids/Pcds from CpuDxe
gEfiDebugSupportPeriodicCallbackProtocolGuid and
PcdCpuDxeProduceDebugSupport are referred to from CpuDxe.
Delete references from .inf and .h.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2018-02-06 18:01:14 +00:00
Ard Biesheuvel 142fa386eb ArmPkg: remove unused ArmGicSecLib library implementation
This module is not used anywhere under edk2 or edk2-platforms, so let's
remove it. This removes the only dependency on ArmPlatformLib from ArmPkg.
While at it, remove a mention of ArmPlatformPkg from a comment in the
.dec file as well.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2017-11-26 10:58:30 +00:00
Ard Biesheuvel baee8efb36 ArmPkg/GenericWatchdogDxe: Set Watchdog interrupt type
Utilise the new HardwareInterrupt2 protocol to adjust the
Edge/Level characteristics of the Watchdog interrupt.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Girish Pathak <girish.pathak@arm.com>
Signed-off-by: Evan Lloyd <evan.lloyd@arm.com>
Tested-by: Girish Pathak <girish.pathak@arm.com>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2017-10-05 21:23:39 +01:00
Ard Biesheuvel 8659306a2e ArmPkg/ArmGicDxe: Expose HardwareInterrupt2 protocol
The existing HardwareInterrupt protocol lacked a means to configure the
level/edge properties of an interrupt.  The new HardwareInterrupt2
protocol introduced this capability.
This patch updates the GIC drivers to provide the new interfaces.
The changes comprise:
  Update to use HardwareInterrupt2 protocol
  Additions to register info in ArmGicLib.h
  Added new functionality (GetTriggerType and SetTriggerType)

The requirement for this change derives from a problem detected on ARM
Juno boards, but the change is of generic (ARM) relevance.

This commit is in response to review on the mailing list and, as
suggested there, rolls Girish's updates onto Ard's original example.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Girish Pathak <girish.pathak@arm.com>
Signed-off-by: Evan Lloyd <evan.lloyd@arm.com>
Tested-by: Girish Pathak <girish.pathak@arm.com>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2017-10-05 21:23:39 +01:00
Evan Lloyd b0393756d6 ArmPkg: Tidy GIC code before changes.
This change is purely cosmetic, to tidy some code before change.
Mods involve:
    Re-order #includes
    Reformat comments.
    Use ns consistently (always "100ns" not sometimes "100 nS")
    Split overlength code lines.
    Make protocol functions STATIC.
    Remove "Horor vacui" comments.
    Rationalize GIC register address calculations
    Replace explicit test and assert with ASSERT_EFI_ERROR.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Girish Pathak <girish.pathak@arm.com>
Signed-off-by: Alexei Fedorov <alexei.fedorov@arm.com>
Signed-off-by: Evan Lloyd <evan.lloyd@arm.com>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2017-10-05 17:45:16 +01:00
Ard Biesheuvel a94081fb26 ArmPkg: add ArmCrashDumpDxe driver
Even though RELEASE builds produce some diagnostics when a crash
occurs, they can be rather unhelpful:

  Synchronous Exception at 0x0000000000000000

and sometimes, it would be useful to get a full register dump from
a production machine without having to modify the firmware.

This can be achieved very easily by incorporating a DEBUG build of
ARM's DefaultExceptionHandlerLib into a DXE driver, and registering
its DefaultExceptionHandler entry point as the synchronous exception
handler, overriding the default one. If we then build this driver
using the UefiDebugLibConOut DebugLib implementation, we end up
with a module than can simply be loaded via the Shell on any system.

Shell> load fs0:ArmCrashDumpDxe.efi

As a bonus, the crash dump will also appear on the graphical display,
not only on the serial port.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2017-09-06 17:48:03 +01:00
Ard Biesheuvel cffa7925a2 ArmPkg: remove ArmCpuLib header and implementations
Remove ArmCpuLib entirely. It is no longer used.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2017-04-06 14:55:11 +01:00
Ard Biesheuvel bdecff6c0f ArmPkg/CpuDxe: handle implied attributes in EfiAttributeToArmAttribute
Some memory attributes are implied by the memory type, e.g., device memory
is always mapped non-executable and cached memory should have the inner
shareable attribute.

In order to prevent unnecessary memory attribute updates of mappings
created early on, make EfiAttributeToArmAttribute() return these implied
attributes in the same way as ArmMmuLib does already. This avoids false
positives when looking for differences between current and desired mapping
attributes.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2017-03-08 15:40:20 +01:00
Ard Biesheuvel d9c0d991f7 ArmPkg/ArmMmuLib: remove VirtualMask arg from ArmSetMemoryAttributes
We no longer make use of the ArmMmuLib 'feature' to create aliased
memory ranges with mismatched attributes, and in fact, it was only
wired up in the ARM version to begin with.

So remove the VirtualMask argument from ArmSetMemoryAttributes()'s
prototype, and remove the dead code that referred to it.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2017-03-07 09:38:08 +01:00
Ard Biesheuvel 521f3cedac ArmPkg: move ARM version of SetMemoryAttributes to ArmMmuLib
... where it belongs, since AARCH64 already keeps it there, and
non DXE users of ArmMmuLib (such as DxeIpl, for the non-executable
stack) may need its functionality as well.

While at it, rename SetMemoryAttributes to ArmSetMemoryAttributes,
and make any functions that are not exported STATIC. Also, replace
an explicit gBS->AllocatePages() call [which is DXE specific] with
MemoryAllocationLib::AllocatePages().

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2017-03-07 09:38:08 +01:00
Ard Biesheuvel 08b504d9d8 ArmPkg/CpuDxe ARM: honour RO/XP attributes in SetMemoryAttributes()
Enable the use of strict memory permissions on ARM by processing the
EFI_MEMORY_RO and EFI_MEMORY_XP rather than ignoring them. As before,
calls to CpuArchProtocol::SetMemoryAttributes that only set RO/XP
bits will preserve the cacheability attributes. Permissions attributes
are not preserved when setting the memory type only: the way the memory
permission attributes are defined does not allows for that, and so this
situation does not deviate from other architectures.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2017-03-07 09:10:01 +01:00
Ard Biesheuvel 22c7a5b70e ArmPkg/CpuDxe ARM: avoid unnecessary cache/TLB maintenance
Page and section entries in the page tables are updated using the
helper ArmUpdateTranslationTableEntry(), which cleans the page
table entry to the PoC, and invalidates the TLB entry covering
the page described by the entry being updated.

Since we may be updating section entries, we might be leaving stale
TLB entries at this point (for all pages in the section except the
first one), which will be invalidated wholesale at the end of
SetMemoryAttributes(). At that point, all caches are cleaned *and*
invalidated as well.

This cache maintenance is costly and unnecessary. The TLB maintenance
is only necessary if we updated any section entries, since any page
by page entries that have been updated will have been invalidated
individually by ArmUpdateTranslationTableEntry().

So drop the clean/invalidate of the caches, and only perform the
full TLB flush if UpdateSectionEntries() was called, or if sections
were split by UpdatePageEntries(). Finally, make the cache maintenance
on the remapped regions themselves conditional on whether any memory
type attributes were modified.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2017-03-07 09:10:01 +01:00
Ard Biesheuvel df809efe13 ArmPkg/CpuDxe ARM: avoid splitting page table sections unnecessarily
Currently, any range passed to CpuArchProtocol::SetMemoryAttributes is
fully broken down into page mappings if the start or the size of the
region happens to be misaliged relative to the section size of 1 MB.

This is going to result in memory being wasted on second level page tables
when we enable strict memory permissions, given that we remap the entire
RAM space non-executable (modulo the code bits) when the CpuArchProtocol
is installed.

So refactor the code to iterate over the range in a way that ensures
that all naturally aligned section sized subregions are not broken up.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2017-03-07 09:10:01 +01:00
Ard Biesheuvel 3b44bb5527 ArmPkg/CpuDxe: ignore attribute changes during SyncCacheConfig()
To prevent the initial MMU->GCD memory space map synchronization from
stripping permissions attributes [which we cannot use in the GCD memory
space map, unfortunately], implement the same approach as x86, and ignore
SetMemoryAttributes() calls during the time SyncCacheConfig() is in
progress. This is a horrible hack, but is currently the only way we can
implement strict permissions on arbitrary memory regions [as opposed to
PE/COFF text/data sections only]

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2017-02-28 14:59:50 +00:00
Ard Biesheuvel fc7bd8939d ArmPkg/CpuDxe: remove VirtualUncachedPages protocol and implementation
Virtual uncached pages are simply pages that are aliased using mismatched
attributes, which is not allowed by the ARM architecture. So remove the
protocol and its implementation.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2017-02-23 17:57:55 +00:00
Ard Biesheuvel e0307a7dad ArmPkg/ArmMmuLib: AARCH64: add support for modifying only permissions
Since the new DXE page protection for PE/COFF images may invoke
EFI_CPU_ARCH_PROTOCOL.SetMemoryAttributes() with only permission
attributes set, add support for this in the AARCH64 MMU code.

Move the EFI_MEMORY_CACHETYPE_MASK macro to a shared location between
CpuDxe and ArmMmuLib so we don't have to introduce yet another
definition.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2017-02-21 17:23:03 +00:00
Ard Biesheuvel 0a9d732c91 ArmPkg/CpuDxe: ARM: ignore page table updates that only change permissions
Currently, we have not implemented support on 32-bit ARM for managing
permission bits in the page tables. Since the new DXE page protection
for PE/COFF images may invoke EFI_CPU_ARCH_PROTOCOL.SetMemoryAttributes()
with only permission attributes set, let's simply ignore those for now.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2017-02-21 17:23:03 +00:00
Ard Biesheuvel ce82984fe7 ArmPkg/CpuDxe: translate invalid memory types in EfiAttributeToArmAttribute
The single user of EfiAttributeToArmAttribute () is the protocol
method EFI_CPU_ARCH_PROTOCOL.SetMemoryAttributes(), which uses the
return value to compare against the ARM attributes of an existing mapping,
to infer whether it is actually necessary to change anything, or whether
the requested update is redundant. This saves some cache and TLB
maintenance on 32-bit ARM systems that use uncached translation tables.

However, EFI_CPU_ARCH_PROTOCOL.SetMemoryAttributes() may be invoked with
only permission bits set, in which case the implied requested action is to
update the permissions of the region without modifying the cacheability
attributes. This is currently not possible, because
EfiAttributeToArmAttribute () ASSERT()s [on AArch64] on Attributes arguments
that lack a cacheability bit.

So let's simply return TT_ATTR_INDX_MASK (AArch64) or
TT_DESCRIPTOR_SECTION_TYPE_FAULT (ARM) in these cases (or'ed with the
appropriate permission bits). This way, the return value is equally
suitable for checking whether the attributes need to be modified, but
in a way that accommodates the use without a cacheability bit set.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2017-02-21 17:23:03 +00:00
Jiewen Yao b7a09b71b6 ArmPkg/CpuDxe: Correct EFI_MEMORY_RO usage
Current Arm CpuDxe driver uses EFI_MEMORY_WP for write protection,
according to UEFI spec, we should use EFI_MEMORY_RO for write protection.
The EFI_MEMORY_WP is the cache attribute instead of memory attribute.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2017-02-21 17:23:03 +00:00
Alexei 7c609a144b ArmPkg/GenericWatchdogDxe: Declare MMIO PCDs as UINT64
PcdGenericWatchdogControlBase & PcdGenericWatchdogRefreshBase
are declared as UINT32 values in ArmPkg.dec, but for platforms
with addresses in the memory range above 4GB this causes build
error F000: Too large PCD value for datum type [UINT32]
of PCD gArmTokenSpaceGuid.PcdGenericWatchdogControlBase

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Alexei Fedorov <alexei.fedorov@arm.com>
Signed-off-by: Evan Lloyd <evan.lloyd@arm.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=361
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2017-02-07 08:37:30 +00:00
Ard Biesheuvel 734bd6cc41 ArmPkg/ArmLib: remove indirection layer from timer register accessors
The generic timer support libraries call the actual system register
accessor function via a single pair of functions ArmArchTimerReadReg()
and ArmArchTimerWriteReg(), which take an enum argument to identify
the register, and return output values by pointer reference.

Since these functions are never called with a non-immediate argument,
we can simply replace each invocation with the underlying system register
accessor instead. This is mostly functionally equivalent, with the
exception of the bounds check for the enum (which is pointless given the
fact that we never pass a variable), the check for the presence of the
architected timer (which only makes sense for ARMv7, but is highly unlikely
to vary between platforms that are similar enough to run the same firmware
image), and a check for enum values that refer to the HYP view of the timer,
which we never referred to anywhere in the code in the first place.

So get rid of the middle man, and update the ArmGenericTimerPhyCounterLib
and ArmGenericTimerVirtCounterLib implementations to call the system
register accessors directly.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
Tested-by: Ryan Harkin <ryan.harkin@linaro.org>
2017-01-20 15:51:34 +00:00
Ard Biesheuvel 756a514aa4 ArmPkg/CpuDxe: set DmaBufferAlignment according to CWG
The DmaBufferAlignment currently defaults to 4, which is dangerously
small and may result in lost data on platforms that perform non-coherent
DMA. So instead, take the CWG value from the cache info registers.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2016-11-02 16:22:48 +00:00
Ard Biesheuvel a383ca341e ArmPkg/ArmCortexA9Lib RVCT: remove incompatible GCC include
Drop the include of AsmMacroIoLib.h, which contains GCC preprocessor macros
that RVCT does not use or require, given it has its own AsmMacroIoLib.inc

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Ryan Harkin <ryan.harkin@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2016-10-28 10:24:24 +01:00
Kurt Kennett f6be48e990 ArmPkg/CpuDxe: Fix MMU initialization problem
During Mmu initialization in the CpuDxe, for a page table any bits set
in the 'NextSectionAttributes' are garbage and were set from bits that
are actually part of the pagetable address.  We clear it out to zero
so that the SyncCacheConfigPage will use the page attributes instead
of trying to convert the (bogus) section attributes into page
attributes.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Kurt Kennett <kurt.kennett@microsoft.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2016-09-26 15:50:28 -07:00
Ard Biesheuvel 92cec05e27 ArmPkg/ArmGicLib: use correct loop variable
The ArmGicLib API function GicGetCpuRedistributorBase () declares
GicCpuRedistributorBase to iterate over the redistributors of all
CPUs, but then inadvertently advances GicRedistributorBase instead.

Reported-by: "Oliyil Kunnil, Vishal" <vishalo@qti.qualcomm.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2016-09-09 16:56:38 +01:00
Dennis Chen 8a1f2378d7 ArmPkg ArmPlatformPkg ArmVirtPkg: ARM GICv2/v3 Base Address width fix-up
According to the ACPI 6.0/6.1 spec, the physical base address of GICC,
GICD, GICR and GIC ITS is 64-bit. So change the type of the various GIC
base address PCDs to 64-bit, and fix up all users.

Contributed-under: TianoCore Contribution Agreement 1.0
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Signed-off-by: Dennis Chen <dennis.chen@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2016-09-08 09:16:01 +01:00
Ard Biesheuvel f0883e35de ArmPkg/ArmGicV3: switch to ASM_FUNC() asm macro
Annotate functions with ASM_FUNC() so that they are emitted into
separate sections.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2016-08-11 12:29:31 +02:00
Ard Biesheuvel 136df8b8b2 ArmPkg/ArmCpuLib: switch to ASM_FUNC() asm macro
Annotate functions with ASM_FUNC() so that they are emitted into
separate sections.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2016-08-11 12:29:31 +02:00
Alexei Fedorov 7989300df7 ArmPkg/ArmGicDxe: Fix double GIC EIOR write per interrupt
This commit fixes a bug in the GIC v2 and v3 drivers where the GICC_EOIR
(End Of Interrupt Register) is written twice for a single interrupt.
GicV(2|3)IrqInterruptHandler() calls the Interrupt Handler and then
GicV(2|3)EndOfInterrupt() on exit:

 InterruptHandler = gRegisteredInterruptHandlers[GicInterrupt];
 if (InterruptHandler != NULL) {
   // Call the registered interrupt handler.
   InterruptHandler (GicInterrupt, SystemContext);
 } else {
   DEBUG ((EFI_D_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt));
 }

 GicV2EndOfInterrupt (&gHardwareInterruptV2Protocol, GicInterrupt);

although gInterrupt->EndOfInterrupt() can be expected to have already
been called by InterruptHandler() [which is the case for the primary
in-tree handler in TimerDxe]

The fix moves the EndOfInterrupt() call inside the else case for
unregistered/spurious interrupts. This removes a potential race
condition that might have lost interrupts.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Alexei Fedorov <alexei.fedorov@arm.com>
Signed-off-by: Evan Lloyd <evan.lloyd@arm.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2016-08-08 15:46:00 +02:00