Commit graph

23 commits

Author SHA1 Message Date
Andre Przywara
b7253a14cd fix(fpga): include missing header file
Since transitioning over FEAT_SPE to the new feature checking scheme, we
make use of the new is_feat_spe_supported() function in the Arm FPGA
platform code. However this missed to include the header file, so the
build broke.

Add the arch_features.h header to make arm_fpga compile again.

Change-Id: I5c8feecfcc6fb5845a6671842850df1943086a58
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
2023-03-23 13:25:41 +00:00
Andre Przywara
6437a09a2d refactor(spe): enable FEAT_SPE for FEAT_STATE_CHECKED
At the moment we only support FEAT_SPE to be either unconditionally
compiled in, or to be not supported at all.

Add support for runtime detection (ENABLE_SPE_FOR_NS=2), by splitting
is_armv8_2_feat_spe_present() into an ID register reading function and
a second function to report the support status. That function considers
both build time settings and runtime information (if needed), and is
used before we access SPE related registers.

Previously SPE was enabled unconditionally for all platforms, change
this now to the runtime detection version.

Change-Id: I830c094107ce6a398bf1f4aef7ffcb79d4f36552
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
2023-03-20 13:37:36 +00:00
Andre Przywara
422b44fb56 feat(arm_fpga): write UART baud base clock frequency into DTB
Since we now autodetect the actual system frequency, which is also used
as the base for the UART baudrate generation, we should update the value
currently hard-coded in the DT. Otherwise Linux will reprogram the
divider using a potentially wrong base rate, which breaks the UART
output.

Find the DT node referenced by the UART node as the clock rate, and set
the "clock-frequency" property in that node to the detected system
frequency. This will let Linux reprogram the divider to the same value,
preserving the actual baudrate.

Change-Id: Ib5a936849f2198577b86509f032751d5386ed2f8
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
2021-11-04 15:58:34 +00:00
Andre Przywara
d850169c9c feat(arm_fpga): query PL011 to learn system frequency
The Arm FPGAs run in mostly one clock domain, which is used for the CPU
cores, the generic timer, and also the UART baudrate base clock. This
single clock can have different rates, to compensate for different IP
complexity. So far most images used 10 MHz, but different rates start to
appear.

To avoid patching both the arch timer frequency and UART baud base fixed
clock in the DTB manually, we would like to set the clock rate
automatically. Fortunately the SCP firmware has the actual clock rate
hard coded, and already programs the PL011 UART baud divider register
with the correct value to achieve a 38400 bps baudrate.

So read the two PL011 baudrate divider values and re-calculate the
original base clock from there, to use as the arch timer frequency. If
the arch timer DT node contains a clock-frequency property, we use that
instead, to support overriding and disabling this autodetection.

Change-Id: I9857fbb418deb4644aeb2816f1102796f9bfd3bb
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
2021-11-04 15:58:34 +00:00
Andre Przywara
52b8f4465e refactor(arm_fpga): move command line code into separate function
The code dealing with finding the command line and inserting that into
the DTB is somewhat large, and drowns the other DT handlers in our
fpga_prepare_dtb() function.

Move that code into a separate function, to improve readability.

Change-Id: I828203c4bb248d38a2562fcb6afdefedf3179f8d
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
2021-11-04 15:58:34 +00:00
Andre Przywara
d7e39c43f2 feat(arm_fpga): add ITS autodetection
Some FPGAs come with a GIC that has an ITS block configured. Since the
ITS sits between the distributor and redistributors, we can autodetect
that, and already adjust the GICR base address.

To also make this ITS usable, add an ITS node to our base DTB, and
remove that should we not find an ITS during the scan for the
redistributor. This allows to use the same TF-A binary for FPGA images
with or without an ITS.

Change-Id: I4c0417dec7bccdbad8cbca26fa2634950fc50a66
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
2021-11-04 15:58:34 +00:00
Andre Przywara
93b785f5ae feat(arm_fpga): determine GICR base by probing
When an Arm Ltd GIC (Arm GIC-[567]00) is instantiated with one or more
ITSes, the ITS MMIO frames appear between the distributor and
redistributor addresses. This makes the beginning of the redistributor
region dependent on the existence and number of ITSes.

To support various FPGA images, with and without ITSes, probe the
addresses in question, to learn whether they accommodate an ITS or a
redistributor. This can be safely done by looking at the PIDR[01]
registers, which contain an ID code for each region, documented in the
Arm GIC TRMs.

We try to find all ITSes instantiated, and skip either two or four 64K
frames, depending on GICv4.1 support. At some point we will find the
first redistributor; this address we then update in the DTB.

Change-Id: Iefb88c2afa989e044fe0b36b7020b56538c60b07
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
2021-11-04 15:58:34 +00:00
Andre Przywara
4d585fe52f feat(libfdt): also allow changing base address
For platforms where we don't know the number of cores at compile time,
the size of the GIC redistributor frame is then also undetermined, since
it depends on this number of cores.
On top of this the GICR base address can also change, when an unknown
number of ITS frames (including zero) take up space between the
distributor and redistributor.

So while those two adjustments are done for independent reasons, the
code for doing so is very similar, so we should utilise the existing
fdt_adjust_gic_redist() function.

Add an (optional) gicr_base parameters to the prototype, so callers can
choose to also adjust this base address later, if needed.

Change-Id: Id39c0ba83e7401fdff1944e86950bb7121f210e8
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
2021-11-04 15:58:34 +00:00
Madhukar Pappireddy
e2e0444443 Merge changes from topic "arm_fpga_resmem" into integration
* changes:
  fix(arm_fpga): reserve BL31 memory
  fix(arm_fpga): limit BL31 memory usage
2021-10-05 22:55:13 +02:00
Andre Przywara
13e16fee86 fix(arm_fpga): reserve BL31 memory
Embarrassingly we never told the non-secure world that secure firmware
lives in the first few hundred KBs of DRAM, so any non-secure payload
could happily overwrite TF-A, and we couldn't even blame it.

Advertise the BL31 region in the reserved-memory DT node, so non-secure
world stays out of it.

This fixes Linux booting on FPGAs with less memory than usual.

Change-Id: I7fbe7d42c0b251c0ccc43d7c50ca902013d152ec
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
2021-09-03 17:24:46 +01:00
Andre Przywara
c69f815b09 feat(arm_fpga): support GICv4 images
Up until now we relied on the GICs used in our FPGA images to be GICv3
compliant, without the "direct virtual injection" feature (aka GICv4)
enabled.
To support newer images which have GICv4 compliant GICs, enable the
newly introduced GICv4 detection code, and use that also when we adjust
the redistributor region size in the devicetree.

This allows the same BL31 image to be used with GICv3 or GICv4 FPGA
images.

Change-Id: I9f6435a6d5150983625efe3650a8b7d1ef11b1d1
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
2021-09-01 16:14:03 +01:00
Andre Przywara
858f40e379 feat(gicv3): detect GICv4 feature at runtime
At the moment we have a GIC_ENABLE_V4_EXTN build time variable to
determine whether the GIC interrupt controller is compliant to version
4.0 of the spec or not. This just changes the number of 64K MMIO pages
we expect per redistributor.

To support firmware builds which run on variable systems (emulators,
fast model or FPGAs), let's make this decision at runtime.
The GIC specification provides several architected flags to learn the
size of the MMIO frame per redistributor, we use GICR_TYPER[VLPI] here.

Provide a (static inline) function to return the size of each
redistributor.
We keep the GIC_ENABLE_V4_EXTN build time variable around, but change
its meaning to enable this autodetection code. Systems not defining this
rely on a "pure" GICv3 (as before), but platforms setting it to "1" can
now deal with both configurations.

Change-Id: I9ede4acf058846157a0a9e2ef6103bf07c7655d9
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
2021-09-01 16:14:03 +01:00
Andre Przywara
40a0de1972 arm_fpga: Remove SPE PMU DT node if SPE is not available
The Statistical Profiling Extension (SPE) is an architectural feature we
can safely detect at runtime. However it still relies on one piece of
platform-specific information: the interrupt line it is connected
to. This requires SPE to be described in a devicetree node.

Since SPE support varies with the CPU cores found on an FPGA image, we
should detect the presence of SPE at runtime, and remove a potentially
existing SPE PMU node from the DT.

This allows to always have the SPE node in a generic devicetree file,
without risking exposing it on a CPU without this feature.

Change-Id: I73d83ea8509b03fe7bba20b9cce8d1335035fa31
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
2020-09-29 13:28:25 +01:00
Andre Przywara
283e5595af arm_fpga: Adjust GICR size in DT to match number of cores
The size of a GICv3 redistributor region depends on the number of
cores in the system. For the ARM FPGA port, we detect the topology at
runtime, and adjust the CPU DT nodes accordingly.
Now the size of the GICR region must also be adjusted, or Linux will
fail to initialise the GICv3.

Use the newly introduced function to overwrite the GICR size entry in
the GICv3 reg property. We count the number of existing cores by
iterating over the GICR frames until we find the LAST bit set in TYPER.

Change-Id: Ib69565600859de9b1b15ceb8495172cd26d16fce
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
2020-09-29 13:28:25 +01:00
Javier Almansa Sobrino
20ff991e92 arm_fpga: Add support to populate the CPU nodes in the DTB
At the moment BL31 dynamically discovers the CPU topology of an FPGA
system at runtime, but does not export it to the non-secure world.
Any BL33 user would typically looks at the devicetree to learn about
existing CPUs.

This patch exports a minimum /cpus node in a devicetree to satisfy
the binding. This means that no cpumaps or caches are described.
This could be added later if needed.

An existing /cpus node in the DT will make the code bail out with a
message.

Signed-off-by: Javier Almansa Sobrino <javier.almansasobrino@arm.com>
Change-Id: I589a2b3412411a3660134bdcef3a65e8200e1d7e
2020-09-02 16:46:48 +01:00
Andre Przywara
fa30f73b37 arm_fpga: Support uploading a custom command line
The command line for BL33 payloads is typically taken from the DTB. On
"normal" systems the bootloader will put the right version in there, but
we typically don't use one on the FPGAs.
To avoid editing (and possibly re-packaging) the DTB for every change in
the command line, try to read it from some "magic" memory location
instead. It can be easily placed there by the tool that uploads the
other payloads to the FPGA's memory. BL31 will then replace the existing
command line in the DTB with that new string.

To avoid reading garbage, check the memory location for containing a
magic value. This is conveniently chosen to be a simple ASCII string, so
it can just preceed the actual command line in a text file:
--------------------------------
CMD:console=ttyAMA0,38400n8 debug loglevel=8
--------------------------------

Change-Id: I5923a80332c9fac3b4afd1a6aaa321233d0f60da
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
2020-07-30 17:18:37 +01:00
Javier Almansa Sobrino
727bbf680d arm_fpga: Add support for topology self-discovery
As secondary cores show up, they populate an array to
announce themselves so plat_core_pos_by_mpidr() can
return an invalid COREID code for any non-existing
MPIDR that it is queried about.

The Power Domain Tree Description is populated with
a topology based on the maximum harcoded values.

Signed-off-by: Javier Almansa Sobrino <javier.almansasobrino@arm.com>
Change-Id: I8fd64761a2296714ce0f37c46544f3e6f13b5f61
2020-07-24 15:06:42 +01:00
Andre Przywara
670c66af06 arm_fpga: Read generic timer counter frequency from DT
The ARM Generic Timer DT binding describes an (optional) property to
declare the counter frequency. Its usage is normally discouraged, as the
value should be read from the CNTFRQ_EL0 system register.

However in our case we can use it to program this register in the first
place, which avoids us to hard code a counter frequency into the code.
We keep some default value in, if the DT lacks that property for
whatever reason.

Change-Id: I5b71176db413f904f21eb16f3302fbb799cb0305
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
2020-05-05 15:36:51 +01:00
Andre Przywara
a82ea1dbbf arm_fpga: Remove bogus timer initialisation
The arm_fpga platform code contains an dubious line to initialise some
timer. On closer inspection this turn out to be bogus, as this was only
needed on some special (older) FPGA board, and is actually not needed on
the current model. Also the base address was wrong anyways.

Remove the code entirely.

Change-Id: I02e71aea645051b5addb42d972d7a79f04b81106
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
2020-04-09 13:53:50 +01:00
Oliver Swede
87762bce84 plat/arm/board/arm_fpga: Initialize the Generic Interrupt Controller
This initializes the GIC using the Arm GIC drivers in TF-A.
The initial FPGA image uses a GIC600 implementation, and so that its
power controller is enabled, this platform port calls the corresponding
implementation-specific routines.

Signed-off-by: Oliver Swede <oli.swede@arm.com>
Change-Id: I88d5a073eead4b653b1ca73273182cd98a95e4c5
2020-03-26 20:41:58 +00:00
Oliver Swede
2d696d1811 plat/arm/board/arm_fpga: Initialize the System Counter
This sets the frequency of the system counter so that the Delay Timer
driver programs the correct value to CNTCRL. This value depends on
the FPGA image being used, and is 10MHz for the initial test image.
Once configured, the BL31 platform setup sequence then enables the
system counter.

Signed-off-by: Oliver Swede <oli.swede@arm.com>
Change-Id: Ieb036a36fd990f350b5953357424a255b8ac5d5a
2020-03-26 20:40:50 +00:00
Oliver Swede
5cfe699f2b plat/arm/board/arm_fpga: Use preloaded BL33 alternative boot flow
This makes use of the PRELOADED_BL33_BASE flag to indicate to BL31 that
the BL33 payload (kernel) has already been loaded and resides in memory;
BL31 will then jump to the non-secure address.

For this port the BL33 payload is the Linux kernel, and in accordance
with the pre-kernel setup requirements (as specified in the `Booting
AArch64 Linux' documentation:
https://www.kernel.org/doc/Documentation/arm64/booting.txt),
this change also sets up the primary CPU's registers x0-x3 so they are
the expected values, which includes the address of the DTB at x0.

An external linker script is currently required to combine BL31, the
BL33 payload, and any other software images to create an ELF file that
can be uploaded to the FPGA board along with the bit file. It therefore
has dependencies on the value of PRELOADED_BL33_BASE (kernel base) and
the DTB base (plus any other relevant base addresses used to
distinguish the different ELF sections), both of which are set in this
patch.

Signed-off-by: Oliver Swede <oli.swede@arm.com>
Change-Id: If7ae8ee82d1e09fb05f553f6077ae13680dbf66b
2020-03-26 20:22:33 +00:00
Oliver Swede
536d906abc plat/arm/board/arm_fpga: Enable basic BL31 port for an FPGA image
This adds the minimal functions and definitions to create a basic
BL31 port for an initial FPGA image, in order for the port to be
uploaded to one the FPGA boards operated by an internal group within
Arm, such that BL31 runs as a payload for an image.

Future changes will enable the port for a wide range of system
configurations running on the FPGA boards to ensure compatibility with
multiple FPGA images.

It is expected that this will replace the FPGA fork of the Linux kernel
bootwrapper by performing similar secure-world initialization and setup
through the use of drivers and other well-established methods, before
passing control to the kernel, which will act as the BL33 payload and
run in EL2NS.

This change introduces a basic, loadable port with the console
initialized by setting the baud rate and base address of the UART as
configured by the Zeus image.

It is a BL31-only port, and RESET_TO_BL31 is enabled to reflect this.

Signed-off-by: Oliver Swede <oli.swede@arm.com>
Change-Id: I1817ad81be00afddcdbbda1ab70eb697203178e2
2020-03-26 20:22:30 +00:00