Merge changes from topic "memory_bank" into integration

* changes:
  fix(qemu): statically allocate bitlocks array
  feat(qemu): update for renamed struct memory_bank
  feat(fvp): increase GPT PPS to 1TB
  feat(gpt): statically allocate bitlocks array
  chore(gpt): define PPS in platform header files
  feat(fvp): allocate L0 GPT at the top of SRAM
  feat(fvp): change size of PCIe memory region 2
  feat(rmm): add PCIe IO info to Boot manifest
  feat(fvp): define single Root region
This commit is contained in:
Soby Mathew 2025-02-12 10:49:42 +01:00 committed by TrustedFirmware Code Review
commit e13622312e
31 changed files with 674 additions and 389 deletions

View file

@ -277,7 +277,7 @@ int fdtw_write_inplace_bytes(void *dtb, int node, const char *prop,
return err;
}
static uint64_t fdt_read_prop_cells(const fdt32_t *prop, int nr_cells)
uint64_t fdt_read_prop_cells(const fdt32_t *prop, int nr_cells)
{
uint64_t reg = fdt32_to_cpu(prop[0]);

View file

@ -124,10 +124,7 @@ Level 0 and Level 1 Tables
The GPT initialization APIs require memory to be passed in for the tables to be
constructed. The ``gpt_init_l0_tables`` API takes a memory address and size for
building the level 0 tables and also memory for allocating the fine-grained bitlock
data structure. The amount of memory needed for bitlock structure is controlled via
``RME_GPT_BITLOCK_BLOCK`` config which defines the block size for each bit of the
the bitlock.
building the level 0 tables.
The ``gpt_init_pas_l1_tables`` API takes an address and size for
building the level 1 tables which are linked from level 0 descriptors. The
@ -156,7 +153,7 @@ Locking Scheme
During Granule Transition access to L1 tables is controlled by a lock to ensure
that no more than one CPU is allowed to make changes at any given time.
The granularity of the lock is defined by ``RME_GPT_BITLOCK_BLOCK`` build option
which defines the size of the memory block protected by one bit of ``bitlock``
which defines the size of the memory block protected by one bit of ``bitlock_t``
structure. Setting this option to 0 chooses a single spinlock for all GPT L1
table entries.
@ -185,6 +182,10 @@ process.
#. In systems that make use of the granule transition service, runtime
firmware must call ``gpt_runtime_init`` to set up the data structures needed
by the GTSI to find the tables and transition granules between PAS types.
The base address of bitlocks array and its size are provided to this function
as arguments. These parameters are not used in case of a single spinlock for
all GPT L1 table entries(``RME_GPT_BITLOCK_BLOCK`` is 0) and are passed as zero
values.
API Constraints
~~~~~~~~~~~~~~~
@ -225,9 +226,6 @@ The L0 table memory has some constraints that must be taken into account.
is greater. L0 table size is the total protected space (PPS) divided by the
size of each L0 region (L0GPTSZ) multiplied by the size of each L0 descriptor
(8 bytes). ((PPS / L0GPTSZ) * 8)
* The L0 memory size must be greater than the table size and have enough space
to allocate array of ``bitlock`` structures at the end of L0 table if
required (``RME_GPT_BITLOCK_BLOCK`` is not 0).
* The L0 memory must fall within a PAS of type GPT_GPI_ROOT.
The L1 memory also has some constraints.
@ -237,6 +235,10 @@ The L1 memory also has some constraints.
the granules controlled in each byte (2). ((L0GPTSZ / PGS) / 2)
* There must be enough L1 memory supplied to build all requested L1 tables.
* The L1 memory must fall within a PAS of type GPT_GPI_ROOT.
* The platform allocates the bitlock array which contains fine-grained
``bitlock_t`` data structures. The RME GPT library will check that the array
has at least the amount of memory defined by PPS and ``RME_GPT_BITLOCK_BLOCK``
value.
If an invalid combination of parameters is supplied, the APIs will print an
error message and return a negative value. The return values of APIs should be
@ -245,7 +247,7 @@ checked to ensure successful configuration.
Sample Calculation for L0 memory size and alignment
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Let PPS=GPCCR_PPS_4GB and L0GPTSZ=GPCCR_L0GPTSZ_30BITS
Let PPS=4GB and L0GPTSZ=GPCCR_L0GPTSZ_30BITS
We can find the total L0 table size with ((PPS / L0GPTSZ) * 8)
@ -254,19 +256,19 @@ Substitute values to get this: ((0x100000000 / 0x40000000) * 8)
And solve to get 32 bytes. In this case, 4096 is greater than 32, so the L0
tables must be aligned to 4096 bytes.
Sample calculation for bitlock array size
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sample calculation for bitlocks array size
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Let PGS=GPCCR_PPS_256TB and RME_GPT_BITLOCK_BLOCK=1
Let PPS=256TB and RME_GPT_BITLOCK_BLOCK=1
The size of bit lock array in bits is the total protected space (PPS) divided
The size of bitlocks array in bits is the total protected space (PPS) divided
by the size of memory block per bit. The size of memory block
is ``RME_GPT_BITLOCK_BLOCK`` (number of 512MB blocks per bit) times
512MB (0x20000000). This is then divided by the number of bits in ``bitlock``
structure (8) to get the size of bit array in bytes.
512MB (0x20000000). This is then divided by the number of bits in ``bitlock_t``
structure (8) to get the size of array in bytes.
In other words, we can find the total size of ``bitlock`` array
in bytes with PPS / (RME_GPT_BITLOCK_BLOCK * 0x20000000 * 8).
In other words, we can find the total size of ``bitlock_t`` array
in bytes with PPS / (RME_GPT_BITLOCK_BLOCK * 0x20000000 * 8).
Substitute values to get this: 0x1000000000000 / (1 * 0x20000000 * 8)

View file

@ -53,7 +53,7 @@ are explained below:
consistency with the versioning schemes used in other parts of RMM.
This document specifies the 0.4 version of Boot Interface ABI and RMM-EL3
services specification and the 0.3 version of the Boot Manifest.
services specification and the 0.4 version of the Boot Manifest.
.. _rmm_el3_boot_interface:
@ -182,12 +182,12 @@ platform information.
This Boot Manifest is versioned independently of the Boot Interface, to help
evolve the former independent of the latter.
The current version for the Boot Manifest is ``v0.3`` and the rules explained
The current version for the Boot Manifest is ``v0.4`` and the rules explained
in :ref:`rmm_el3_ifc_versioning` apply on this version as well.
The Boot Manifest v0.3 has the following fields:
The Boot Manifest v0.4 has the following fields:
- version : Version of the Manifest (v0.3)
- version : Version of the Manifest (v0.4)
- plat_data : Pointer to the platform specific data and not specified by this
document. These data are optional and can be NULL.
- plat_dram : Structure encoding the NS DRAM information on the platform. This
@ -720,61 +720,65 @@ _____
RMM-EL3 Boot Manifest structure
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The RMM-EL3 Boot Manifest v0.3 structure contains platform boot information passed
from EL3 to RMM. The size of the Boot Manifest is 64 bytes.
The RMM-EL3 Boot Manifest v0.4 structure contains platform boot information passed
from EL3 to RMM. The size of the Boot Manifest is 112 bytes.
The members of the RMM-EL3 Boot Manifest structure are shown in the following
table:
+--------------+--------+----------------+----------------------------------------+
| Name | Offset | Type | Description |
+==============+========+================+========================================+
| version | 0 | uint32_t | Boot Manifest version |
+--------------+--------+----------------+----------------------------------------+
| padding | 4 | uint32_t | Reserved, set to 0 |
+--------------+--------+----------------+----------------------------------------+
| plat_data | 8 | uintptr_t | Pointer to Platform Data section |
+--------------+--------+----------------+----------------------------------------+
| plat_dram | 16 | ns_dram_info | NS DRAM Layout Info structure |
+--------------+--------+----------------+----------------------------------------+
| plat_console | 40 | console_list | List of consoles available to RMM |
+--------------+--------+----------------+----------------------------------------+
+--------------------+--------+-------------------+----------------------------------------------+
| Name | Offset | Type | Description |
+====================+========+===================+==============================================+
| version | 0 | uint32_t | Boot Manifest version |
+--------------------+--------+-------------------+----------------------------------------------+
| padding | 4 | uint32_t | Reserved, set to 0 |
+--------------------+--------+-------------------+----------------------------------------------+
| plat_data | 8 | uintptr_t | Pointer to Platform Data section |
+--------------------+--------+-------------------+----------------------------------------------+
| plat_dram | 16 | memory_info | NS DRAM Layout Info structure |
+--------------------+--------+-------------------+----------------------------------------------+
| plat_console | 40 | console_list | List of consoles available to RMM |
+--------------------+--------+-------------------+----------------------------------------------+
| plat_ncoh_region | 64 | memory_info | Device non-coherent ranges Info structure |
+--------------------+--------+-------------------+----------------------------------------------+
| plat_coh_region | 88 | memory_info | Device coherent ranges Info structure |
+--------------------+--------+-------------------+----------------------------------------------+
.. _ns_dram_info_struct:
.. _memory_info_struct:
NS DRAM Layout Info structure
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Memory Info structure
~~~~~~~~~~~~~~~~~~~~~~
NS DRAM Layout Info structure contains information about platform Non-secure
DRAM layout. The members of this structure are shown in the table below:
Memory Info structure contains information about platform memory layout.
The members of this structure are shown in the table below:
+-----------+--------+----------------+----------------------------------------+
| Name | Offset | Type | Description |
+===========+========+================+========================================+
| num_banks | 0 | uint64_t | Number of NS DRAM banks |
| num_banks | 0 | uint64_t | Number of memory banks/device regions |
+-----------+--------+----------------+----------------------------------------+
| banks | 8 | ns_dram_bank * | Pointer to 'ns_dram_bank'[] array |
| banks | 8 | memory_bank * | Pointer to 'memory_bank'[] array |
+-----------+--------+----------------+----------------------------------------+
| checksum | 16 | uint64_t | Checksum |
+-----------+--------+----------------+----------------------------------------+
Checksum is calculated as two's complement sum of 'num_banks', 'banks' pointer
and DRAM banks data array pointed by it.
and memory banks data array pointed by it.
.. _ns_dram_bank_struct:
.. _memory_bank_struct:
NS DRAM Bank structure
~~~~~~~~~~~~~~~~~~~~~~
Memory Bank/Device region structure
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NS DRAM Bank structure contains information about each Non-secure DRAM bank:
Memory Bank structure contains information about each memory bank/device region:
+-----------+--------+----------------+----------------------------------------+
| Name | Offset | Type | Description |
+===========+========+================+========================================+
| base | 0 | uintptr_t | Base address |
+-----------+--------+----------------+----------------------------------------+
| size | 8 | uint64_t | Size of bank in bytes |
+-----------+--------+----------------+----------------------------------------+
+-----------+--------+----------------+--------------------------------------------+
| Name | Offset | Type | Description |
+===========+========+================+============================================+
| base | 0 | uintptr_t | Base address |
+-----------+--------+----------------+--------------------------------------------+
| size | 8 | uint64_t | Size of memory bank/device region in bytes |
+-----------+--------+----------------+--------------------------------------------+
.. _console_list_struct:
@ -784,15 +788,15 @@ Console List structure
Console List structure contains information about the available consoles for RMM.
The members of this structure are shown in the table below:
+--------------+--------+----------------+----------------------------------------+
| Name | Offset | Type | Description |
+==============+========+================+========================================+
| num_consoles | 0 | uint64_t | Number of consoles |
+--------------+--------+----------------+----------------------------------------+
| consoles | 8 | console_info * | Pointer to 'console_info'[] array |
+--------------+--------+----------------+----------------------------------------+
| checksum | 16 | uint64_t | Checksum |
+--------------+--------+----------------+----------------------------------------+
+--------------+--------+----------------+-------------------------------------+
| Name | Offset | Type | Description |
+==============+========+================+=====================================+
| num_consoles | 0 | uint64_t | Number of consoles |
+--------------+--------+----------------+-------------------------------------+
| consoles | 8 | console_info * | Pointer to 'console_info'[] array |
+--------------+--------+----------------+-------------------------------------+
| checksum | 16 | uint64_t | Checksum |
+--------------+--------+----------------+-------------------------------------+
Checksum is calculated as two's complement sum of 'num_consoles', 'consoles'
pointer and the consoles array pointed by it.
@ -804,28 +808,28 @@ Console Info structure
Console Info structure contains information about each Console available to RMM.
+-----------+--------+---------------+----------------------------------------+
| Name | Offset | Type | Description |
+===========+========+===============+========================================+
| base | 0 | uintptr_t | Console Base address |
+-----------+--------+---------------+----------------------------------------+
| map_pages | 8 | uint64_t | Num of pages to map for console MMIO |
+-----------+--------+---------------+----------------------------------------+
| name | 16 | char[] | Name of console |
+-----------+--------+---------------+----------------------------------------+
| clk_in_hz | 24 | uint64_t | UART clock (in hz) for console |
+-----------+--------+---------------+----------------------------------------+
| baud_rate | 32 | uint64_t | Baud rate |
+-----------+--------+---------------+----------------------------------------+
| flags | 40 | uint64_t | Additional flags (RES0) |
+-----------+--------+---------------+----------------------------------------+
+-----------+--------+---------------+-----------------------------------------+
| Name | Offset | Type | Description |
+===========+========+===============+=========================================+
| base | 0 | uintptr_t | Console Base address |
+-----------+--------+---------------+-----------------------------------------+
| map_pages | 8 | uint64_t | Num of pages to map for console MMIO |
+-----------+--------+---------------+-----------------------------------------+
| name | 16 | char[8] | Name of console |
+-----------+--------+---------------+-----------------------------------------+
| clk_in_hz | 24 | uint64_t | UART clock (in Hz) for console |
+-----------+--------+---------------+-----------------------------------------+
| baud_rate | 32 | uint64_t | Baud rate |
+-----------+--------+---------------+-----------------------------------------+
| flags | 40 | uint64_t | Additional flags (RES0) |
+-----------+--------+---------------+-----------------------------------------+
.. _el3_token_sign_request_struct:
EL3 Token Sign Request structure
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This structure represents a realm attestation toekn signing request.
This structure represents a realm attestation token signing request.
+-------------+--------+---------------+-----------------------------------------+
| Name | Offset | Type | Description |

View file

@ -137,7 +137,8 @@ Arm FVP Build Options
---------------------
- ``FVP_TRUSTED_SRAM_SIZE``: Size (in kilobytes) of the Trusted SRAM region to
utilize when building for the FVP platform. This option defaults to 256.
utilize when building for the FVP platform. This option defaults to 256 with
build option ENABLE_RME=0 and 384 for ENABLE_RME=1.
Arm Juno Build Options
----------------------

View file

@ -7,7 +7,7 @@
*
* RTSM_VE_AEMv8A.lisa
*
* Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2017-2025, ARM Limited and Contributors. All rights reserved.
*/
#include <dt-bindings/interrupt-controller/arm-gic.h>
@ -249,4 +249,39 @@
<0 0 44 &gic 0 GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
<0 0 46 &gic 0 GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
};
#if (ENABLE_RME == 1)
pci: pci@40000000 {
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
compatible = "pci-host-ecam-generic";
device_type = "pci";
reg = <0x0 0x40000000 0x0 0x10000000>;
ranges = <0x2000000 0x0 0x50000000 0x0 0x50000000 0x0 0x10000000>,
/* First 3GB of 256GB PCIe memory region 2 */
<0x2000000 0x40 0x00000000 0x40 0x00000000 0x0 0xc0000000>;
interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>,
<0 0 0 2 &gic 0 0 GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>,
<0 0 0 3 &gic 0 0 GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
<0 0 0 4 &gic 0 0 GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
interrupt-map-mask = <0x0 0x0 0x0 0x7>;
msi-map = <0x0 &its 0x0 0x10000>;
iommu-map = <0x0 &smmu 0x0 0x10000>;
dma-coherent;
};
smmu: iommu@2b400000 {
compatible = "arm,smmu-v3";
reg = <0x0 0x2b400000 0x0 0x100000>;
interrupts = <GIC_SPI 74 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 79 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 75 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 77 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "eventq", "gerror", "priq", "cmdq-sync";
dma-coherent;
#iommu-cells = <1>;
msi-parent = <&its 0x10000>;
};
#endif /* ENABLE_RME */
};

View file

@ -49,6 +49,8 @@ int fdtw_for_each_cpu(const void *fdt,
int fdtw_find_or_add_subnode(void *fdt, int parentoffset, const char *name);
uint64_t fdt_read_prop_cells(const fdt32_t *prop, int nr_cells);
static inline uint32_t fdt_blob_size(const void *dtb)
{
const uint32_t *dtb_header = (const uint32_t *)dtb;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Arm Limited. All rights reserved.
* Copyright (c) 2022-2025, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -8,13 +8,20 @@
#define GPT_RME_H
#include <stdint.h>
#include <arch.h>
#include <lib/spinlock.h>
/******************************************************************************/
/* GPT helper macros and definitions */
/******************************************************************************/
#if (RME_GPT_BITLOCK_BLOCK != 0)
#define LOCK_SIZE sizeof(((bitlock_t *)NULL)->lock)
#define LOCK_TYPE typeof(((bitlock_t *)NULL)->lock)
#define LOCK_BITS (LOCK_SIZE * UL(8))
CASSERT((UL(1) == LOCK_SIZE), assert_bitlock_type_not_uint8_t);
#endif /* RME_GPT_BITLOCK_BLOCK */
/*
* Structure for specifying a mapping range and it's properties. This should not
* be manually initialized, using the MAP_GPT_REGION_x macros is recommended as
@ -238,10 +245,14 @@ int gpt_init_pas_l1_tables(gpccr_pgs_e pgs,
* initialization from a previous stage. Granule protection checks must be
* enabled already or this function will return an error.
*
* Parameters
* l1_bitlocks_base Base address of memory for L1 tables bitlocks.
* l1_bitlocks_size Total size of memory available for L1 tables bitlocks.
*
* Return
* Negative Linux error code in the event of a failure, 0 for success.
*/
int gpt_runtime_init(void);
int gpt_runtime_init(uintptr_t l1_bitlocks_base, size_t l1_bitlocks_size);
/*
* Public API to enable granule protection checks once the tables have all been

View file

@ -20,7 +20,6 @@
* Definitions common to all ARM standard platforms
*****************************************************************************/
/* Special value used to verify platform parameters from BL2 to BL31 */
#define ARM_BL31_PLAT_PARAM_VAL ULL(0x0f1e2d3c4b5a6978)
@ -63,11 +62,22 @@
#define ARM_SHARED_RAM_BASE ARM_TRUSTED_SRAM_BASE
#define ARM_SHARED_RAM_SIZE UL(0x00001000) /* 4 KB */
#if ENABLE_RME
/* Store level 0 GPT at the top of the Trusted SRAM */
#define ARM_L0_GPT_BASE (ARM_TRUSTED_SRAM_BASE + \
PLAT_ARM_TRUSTED_SRAM_SIZE - \
ARM_L0_GPT_SIZE)
#define ARM_L0_GPT_SIZE UL(0x00002000) /* 8 KB */
#else
#define ARM_L0_GPT_SIZE UL(0)
#endif
/* The remaining Trusted SRAM is used to load the BL images */
#define ARM_BL_RAM_BASE (ARM_SHARED_RAM_BASE + \
ARM_SHARED_RAM_SIZE)
#define ARM_BL_RAM_SIZE (PLAT_ARM_TRUSTED_SRAM_SIZE - \
#define ARM_BL_RAM_BASE (ARM_SHARED_RAM_BASE + \
ARM_SHARED_RAM_SIZE)
#define ARM_BL_RAM_SIZE (PLAT_ARM_TRUSTED_SRAM_SIZE - \
ARM_SHARED_RAM_SIZE - \
ARM_L0_GPT_SIZE)
/*
* The top 16MB (or 64MB if RME is enabled) of DRAM1 is configured as
@ -110,6 +120,7 @@
* placed here. 3MB region is reserved if RME is enabled, 2MB otherwise.
*/
#define ARM_EL3_TZC_DRAM1_SIZE UL(0x00300000) /* 3MB */
/* 8 x 128KB L1 pages (L0GPTSZ = 1GB, PGS = 4KB) */
#define ARM_L1_GPT_SIZE UL(0x00100000) /* 1MB */
/* 32MB - ARM_EL3_RMM_SHARED_SIZE */
#define ARM_REALM_SIZE (UL(0x02000000) - \
@ -150,7 +161,7 @@ MEASURED_BOOT
#endif /* (SPD_tspd || SPD_opteed || SPD_spmd) && MEASURED_BOOT */
#if ENABLE_RME
#define ARM_L1_GPT_BASE (ARM_DRAM1_BASE + \
#define ARM_L1_GPT_BASE (ARM_DRAM1_BASE + \
ARM_DRAM1_SIZE - \
ARM_L1_GPT_SIZE)
#define ARM_L1_GPT_END (ARM_L1_GPT_BASE + \
@ -246,6 +257,9 @@ MEASURED_BOOT
/* Number of DRAM banks */
#define ARM_DRAM_NUM_BANKS 2UL
/* Number of PCIe memory regions */
#define ARM_PCI_NUM_REGIONS 2UL
#define ARM_IRQ_SEC_PHY_TIMER 29
#define ARM_IRQ_SEC_SGI_0 8
@ -352,7 +366,6 @@ MEASURED_BOOT
ARM_EL3_RMM_SHARED_BASE, \
ARM_EL3_RMM_SHARED_SIZE, \
MT_MEMORY | MT_RW | MT_REALM)
#endif /* ENABLE_RME */
/*
@ -540,18 +553,6 @@ MEASURED_BOOT
#define ARM_FW_CONFIGS_LIMIT (ARM_BL_RAM_BASE + ARM_FW_CONFIGS_SIZE)
#endif
#if ENABLE_RME
/*
* Store the L0 GPT on Trusted SRAM next to firmware
* configuration memory, 4KB aligned.
*/
#define ARM_L0_GPT_SIZE (PAGE_SIZE)
#define ARM_L0_GPT_BASE (ARM_FW_CONFIGS_LIMIT)
#define ARM_L0_GPT_LIMIT (ARM_L0_GPT_BASE + ARM_L0_GPT_SIZE)
#else
#define ARM_L0_GPT_SIZE U(0)
#endif
/*******************************************************************************
* BL1 specific defines.
* BL1 RW data is relocated from ROM to RAM at runtime so we need 2 sets of
@ -567,7 +568,8 @@ MEASURED_BOOT
#endif
/*
* Put BL1 RW at the top of the Trusted SRAM.
* With ENABLE_RME=1 put BL1 RW below L0 GPT,
* or at the top of Trusted SRAM otherwise.
*/
#define BL1_RW_BASE (ARM_BL_RAM_BASE + \
ARM_BL_RAM_SIZE - \

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -43,6 +43,11 @@
#define SZ_1G UL(0x40000000)
#define SZ_2G UL(0x80000000)
#define SZ_1T UL(0x10000000000)
#define SZ_4T UL(0x40000000000)
#define SZ_1P UL(0x4000000000000)
#else /* !__aarch64__ */
#define SZ_32 U(0x00000020)
#define SZ_64 U(0x00000040)

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2024, Arm Limited. All rights reserved.
* Copyright (c) 2022-2025, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -14,7 +14,7 @@
#include <lib/cassert.h>
#define RMMD_MANIFEST_VERSION_MAJOR U(0)
#define RMMD_MANIFEST_VERSION_MINOR U(3)
#define RMMD_MANIFEST_VERSION_MINOR U(4)
#define RMM_CONSOLE_MAX_NAME_LEN U(8)
@ -37,29 +37,29 @@
#define RMMD_GET_MANIFEST_VERSION_MINOR(_version) \
(_version & 0xFFFF)
/* NS DRAM bank structure */
struct ns_dram_bank {
/* Memory bank/device region structure */
struct memory_bank {
uintptr_t base; /* Base address */
uint64_t size; /* Size of bank */
uint64_t size; /* Size of memory bank/device region */
};
CASSERT(offsetof(struct ns_dram_bank, base) == 0UL,
CASSERT(offsetof(struct memory_bank, base) == 0UL,
rmm_manifest_base_unaligned);
CASSERT(offsetof(struct ns_dram_bank, size) == 8UL,
CASSERT(offsetof(struct memory_bank, size) == 8UL,
rmm_manifest_size_unaligned);
/* NS DRAM layout info structure */
struct ns_dram_info {
uint64_t num_banks; /* Number of NS DRAM banks */
struct ns_dram_bank *banks; /* Pointer to ns_dram_bank[] */
uint64_t checksum; /* Checksum of ns_dram_info data */
/* Memory/device region layout info structure */
struct memory_info {
uint64_t num_banks; /* Number of memory banks/device regions */
struct memory_bank *banks; /* Pointer to memory_bank[] */
uint64_t checksum; /* Checksum of memory_info data */
};
CASSERT(offsetof(struct ns_dram_info, num_banks) == 0UL,
CASSERT(offsetof(struct memory_info, num_banks) == 0UL,
rmm_manifest_num_banks_unaligned);
CASSERT(offsetof(struct ns_dram_info, banks) == 8UL,
CASSERT(offsetof(struct memory_info, banks) == 8UL,
rmm_manifest_dram_data_unaligned);
CASSERT(offsetof(struct ns_dram_info, checksum) == 16UL,
CASSERT(offsetof(struct memory_info, checksum) == 16UL,
rmm_manifest_checksum_unaligned);
/* Console info structure */
@ -98,13 +98,18 @@ CASSERT(offsetof(struct console_list, consoles) == 8UL,
CASSERT(offsetof(struct console_list, checksum) == 16UL,
rmm_manifest_console_list_checksum);
/* Boot manifest core structure as per v0.3 */
/* Boot manifest core structure as per v0.4 */
struct rmm_manifest {
uint32_t version; /* Manifest version */
uint32_t padding; /* RES0 */
uintptr_t plat_data; /* Manifest platform data */
struct ns_dram_info plat_dram; /* Platform NS DRAM data (v0.2) */
struct console_list plat_console; /* Platform console list (v0.3) */
/* Platform NS DRAM data (v0.2) */
struct memory_info plat_dram;
/* Platform console list (v0.3) */
struct console_list plat_console;
/* Platform device address ranges (v0.4) */
struct memory_info plat_ncoh_region;
struct memory_info plat_coh_region;
};
CASSERT(offsetof(struct rmm_manifest, version) == 0UL,
@ -115,5 +120,9 @@ CASSERT(offsetof(struct rmm_manifest, plat_dram) == 16UL,
rmm_manifest_plat_dram_unaligned);
CASSERT(offsetof(struct rmm_manifest, plat_console) == 40UL,
rmm_manifest_plat_console_unaligned);
CASSERT(offsetof(struct rmm_manifest, plat_ncoh_region) == 64UL,
rmm_manifest_plat_ncoh_region_unaligned);
CASSERT(offsetof(struct rmm_manifest, plat_coh_region) == 88UL,
rmm_manifest_plat_coh_region_unaligned);
#endif /* RMM_CORE_MANIFEST_H */

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2024, Arm Limited. All rights reserved.
* Copyright (c) 2022-2025, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -12,14 +12,13 @@
#include <arch.h>
#include <arch_features.h>
#include <arch_helpers.h>
#include <common/debug.h>
#include "gpt_rme_private.h"
#include <lib/gpt_rme/gpt_rme.h>
#include <lib/smccc.h>
#include <lib/spinlock.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include "gpt_rme_private.h"
#if !ENABLE_RME
#error "ENABLE_RME must be enabled to use the GPT library"
#endif
@ -123,25 +122,19 @@ static uint64_t gpt_l1_index_mask;
#define GPT_L1_INDEX(_pa) \
(((_pa) >> (unsigned int)GPT_L1_IDX_SHIFT(gpt_config.p)) & gpt_l1_index_mask)
/* These variables are used during initialization of the L1 tables */
/* This variable is used during initialization of the L1 tables */
static uintptr_t gpt_l1_tbl;
/* These variable is used during runtime */
/* These variables are used during runtime */
#if (RME_GPT_BITLOCK_BLOCK == 0)
/*
* The GPTs are protected by a global spinlock to ensure
* that multiple CPUs do not attempt to change the descriptors at once.
*/
static spinlock_t gpt_lock;
#else
/* Bitlocks base address */
static bitlock_t *gpt_bitlock_base;
#endif
/* Lock/unlock macros for GPT entries */
#if (RME_GPT_BITLOCK_BLOCK == 0)
/*
/* Lock/unlock macros for GPT entries
*
* Access to GPT is controlled by a global lock to ensure
* that no more than one CPU is allowed to make changes at any
* given time.
@ -149,13 +142,17 @@ static bitlock_t *gpt_bitlock_base;
#define GPT_LOCK spin_lock(&gpt_lock)
#define GPT_UNLOCK spin_unlock(&gpt_lock)
#else
/* Base address of bitlocks array */
static bitlock_t *gpt_bitlock;
/*
* Access to a block of memory is controlled by a bitlock.
* Size of block = RME_GPT_BITLOCK_BLOCK * 512MB.
*/
#define GPT_LOCK bit_lock(gpi_info.lock, gpi_info.mask)
#define GPT_UNLOCK bit_unlock(gpi_info.lock, gpi_info.mask)
#endif
#endif /* RME_GPT_BITLOCK_BLOCK */
static void tlbi_page_dsbosh(uintptr_t base)
{
@ -494,8 +491,8 @@ static int validate_pas_mappings(pas_region_t *pas_regions,
* This function validates L0 initialization parameters.
*
* Parameters
* l0_mem_base Base address of memory used for L0 tables.
* l0_mem_size Size of memory available for L0 tables.
* l0_mem_base Base address of memory used for L0 table.
* l0_mem_size Size of memory available for L0 table.
*
* Return
* Negative Linux error code in the event of a failure, 0 for success.
@ -503,7 +500,7 @@ static int validate_pas_mappings(pas_region_t *pas_regions,
static int validate_l0_params(gpccr_pps_e pps, uintptr_t l0_mem_base,
size_t l0_mem_size)
{
size_t l0_alignment, locks_size = 0;
size_t l0_alignment;
/*
* Make sure PPS is valid and then store it since macros need this value
@ -516,8 +513,8 @@ static int validate_l0_params(gpccr_pps_e pps, uintptr_t l0_mem_base,
gpt_config.pps = pps;
gpt_config.t = gpt_t_lookup[pps];
/* Alignment must be the greater of 4KB or l0 table size */
l0_alignment = PAGE_SIZE_4KB;
/* Alignment must be the greater of 4KB or L0 table size */
l0_alignment = SZ_4K;
if (l0_alignment < GPT_L0_TABLE_SIZE(gpt_config.t)) {
l0_alignment = GPT_L0_TABLE_SIZE(gpt_config.t);
}
@ -529,28 +526,11 @@ static int validate_l0_params(gpccr_pps_e pps, uintptr_t l0_mem_base,
return -EFAULT;
}
#if (RME_GPT_BITLOCK_BLOCK != 0)
/*
* Size of bitlocks in bytes for the protected address space
* with RME_GPT_BITLOCK_BLOCK * 512MB per bitlock.
*/
locks_size = GPT_PPS_ACTUAL_SIZE(gpt_config.t) /
(RME_GPT_BITLOCK_BLOCK * SZ_512M * 8U);
/*
* If protected space size is less than the size covered
* by 'bitlock' structure, check for a single bitlock.
*/
if (locks_size < LOCK_SIZE) {
locks_size = LOCK_SIZE;
}
#endif
/* Check size for L0 tables and bitlocks */
if (l0_mem_size < (GPT_L0_TABLE_SIZE(gpt_config.t) + locks_size)) {
/* Check memory size for L0 table */
if (l0_mem_size < GPT_L0_TABLE_SIZE(gpt_config.t)) {
ERROR("GPT: Inadequate L0 memory\n");
ERROR(" Expected 0x%lx bytes, got 0x%lx bytes\n",
GPT_L0_TABLE_SIZE(gpt_config.t) + locks_size,
l0_mem_size);
ERROR(" Expected 0x%lx bytes, got 0x%lx\n",
GPT_L0_TABLE_SIZE(gpt_config.t), l0_mem_size);
return -ENOMEM;
}
@ -600,7 +580,7 @@ static int validate_l1_params(uintptr_t l1_mem_base, size_t l1_mem_size,
if (l1_mem_size < l1_gpt_mem_sz) {
ERROR("%sL1 GPTs%s", (const char *)"GPT: Inadequate ",
(const char *)" memory\n");
ERROR(" Expected 0x%lx bytes, got 0x%lx bytes\n",
ERROR(" Expected 0x%lx bytes, got 0x%lx\n",
l1_gpt_mem_sz, l1_mem_size);
return -ENOMEM;
}
@ -623,7 +603,7 @@ static void generate_l0_blk_desc(pas_region_t *pas)
unsigned long idx, end_idx;
uint64_t *l0_gpt_arr;
assert(gpt_config.plat_gpt_l0_base != 0U);
assert(gpt_config.plat_gpt_l0_base != 0UL);
assert(pas != NULL);
/*
@ -928,7 +908,7 @@ static void generate_l0_tbl_desc(pas_region_t *pas)
uint64_t *l1_gpt_arr;
unsigned int l0_idx, gpi;
assert(gpt_config.plat_gpt_l0_base != 0U);
assert(gpt_config.plat_gpt_l0_base != 0UL);
assert(pas != NULL);
/*
@ -1121,12 +1101,10 @@ int gpt_init_l0_tables(gpccr_pps_e pps, uintptr_t l0_mem_base,
size_t l0_mem_size)
{
uint64_t gpt_desc;
size_t locks_size = 0;
__unused bitlock_t *bit_locks;
int ret;
/* Ensure that MMU and Data caches are enabled */
assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U);
assert((read_sctlr_el3() & SCTLR_C_BIT) != 0UL);
/* Validate other parameters */
ret = validate_l0_params(pps, l0_mem_base, l0_mem_size);
@ -1142,31 +1120,8 @@ int gpt_init_l0_tables(gpccr_pps_e pps, uintptr_t l0_mem_base,
((uint64_t *)l0_mem_base)[i] = gpt_desc;
}
#if (RME_GPT_BITLOCK_BLOCK != 0)
/* Initialise bitlocks at the end of L0 table */
bit_locks = (bitlock_t *)(l0_mem_base +
GPT_L0_TABLE_SIZE(gpt_config.t));
/* Size of bitlocks in bytes */
locks_size = GPT_PPS_ACTUAL_SIZE(gpt_config.t) /
(RME_GPT_BITLOCK_BLOCK * SZ_512M * 8U);
/*
* If protected space size is less than the size covered
* by 'bitlock' structure, initialise a single bitlock.
*/
if (locks_size < LOCK_SIZE) {
locks_size = LOCK_SIZE;
}
for (size_t i = 0UL; i < (locks_size/LOCK_SIZE); i++) {
bit_locks[i].lock = 0U;
}
#endif
/* Flush updated L0 tables and bitlocks to memory */
flush_dcache_range((uintptr_t)l0_mem_base,
GPT_L0_TABLE_SIZE(gpt_config.t) + locks_size);
/* Flush updated L0 table to memory */
flush_dcache_range((uintptr_t)l0_mem_base, GPT_L0_TABLE_SIZE(gpt_config.t));
/* Stash the L0 base address once initial setup is complete */
gpt_config.plat_gpt_l0_base = l0_mem_base;
@ -1202,7 +1157,7 @@ int gpt_init_pas_l1_tables(gpccr_pgs_e pgs, uintptr_t l1_mem_base,
int l1_gpt_cnt, ret;
/* Ensure that MMU and Data caches are enabled */
assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U);
assert((read_sctlr_el3() & SCTLR_C_BIT) != 0UL);
/* PGS is needed for validate_pas_mappings so check it now */
if (pgs > GPT_PGS_MAX) {
@ -1213,7 +1168,7 @@ int gpt_init_pas_l1_tables(gpccr_pgs_e pgs, uintptr_t l1_mem_base,
gpt_config.p = gpt_p_lookup[pgs];
/* Make sure L0 tables have been initialized */
if (gpt_config.plat_gpt_l0_base == 0U) {
if (gpt_config.plat_gpt_l0_base == 0UL) {
ERROR("GPT: L0 tables must be initialized first!\n");
return -EPERM;
}
@ -1295,18 +1250,23 @@ int gpt_init_pas_l1_tables(gpccr_pgs_e pgs, uintptr_t l1_mem_base,
* initialization from a previous stage. Granule protection checks must be
* enabled already or this function will return an error.
*
* Parameters
* l1_bitlocks_base Base address of memory for L1 tables bitlocks.
* l1_bitlocks_size Total size of memory available for L1 tables bitlocks.
*
* Return
* Negative Linux error code in the event of a failure, 0 for success.
*/
int gpt_runtime_init(void)
int gpt_runtime_init(uintptr_t l1_bitlocks_base, size_t l1_bitlocks_size)
{
u_register_t reg;
__unused size_t locks_size;
/* Ensure that MMU and Data caches are enabled */
assert((read_sctlr_el3() & SCTLR_C_BIT) != 0U);
assert((read_sctlr_el3() & SCTLR_C_BIT) != 0UL);
/* Ensure GPC are already enabled */
if ((read_gpccr_el3() & GPCCR_GPC_BIT) == 0U) {
if ((read_gpccr_el3() & GPCCR_GPC_BIT) == 0UL) {
ERROR("GPT: Granule protection checks are not enabled!\n");
return -EPERM;
}
@ -1334,17 +1294,43 @@ int gpt_runtime_init(void)
gpt_l1_index_mask = GPT_L1_IDX_MASK(gpt_config.p);
#if (RME_GPT_BITLOCK_BLOCK != 0)
/* Bitlocks at the end of L0 table */
gpt_bitlock_base = (bitlock_t *)(gpt_config.plat_gpt_l0_base +
GPT_L0_TABLE_SIZE(gpt_config.t));
#endif
/*
* Size of GPT bitlocks in bytes for the protected address space
* with RME_GPT_BITLOCK_BLOCK * 512MB per bitlock.
*/
locks_size = GPT_PPS_ACTUAL_SIZE(gpt_config.t) /
(RME_GPT_BITLOCK_BLOCK * SZ_512M * 8U);
/*
* If protected space size is less than the size covered
* by 'bitlock' structure, check for a single bitlock.
*/
if (locks_size < LOCK_SIZE) {
locks_size = LOCK_SIZE;
/* Check bitlocks array size */
} else if (locks_size > l1_bitlocks_size) {
ERROR("GPT: Inadequate GPT bitlocks memory\n");
ERROR(" Expected 0x%lx bytes, got 0x%lx\n",
locks_size, l1_bitlocks_size);
return -ENOMEM;
}
gpt_bitlock = (bitlock_t *)l1_bitlocks_base;
/* Initialise GPT bitlocks */
(void)memset((void *)gpt_bitlock, 0, locks_size);
/* Flush GPT bitlocks to memory */
flush_dcache_range((uintptr_t)gpt_bitlock, locks_size);
#endif /* RME_GPT_BITLOCK_BLOCK */
VERBOSE("GPT: Runtime Configuration\n");
VERBOSE(" PPS/T: 0x%x/%u\n", gpt_config.pps, gpt_config.t);
VERBOSE(" PGS/P: 0x%x/%u\n", gpt_config.pgs, gpt_config.p);
VERBOSE(" L0GPTSZ/S: 0x%x/%u\n", GPT_L0GPTSZ, GPT_S_VAL);
VERBOSE(" L0 base: 0x%"PRIxPTR"\n", gpt_config.plat_gpt_l0_base);
#if (RME_GPT_BITLOCK_BLOCK != 0)
VERBOSE(" Bitlocks: 0x%"PRIxPTR"\n", (uintptr_t)gpt_bitlock_base);
VERBOSE(" Bitlocks: 0x%"PRIxPTR"/0x%lx\n", (uintptr_t)gpt_bitlock,
locks_size);
#endif
return 0;
}
@ -1391,7 +1377,7 @@ static int get_gpi_params(uint64_t base, gpi_info_t *gpi_info)
block_idx = (unsigned int)(base / (RME_GPT_BITLOCK_BLOCK * SZ_512M));
/* Bitlock address and mask */
gpi_info->lock = &gpt_bitlock_base[block_idx / LOCK_BITS];
gpi_info->lock = &gpt_bitlock[block_idx / LOCK_BITS];
gpi_info->mask = 1U << (block_idx & (LOCK_BITS - 1U));
#endif
return 0;

View file

@ -1,19 +1,24 @@
#
# Copyright (c) 2021-2024, Arm Limited. All rights reserved.
# Copyright (c) 2021-2025, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
# RME_GPT_BITLOCK_BLOCK is the number of 512MB blocks
# per bit and the value must be power of 2.
BITLOCK_BLOCK_POWER_2=$(shell echo $$(( ${RME_GPT_BITLOCK_BLOCK} & (${RME_GPT_BITLOCK_BLOCK} - 1) )))
# Process RME_GPT_BITLOCK_BLOCK value
ifeq ($(filter 0 1 2 4 8 16 32 64 128 256 512, ${RME_GPT_BITLOCK_BLOCK}),)
$(error "Invalid value for RME_GPT_BITLOCK_BLOCK: ${RME_GPT_BITLOCK_BLOCK}")
ifneq (${BITLOCK_BLOCK_POWER_2}, 0)
$(error "RME_GPT_BITLOCK_BLOCK must be power of 2. Invalid value ${RME_GPT_BITLOCK_BLOCK}.")
endif
ifeq (${RME_GPT_BITLOCK_BLOCK},0)
$(warning "GPT library uses global spinlock")
$(info "GPT library uses global spinlock")
endif
# Process RME_GPT_MAX_BLOCK value
# Process the maximum size of supported contiguous blocks
# RME_GPT_MAX_BLOCK
ifeq ($(filter 0 2 32 512, ${RME_GPT_MAX_BLOCK}),)
$(error "Invalid value for RME_GPT_MAX_BLOCK: ${RME_GPT_MAX_BLOCK}")
endif

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2024, Arm Limited. All rights reserved.
* Copyright (c) 2022-2025, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -7,9 +7,7 @@
#ifndef GPT_RME_PRIVATE_H
#define GPT_RME_PRIVATE_H
#include <arch.h>
#include <lib/gpt_rme/gpt_rme.h>
#include <lib/spinlock.h>
#include <lib/utils_def.h>
/******************************************************************************/
@ -141,10 +139,6 @@ typedef enum {
PGS_64KB_P = 16U
} gpt_p_val_e;
#define LOCK_SIZE sizeof(((bitlock_t *)NULL)->lock)
#define LOCK_TYPE typeof(((bitlock_t *)NULL)->lock)
#define LOCK_BITS (LOCK_SIZE * 8U)
/*
* Internal structure to retrieve the values from get_gpi_params();
*/

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2023, Arm Limited. All rights reserved.
* Copyright (c) 2020-2025, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -18,7 +18,8 @@ struct gicv3_config_t gicv3_config;
struct hw_topology_t soc_topology;
struct uart_serial_config_t uart_serial_config;
struct cpu_timer_t cpu_timer;
struct ns_dram_layout dram_layout;
struct dram_layout_t dram_layout;
struct pci_props_t pci_props;
/*
* Each NS DRAM bank entry is 'reg' node property which is
@ -27,6 +28,7 @@ struct ns_dram_layout dram_layout;
#define DRAM_ENTRY_SIZE (4UL * sizeof(uint32_t))
CASSERT(ARM_DRAM_NUM_BANKS == 2UL, ARM_DRAM_NUM_BANKS_mismatch);
CASSERT(ARM_PCI_NUM_REGIONS == 2UL, ARM_PCI_NUM_REGIONS_mismatch);
#define ILLEGAL_ADDR ULL(~0)
@ -352,8 +354,98 @@ int fconf_populate_dram_layout(uintptr_t config)
return 0;
}
/*
* Each PCIe memory region entry is 'ranges' node property which is
* an arbitrary number of (child-bus-address, parent-bus-address, length)
* triplets. E.g. with
* #address-cells = <3>
* #size-cells = <2>
* parent's #address-cells = <2>
* each entry occupies 7 32-bit words.
*/
int fconf_populate_pci_props(uintptr_t config)
{
int node, parent, len, err;
int parent_ac, ac, sc, entry_len;
const uint32_t *reg, *ranges;
/* Necessary to work with libfdt APIs */
const void *hw_config_dtb = (const void *)config;
/* Find 'pci' node */
node = fdt_node_offset_by_prop_value(hw_config_dtb, -1, "device_type",
"pci", sizeof("pci"));
if (node < 0) {
WARN("FCONF: Unable to locate 'pci' node\n");
pci_props.ecam_base = 0UL;
pci_props.size = 0UL;
pci_props.num_ncoh_regions = 0UL;
/* Don't return error code if 'pci' node not found */
return 0;
}
reg = fdt_getprop(hw_config_dtb, node, "reg", &len);
if (reg == NULL) {
ERROR("FCONF failed to read 'reg' property\n");
return len;
}
err = fdt_get_reg_props_by_index(hw_config_dtb, node, 0,
(uintptr_t *)&pci_props.ecam_base,
(size_t *)&pci_props.size);
if (err < 0) {
ERROR("FCONF: Failed to read 'reg' property of 'pci' node\n");
return err;
}
parent = fdt_parent_offset(hw_config_dtb, node);
if (parent < 0) {
return -FDT_ERR_BADOFFSET;
}
parent_ac = fdt_address_cells(hw_config_dtb, parent);
ac = fdt_address_cells(hw_config_dtb, node);
sc = fdt_size_cells(hw_config_dtb, node);
entry_len = parent_ac + ac + sc;
ranges = fdt_getprop(hw_config_dtb, node, "ranges", &len);
if (ranges == NULL) {
ERROR("FCONF failed to read 'ranges' property\n");
return len;
}
/* 'ranges' length in 32-bit words */
len /= sizeof(uint32_t);
if ((len % entry_len) != 0) {
return -FDT_ERR_BADVALUE;
}
pci_props.num_ncoh_regions = (uint64_t)(len / entry_len);
if (pci_props.num_ncoh_regions > ARM_PCI_NUM_REGIONS) {
WARN("FCONF: 'ranges' reports more memory regions than supported\n");
pci_props.num_ncoh_regions = ARM_PCI_NUM_REGIONS;
}
for (unsigned int i = 0U; i < (unsigned int)pci_props.num_ncoh_regions; i++) {
unsigned int cell = i * entry_len + ac;
/* Read CPU address (parent-bus-address) space */
pci_props.ncoh_regions[i].base =
fdt_read_prop_cells(&ranges[cell], ac);
/* Read CPU address size */
pci_props.ncoh_regions[i].size =
fdt_read_prop_cells(&ranges[cell + parent_ac], sc);
}
return 0;
}
FCONF_REGISTER_POPULATOR(HW_CONFIG, gicv3_config, fconf_populate_gicv3_config);
FCONF_REGISTER_POPULATOR(HW_CONFIG, topology, fconf_populate_topology);
FCONF_REGISTER_POPULATOR(HW_CONFIG, uart_config, fconf_populate_uart_config);
FCONF_REGISTER_POPULATOR(HW_CONFIG, cpu_timer, fconf_populate_cpu_timer);
FCONF_REGISTER_POPULATOR(HW_CONFIG, dram_layout, fconf_populate_dram_layout);
FCONF_REGISTER_POPULATOR(HW_CONFIG, pci_props, fconf_populate_pci_props);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2024, Arm Limited. All rights reserved.
* Copyright (c) 2019-2025, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -7,6 +7,10 @@
#include <common/tbbr/tbbr_img_def.h>
#include <platform_def.h>
/* DTB load addresses */
#define TB_SOC_FW_ADDR (ARM_BL_RAM_BASE + 0x300)
#define TOS_FW_ADDR (ARM_BL_RAM_BASE + 0x500)
/dts-v1/;
/ {
@ -14,7 +18,7 @@
compatible = "fconf,dyn_cfg-dtb_registry";
tb_fw-config {
load-address = <0x0 0x4001300>;
load-address = <0x0 TB_SOC_FW_ADDR>;
max-size = <0x1800>;
id = <TB_FW_CONFIG_ID>;
};
@ -33,7 +37,7 @@
* is loaded at base of DRAM.
*/
soc_fw-config {
load-address = <0x0 0x04001300>;
load-address = <0x0 TB_SOC_FW_ADDR>;
max-size = <0x200>;
id = <SOC_FW_CONFIG_ID>;
};
@ -41,8 +45,7 @@
/* If required, SPD should enable loading of trusted OS fw config */
#if defined(SPD_tspd) || defined(SPD_spmd)
tos_fw-config {
load-address = <0x0 0x04001500>;
load-address = <0x0 TOS_FW_ADDR>;
#if ENABLE_RME
secondary-load-address = <0x0 0x7e00000>;
#endif /* ENABLE_RME */
@ -50,7 +53,6 @@
id = <TOS_FW_CONFIG_ID>;
};
#endif
nt_fw-config {
load-address = <0x0 0x80000000>;
max-size = <0x200>;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -30,21 +30,25 @@ static pas_region_t pas_regions[] = {
ARM_PAS_SECURE,
ARM_PAS_REALM,
ARM_PAS_EL3_DRAM,
#ifdef ARM_PAS_GPTS
ARM_PAS_GPTS,
ARM_PAS_KERNEL_1
#endif
ARM_PAS_KERNEL_1,
ARM_PAS_PCI_MEM_1,
ARM_PAS_PCI_MEM_2
};
static const arm_gpt_info_t arm_gpt_info = {
.pas_region_base = pas_regions,
.pas_region_count = (unsigned int)ARRAY_SIZE(pas_regions),
.l0_base = (uintptr_t)ARM_L0_GPT_BASE,
.l1_base = (uintptr_t)ARM_L1_GPT_BASE,
.l0_size = (size_t)ARM_L0_GPT_SIZE,
.l1_size = (size_t)ARM_L1_GPT_SIZE,
.pps = GPCCR_PPS_64GB,
.l0_base = ARM_L0_GPT_BASE,
.l1_base = ARM_L1_GPT_BASE,
.l0_size = ARM_L0_GPT_SIZE,
.l1_size = ARM_L1_GPT_SIZE,
.pps = GPCCR_PPS_1TB,
.pgs = GPCCR_PGS_4K
};
#endif
#endif /* ENABLE_RME */
void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3)
{

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -34,12 +34,11 @@
#define FVP_GICV2 1
#define FVP_GICV3 2
/* Defines for RMM Console*/
/* Defines for RMM Console */
#define FVP_RMM_CONSOLE_BASE UL(0x1c0c0000)
#define FVP_RMM_CONSOLE_BAUD UL(115200)
#define FVP_RMM_CONSOLE_CLK_IN_HZ UL(14745600)
#define FVP_RMM_CONSOLE_NAME "pl011"
#define FVP_RMM_CONSOLE_COUNT UL(1)
/*******************************************************************************
@ -591,11 +590,78 @@ static uint64_t checksum_calc(uint64_t *buffer, size_t size)
return sum;
}
/*
* Boot Manifest structure illustration, with two DRAM banks,
* a single console and one device memory with two PCIe device
* non-coherent address ranges.
*
* +--------------------------------------------------+
* | offset | field | comment |
* +--------+--------------------+--------------------+
* | 0 | version | 0x00000004 |
* +--------+--------------------+--------------------+
* | 4 | padding | 0x00000000 |
* +--------+--------------------+--------------------+
* | 8 | plat_data | NULL |
* +--------+--------------------+--------------------+
* | 16 | num_banks | |
* +--------+--------------------+ |
* | 24 | banks | plat_dram +--+
* +--------+--------------------+ | |
* | 32 | checksum | | |
* +--------+--------------------+--------------------+ |
* | 40 | num_consoles | | |
* +--------+--------------------+ | |
* | 48 | consoles | plat_console +--|--+
* +--------+--------------------+ | | |
* | 56 | checksum | | | |
* +--------+--------------------+--------------------+ | |
* | 64 | num_banks | | | |
* +--------+--------------------+ | | |
* | 72 | banks | plat_ncoh_region +--|--|--+
* +--------+--------------------+ | | | |
* | 80 | checksum | | | | |
* +--------+--------------------+--------------------+ | | |
* | 88 | num_banks | | | | |
* +--------+--------------------+ | | | |
* | 96 | banks | plat_coh_region | | | |
* +--------+--------------------+ | | | |
* | 104 | checksum | | | | |
* +--------+--------------------+--------------------+<-+ | |
* | 112 | base 0 | | | |
* +--------+--------------------+ mem_bank[0] | | |
* | 120 | size 0 | | | |
* +--------+--------------------+--------------------+ | |
* | 128 | base 1 | | | |
* +--------+--------------------+ mem_bank[1] | | |
* | 136 | size 1 | | | |
* +--------+--------------------+--------------------+<----+ |
* | 144 | base | | |
* +--------+--------------------+ | |
* | 152 | map_pages | | |
* +--------+--------------------+ | |
* | 160 | name | | |
* +--------+--------------------+ consoles[0] | |
* | 168 | clk_in_hz | | |
* +--------+--------------------+ | |
* | 176 | baud_rate | | |
* +--------+--------------------+ | |
* | 184 | flags | | |
* +--------+--------------------+--------------------+<-------+
* | 192 | base 0 | |
* +--------+--------------------+ ncoh_region[0] |
* | 200 | size 0 | |
* +--------+--------------------+--------------------+
* | 208 | base 1 | |
* +--------+--------------------+ ncoh_region[1] |
* | 216 | size 1 | |
* +--------+--------------------+--------------------+
*/
int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
{
uint64_t checksum, num_banks, num_consoles;
struct ns_dram_bank *bank_ptr;
uint64_t num_ncoh_regions, num_coh_regions;
struct memory_bank *bank_ptr, *ncoh_region_ptr;
struct console_info *console_ptr;
assert(manifest != NULL);
@ -607,71 +673,45 @@ int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
/* Set number of consoles */
num_consoles = FVP_RMM_CONSOLE_COUNT;
/* Set number of device non-coherent address ranges based on DT */
num_ncoh_regions = FCONF_GET_PROPERTY(hw_config, pci_props, num_ncoh_regions);
manifest->version = RMMD_MANIFEST_VERSION;
manifest->padding = 0U; /* RES0 */
manifest->plat_data = (uintptr_t)NULL;
manifest->plat_data = 0UL;
manifest->plat_dram.num_banks = num_banks;
manifest->plat_console.num_consoles = num_consoles;
manifest->plat_ncoh_region.num_banks = num_ncoh_regions;
/*
* Boot Manifest structure illustration, with two dram banks and
* a single console.
*
* +----------------------------------------+
* | offset | field | comment |
* +--------+----------------+--------------+
* | 0 | version | 0x00000003 |
* +--------+----------------+--------------+
* | 4 | padding | 0x00000000 |
* +--------+----------------+--------------+
* | 8 | plat_data | NULL |
* +--------+----------------+--------------+
* | 16 | num_banks | |
* +--------+----------------+ |
* | 24 | banks | plat_dram |
* +--------+----------------+ |
* | 32 | checksum | |
* +--------+----------------+--------------+
* | 40 | num_consoles | |
* +--------+----------------+ |
* | 48 | consoles | plat_console |
* +--------+----------------+ |
* | 56 | checksum | |
* +--------+----------------+--------------+
* | 64 | base 0 | |
* +--------+----------------+ bank[0] |
* | 72 | size 0 | |
* +--------+----------------+--------------+
* | 80 | base 1 | |
* +--------+----------------+ bank[1] |
* | 88 | size 1 | |
* +--------+----------------+--------------+
* | 96 | base | |
* +--------+----------------+ |
* | 104 | map_pages | |
* +--------+----------------+ |
* | 112 | name | |
* +--------+----------------+ consoles[0] |
* | 120 | clk_in_hz | |
* +--------+----------------+ |
* | 128 | baud_rate | |
* +--------+----------------+ |
* | 136 | flags | |
* +--------+----------------+--------------+
*/
/* FVP does not support device coherent address ranges */
num_coh_regions = 0UL;
manifest->plat_coh_region.num_banks = num_coh_regions;
manifest->plat_coh_region.banks = NULL;
manifest->plat_coh_region.checksum = 0UL;
bank_ptr = (struct ns_dram_bank *)
(((uintptr_t)manifest) + sizeof(*manifest));
bank_ptr = (struct memory_bank *)
(((uintptr_t)manifest) + sizeof(struct rmm_manifest));
console_ptr = (struct console_info *)
((uintptr_t)bank_ptr + (num_banks * sizeof(*bank_ptr)));
((uintptr_t)bank_ptr + (num_banks *
sizeof(struct memory_bank)));
ncoh_region_ptr = (struct memory_bank *)
((uintptr_t)console_ptr + (num_consoles *
sizeof(struct console_info)));
manifest->plat_dram.banks = bank_ptr;
manifest->plat_console.consoles = console_ptr;
manifest->plat_ncoh_region.banks = ncoh_region_ptr;
/* Ensure the manifest is not larger than the shared buffer */
assert((sizeof(struct rmm_manifest) +
(sizeof(struct console_info) * manifest->plat_console.num_consoles) +
(sizeof(struct ns_dram_bank) * manifest->plat_dram.num_banks)) <= ARM_EL3_RMM_SHARED_SIZE);
(sizeof(struct memory_bank) *
manifest->plat_dram.num_banks) +
(sizeof(struct console_info) *
manifest->plat_console.num_consoles) +
(sizeof(struct memory_bank) *
manifest->plat_ncoh_region.num_banks) +
(sizeof(struct memory_bank) *
manifest->plat_coh_region.num_banks))
<= ARM_EL3_RMM_SHARED_SIZE);
/* Calculate checksum of plat_dram structure */
checksum = num_banks + (uint64_t)bank_ptr;
@ -683,31 +723,56 @@ int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
}
/* Update checksum */
checksum += checksum_calc((uint64_t *)bank_ptr, sizeof(struct ns_dram_bank) * num_banks);
checksum += checksum_calc((uint64_t *)bank_ptr, sizeof(struct memory_bank) * num_banks);
/* Checksum must be 0 */
manifest->plat_dram.checksum = ~checksum + 1UL;
/* Calculate the checksum of the plat_consoles structure */
/* Calculate the checksum of plat_consoles structure */
checksum = num_consoles + (uint64_t)console_ptr;
/* Zero out the console info struct */
(void)memset((void *)console_ptr, '\0', sizeof(struct console_info) * num_consoles);
(void)memset((void *)console_ptr, '\0',
sizeof(struct console_info) * num_consoles);
console_ptr[0].base = FVP_RMM_CONSOLE_BASE;
console_ptr[0].map_pages = 1UL;
console_ptr[0].clk_in_hz = FVP_RMM_CONSOLE_CLK_IN_HZ;
console_ptr[0].baud_rate = FVP_RMM_CONSOLE_BAUD;
(void)strlcpy(console_ptr[0].name, FVP_RMM_CONSOLE_NAME, RMM_CONSOLE_MAX_NAME_LEN - 1UL);
(void)strlcpy(console_ptr[0].name, FVP_RMM_CONSOLE_NAME,
RMM_CONSOLE_MAX_NAME_LEN - 1UL);
/* Update checksum */
checksum += checksum_calc((uint64_t *)console_ptr,
sizeof(struct console_info) * num_consoles);
/* Checksum must be 0 */
manifest->plat_console.checksum = ~checksum + 1UL;
/*
* Calculate the checksum of device non-coherent address ranges
* info structure
*/
checksum = num_ncoh_regions + (uint64_t)ncoh_region_ptr;
/* Zero out the PCIe region info struct */
(void)memset((void *)ncoh_region_ptr, 0,
sizeof(struct memory_bank) * num_ncoh_regions);
for (unsigned long i = 0UL; i < num_ncoh_regions; i++) {
ncoh_region_ptr[i].base =
FCONF_GET_PROPERTY(hw_config, pci_props, ncoh_regions[i].base);
ncoh_region_ptr[i].size =
FCONF_GET_PROPERTY(hw_config, pci_props, ncoh_regions[i].size);
}
/* Update checksum */
checksum += checksum_calc((uint64_t *)ncoh_region_ptr,
sizeof(struct memory_bank) * num_ncoh_regions);
/* Checksum must be 0 */
manifest->plat_ncoh_region.checksum = ~checksum + 1UL;
return 0;
}
#endif /* ENABLE_RME */

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2023, Arm Limited. All rights reserved.
* Copyright (c) 2020-2025, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -18,6 +18,7 @@
#define hw_config__uart_serial_config_getter(prop) uart_serial_config.prop
#define hw_config__cpu_timer_getter(prop) cpu_timer.prop
#define hw_config__dram_layout_getter(prop) dram_layout.prop
#define hw_config__pci_props_getter(prop) pci_props.prop
struct gicv3_config_t {
uint64_t gicd_base;
@ -40,9 +41,16 @@ struct cpu_timer_t {
uint32_t clock_freq;
};
struct ns_dram_layout {
struct dram_layout_t {
uint64_t num_banks;
struct ns_dram_bank dram_bank[ARM_DRAM_NUM_BANKS];
struct memory_bank dram_bank[ARM_DRAM_NUM_BANKS];
};
struct pci_props_t {
uint64_t ecam_base;
uint64_t size;
uint64_t num_ncoh_regions;
struct memory_bank ncoh_regions[ARM_PCI_NUM_REGIONS];
};
int fconf_populate_gicv3_config(uintptr_t config);
@ -50,11 +58,13 @@ int fconf_populate_topology(uintptr_t config);
int fconf_populate_uart_config(uintptr_t config);
int fconf_populate_cpu_timer(uintptr_t config);
int fconf_populate_dram_layout(uintptr_t config);
int fconf_populate_pci_props(uintptr_t config);
extern struct gicv3_config_t gicv3_config;
extern struct hw_topology_t soc_topology;
extern struct uart_serial_config_t uart_serial_config;
extern struct cpu_timer_t cpu_timer;
extern struct ns_dram_layout dram_layout;
extern struct dram_layout_t dram_layout;
extern struct pci_props_t pci_props;
#endif /* FCONF_HW_CONFIG_GETTER_H */

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2024, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2021-2025, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -17,34 +17,37 @@
* The PA space is initially mapped in the GPT as follows:
*
* ============================================================================
* Base Addr| Size |L? GPT|PAS |Content |Comment
* Base Addr | Size |L? GPT|PAS |Content |Comment
* ============================================================================
* 0GB | 1GB |L0 GPT|ANY |TBROM (EL3 code) |Fixed mapping
* | | | |TSRAM (EL3 data) |
* 00000000 | | | |IO (incl.UARTs & GIC) |
* 0GB | 1GB |L0 GPT|ANY |TBROM (EL3 code) |Fixed mapping
* | | | |TSRAM (EL3 data) |
* 00000000 | 40000000 | | |IO (incl.UARTs & GIC) |
* ----------------------------------------------------------------------------
* 1GB | 1GB |L0 GPT|ANY |IO |Fixed mapping
* 40000000 | | | | |
* 1GB | 1GB |L0 GPT|ANY |IO |Fixed mapping
* 40000000 | 40000000 | | | |
* ----------------------------------------------------------------------------
* 2GB |2GB-64MB |L1 GPT|NS |DRAM (NS Kernel) |Use T.Descrip
* 80000000 | | | | |
* 1GB+256MB | 256MB |L1 GPT|NS |PCI Memory Region 1 |Use T.Descrip
* 50000000 | 10000000 | | | |
* ----------------------------------------------------------------------------
* 4GB-64MB |64MB-32MB-4MB|L1 GPT|SECURE|DRAM TZC |Use T.Descrip
* FC000000 | | | | |
* 2GB | 2GB-64MB |L1 GPT|NS |DRAM (NS Kernel) |Use T.Descrip
* 80000000 | 7C000000 | | | |
* ----------------------------------------------------------------------------
* 4GB-32MB | | | | |
* -3MB-1MB |32MB |L1 GPT|REALM |RMM |Use T.Descrip
* FDC00000 | | | | |
* 4GB-64MB |64MB-32MB-4MB|L1 GPT|SECURE|DRAM TZC |Use T.Descrip
* FC000000 | 1C00000 | | | |
* ----------------------------------------------------------------------------
* 4GB-3MB | | | | |
* -1MB |3MB |L1 GPT|ROOT |EL3 DRAM data |Use T.Descrip
* FFC00000 | | | | |
* 4GB-32MB | | | | |
* -3MB-1MB | 32MB |L1 GPT|REALM |RMM |Use T.Descrip
* FDC00000 | 2000000 | | | |
* ----------------------------------------------------------------------------
* 4GB-1MB |1MB |L1 GPT|ROOT |DRAM (L1 GPTs, SCP TZC) |Fixed mapping
* FFF00000 | | | | |
* 4GB-3MB | | | | |
* -1MB | 4MB |L1 GPT|ROOT |EL3 DRAM data, L1 GPTs, |Use T.Descrip
* FFC00000 | 400000 | | |SCP TZC |
* ----------------------------------------------------------------------------
* 34GB |2GB |L1 GPT|NS |DRAM (NS Kernel) |Use T.Descrip
* 880000000| | | | |
* 34GB | 2GB |L1 GPT|NS |DRAM (NS Kernel) |Use T.Descrip
* 880000000 | 80000000 | | | |
* ----------------------------------------------------------------------------
* 256GB | 3GB |L1 GPT|NS |PCI Memory Region 2 |Use T.Descrip
* 4000000000| C0000000 | | |(first 3GB only) |
* ============================================================================
*
* - 4KB of L0 GPT reside in TSRAM, on top of the CONFIG section.
@ -61,7 +64,7 @@
/* Device memory 0 to 2GB */
#define ARM_PAS_1_BASE (U(0))
#define ARM_PAS_1_SIZE ((ULL(1) << 31)) /* 2GB */
#define ARM_PAS_1_SIZE (SZ_2G) /* 2GB */
/* NS memory 2GB to (end - 64MB) */
#define ARM_PAS_2_BASE (ARM_PAS_1_BASE + ARM_PAS_1_SIZE)
@ -77,7 +80,7 @@
/* NS memory 2GB */
#define ARM_PAS_4_BASE ARM_DRAM2_BASE
#define ARM_PAS_4_SIZE ((ULL(1) << 31)) /* 2GB */
#define ARM_PAS_4_SIZE (SZ_2G) /* 2GB */
#define ARM_PAS_GPI_ANY MAP_GPT_REGION(ARM_PAS_1_BASE, \
ARM_PAS_1_SIZE, \
@ -94,6 +97,14 @@
#define ARM_PAS_KERNEL_1 GPT_MAP_REGION_GRANULE(ARM_PAS_4_BASE, \
ARM_PAS_4_SIZE, \
GPT_GPI_NS)
#define ARM_PAS_PCI_MEM_1 GPT_MAP_REGION_GRANULE(PLAT_ARM_PCI_MEM_1_BASE, \
PLAT_ARM_PCI_MEM_1_SIZE, \
GPT_GPI_NS)
#define ARM_PAS_PCI_MEM_2 GPT_MAP_REGION_GRANULE(PLAT_ARM_PCI_MEM_2_BASE, \
PLAT_ARM_PCI_MEM_2_SIZE, \
GPT_GPI_NS)
/*
* REALM and Shared area share the same PAS, so consider them a single
* PAS region to configure in GPT.
@ -102,7 +113,8 @@
(ARM_PAS_SHARED_SIZE + \
ARM_REALM_SIZE), \
GPT_GPI_REALM)
/* Check if the EL3 TZC DRAM is contiguous with L1 GPT region. */
#if (ARM_L1_GPT_BASE != (ARM_EL3_TZC_DRAM1_BASE + ARM_EL3_TZC_DRAM1_SIZE))
#define ARM_PAS_EL3_DRAM GPT_MAP_REGION_GRANULE(ARM_EL3_TZC_DRAM1_BASE, \
ARM_EL3_TZC_DRAM1_SIZE, \
GPT_GPI_ROOT)
@ -110,6 +122,13 @@
#define ARM_PAS_GPTS GPT_MAP_REGION_GRANULE(ARM_L1_GPT_BASE, \
ARM_L1_GPT_SIZE, \
GPT_GPI_ROOT)
#else
/* Contiguous ROOT region */
#define ARM_PAS_EL3_DRAM GPT_MAP_REGION_GRANULE(ARM_EL3_TZC_DRAM1_BASE, \
ARM_EL3_TZC_DRAM1_SIZE + \
ARM_L1_GPT_SIZE, \
GPT_GPI_ROOT)
#endif
/* GPT Configuration options */
#define PLATFORM_L0GPTSZ GPCCR_L0GPTSZ_30BITS

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2024, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2014-2025, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -54,7 +54,10 @@
#if ENABLE_RME
#define PLAT_ARM_RMM_BASE (RMM_BASE)
#define PLAT_ARM_RMM_SIZE (RMM_LIMIT - RMM_BASE)
#endif
/* Protected physical address size */
#define PLAT_ARM_PPS (SZ_1T)
#endif /* ENABLE_RME */
/*
* Max size of SPMC is 2MB for fvp. With SPMD enabled this value corresponds to
@ -65,7 +68,7 @@
#define PLAT_ARM_SPMC_SIZE UL(0x200000) /* 2 MB */
#endif
/* virtual address used by dynamic mem_protect for chunk_base */
/* Virtual address used by dynamic mem_protect for chunk_base */
#define PLAT_ARM_MEM_PROTEC_VA_FRAME UL(0xc0000000)
/* No SCP in FVP */
@ -399,11 +402,22 @@ FVP_TRUSTED_SRAM_SIZE == 512
#define PLAT_ARM_CLUSTER_TO_CCN_ID_MAP 1, 5, 7, 11
/* System timer related constants */
#define PLAT_ARM_NSTIMER_FRAME_ID U(1)
#define PLAT_ARM_NSTIMER_FRAME_ID U(1)
/* Mailbox base address */
#define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE
/* PCIe memory region 1 (Base Platform RevC only) */
#define PLAT_ARM_PCI_MEM_1_BASE (ULL(0x50000000))
#define PLAT_ARM_PCI_MEM_1_SIZE (SZ_256M) /* 256MB */
/*
* PCIe memory region 2 (Base Platform RevC only)
* The full size of the second PCI memory region is 256GB
* but for now we only allocate the L1 GPTs for the first 3GB.
*/
#define PLAT_ARM_PCI_MEM_2_BASE (ULL(0x4000000000))
#define PLAT_ARM_PCI_MEM_2_SIZE (3 * SZ_1G) /* 3GB */
/* TrustZone controller related constants
*

View file

@ -29,9 +29,13 @@ FVP_DT_PREFIX := fvp-base-gicv3-psci-dynamiq
endif
# fdts is wrong otherwise
# Size (in kilobytes) of the Trusted SRAM region to utilize when building for
# the FVP platform. This option defaults to 256.
# Size (in kilobytes) of the Trusted SRAM region to utilize when building for
# the FVP platform.
ifeq (${ENABLE_RME},1)
FVP_TRUSTED_SRAM_SIZE := 384
else
FVP_TRUSTED_SRAM_SIZE := 256
endif
# Macro to enable helpers for running SPM tests. Disabled by default.
PLAT_TEST_SPM := 0

View file

@ -507,8 +507,6 @@
#define ARM_L0_GPT_BASE NRD_CSS_SHARED_SRAM_SIZE - \
ARM_L0_GPT_SIZE
#define ARM_L0_GPT_LIMIT (ARM_L0_GPT_BASE + ARM_L0_GPT_SIZE)
/*******************************************************************************
* Arm shared RAM specifics
******************************************************************************/

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2024-2025, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -48,4 +48,7 @@
*/
#define PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE UL(0x1000)
/* Protected physical address size */
#define PLAT_ARM_PPS (256 * SZ_1T)
#endif /* PLATFORM_DEF_H */

View file

@ -64,7 +64,7 @@ static uint64_t checksum_calc(uint64_t *buffer, size_t size)
int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
{
uint64_t checksum, num_banks, num_consoles;
struct ns_dram_bank *bank_ptr;
struct memory_bank *bank_ptr;
struct console_info *console_ptr;
assert(manifest != NULL);
@ -129,7 +129,7 @@ int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
* +--------+----------------+--------------+
*/
bank_ptr = (struct ns_dram_bank *)
bank_ptr = (struct memory_bank *)
(((uintptr_t)manifest) + sizeof(*manifest));
console_ptr = (struct console_info *)
((uintptr_t)bank_ptr + (num_banks * sizeof(*bank_ptr)));
@ -141,7 +141,7 @@ int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
assert((sizeof(struct rmm_manifest) +
(sizeof(struct console_info) *
manifest->plat_console.num_consoles) +
(sizeof(struct ns_dram_bank) * manifest->plat_dram.num_banks))
(sizeof(struct memory_bank) * manifest->plat_dram.num_banks))
<= ARM_EL3_RMM_SHARED_SIZE);
/* Calculate checksum of plat_dram structure */
@ -156,7 +156,7 @@ int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
/* Update checksum */
checksum += checksum_calc((uint64_t *)bank_ptr,
sizeof(struct ns_dram_bank) * num_banks);
sizeof(struct memory_bank) * num_banks);
/* Checksum must be 0 */
manifest->plat_dram.checksum = ~checksum + 1UL;

View file

@ -34,9 +34,31 @@ struct transfer_list_header *ns_tl __unused;
*/
static entry_point_info_t bl32_image_ep_info;
static entry_point_info_t bl33_image_ep_info;
#if ENABLE_RME
static entry_point_info_t rmm_image_ep_info;
#if (RME_GPT_BITLOCK_BLOCK == 0)
#define BITLOCK_BASE UL(0)
#define BITLOCK_SIZE UL(0)
#else
/*
* Number of bitlock_t entries in bitlocks array for PLAT_ARM_PPS
* with RME_GPT_BITLOCK_BLOCK * 512MB per bitlock.
*/
#if (PLAT_ARM_PPS > (RME_GPT_BITLOCK_BLOCK * SZ_512M * UL(8)))
#define BITLOCKS_NUM (PLAT_ARM_PPS) / \
(RME_GPT_BITLOCK_BLOCK * SZ_512M * UL(8))
#else
#define BITLOCKS_NUM U(1)
#endif
/*
* Bitlocks array
*/
static bitlock_t gpt_bitlock[BITLOCKS_NUM];
#define BITLOCK_BASE (uintptr_t)gpt_bitlock
#define BITLOCK_SIZE sizeof(gpt_bitlock)
#endif /* RME_GPT_BITLOCK_BLOCK */
#endif /* ENABLE_RME */
#if !RESET_TO_BL31
/*
@ -551,7 +573,7 @@ void __init arm_bl31_plat_arch_setup(void)
* stage, so there is no need to provide any PAS here. This function
* sets up pointers to those tables.
*/
if (gpt_runtime_init() < 0) {
if (gpt_runtime_init(BITLOCK_BASE, BITLOCK_SIZE) < 0) {
ERROR("gpt_runtime_init() failed!\n");
panic();
}

View file

@ -46,6 +46,30 @@
MT_DEVICE | MT_RW | EL3_PAS)
#endif
#if ENABLE_RME
#if (RME_GPT_BITLOCK_BLOCK == 0)
#define BITLOCK_BASE UL(0)
#define BITLOCK_SIZE UL(0)
#else
/*
* Number of bitlock_t entries in the gpt_bitlock array for this platform's
* Protected Physical Size. One 8-bit bitlock_t entry covers
* 8 * RME_GPT_BITLOCK_BLOCK * 512MB.
*/
#if (PLAT_QEMU_PPS > (RME_GPT_BITLOCK_BLOCK * SZ_512M * UL(8)))
#define BITLOCKS_NUM (PLAT_QEMU_PPS / \
(RME_GPT_BITLOCK_BLOCK * SZ_512M * UL(8)))
#else
#define BITLOCKS_NUM 1
#endif
static bitlock_t gpt_bitlock[BITLOCKS_NUM];
#define BITLOCK_BASE (uintptr_t)gpt_bitlock
#define BITLOCK_SIZE sizeof(gpt_bitlock)
#endif /* RME_GPT_BITLOCK_BLOCK */
#endif /* ENABLE_RME */
/*
* Placeholder variables for copying the arguments that have been passed to
* BL3-1 from BL2.
@ -202,9 +226,8 @@ static void bl31_plat_gpt_setup(void)
* 256TB of RAM (48-bit PA) would require a 2MB L0 region. At the
* moment we use a 8KB table, which covers 1TB of RAM (40-bit PA).
*/
if (gpt_init_l0_tables(PLATFORM_GPCCR_PPS, PLAT_QEMU_L0_GPT_BASE,
PLAT_QEMU_L0_GPT_SIZE +
PLAT_QEMU_GPT_BITLOCK_SIZE) < 0) {
if (gpt_init_l0_tables(PLAT_QEMU_GPCCR_PPS, PLAT_QEMU_L0_GPT_BASE,
PLAT_QEMU_L0_GPT_SIZE) < 0) {
ERROR("gpt_init_l0_tables() failed!\n");
panic();
}
@ -260,7 +283,7 @@ void bl31_plat_arch_setup(void)
* stage, so there is no need to provide any PAS here. This function
* sets up pointers to those tables.
*/
if (gpt_runtime_init() < 0) {
if (gpt_runtime_init(BITLOCK_BASE, BITLOCK_SIZE) < 0) {
ERROR("gpt_runtime_init() failed!\n");
panic();
}

View file

@ -233,7 +233,7 @@ static uint32_t plat_get_num_memnodes(void)
return 1;
}
static void plat_get_memory_node(int index, struct ns_dram_bank *bank_ptr)
static void plat_get_memory_node(int index, struct memory_bank *bank_ptr)
{
(void) index;
bank_ptr->base = NS_DRAM0_BASE;
@ -245,7 +245,7 @@ static uint32_t plat_get_num_memnodes(void)
return sbsa_platform_num_memnodes();
}
static void plat_get_memory_node(int index, struct ns_dram_bank *bank_ptr)
static void plat_get_memory_node(int index, struct memory_bank *bank_ptr)
{
struct platform_memory_data data = {0, 0, 0};
@ -281,7 +281,7 @@ int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
uint64_t checksum;
size_t num_banks = plat_get_num_memnodes();
size_t num_consoles = 1;
struct ns_dram_bank *bank_ptr;
struct memory_bank *bank_ptr;
struct console_info *console_ptr;
assert(manifest != NULL);
@ -333,7 +333,7 @@ int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
* | 120 | flags | |
* +----------+--------------+--------------+
*/
bank_ptr = (struct ns_dram_bank *)
bank_ptr = (struct memory_bank *)
(((uintptr_t)manifest) + sizeof(*manifest));
console_ptr = (struct console_info *)
@ -345,7 +345,7 @@ int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
/* Ensure the manifest is not larger than the shared buffer */
assert((sizeof(struct rmm_manifest) +
(sizeof(struct console_info) * num_consoles) +
(sizeof(struct ns_dram_bank) * num_banks)) <= RMM_SHARED_SIZE);
(sizeof(struct memory_bank) * num_banks)) <= RMM_SHARED_SIZE);
/* Calculate checksum of plat_dram structure */
checksum = num_banks + (uint64_t)bank_ptr;

View file

@ -342,22 +342,16 @@
* Tables
*/
#define PLAT_QEMU_L0_GPT_BASE (PLAT_QEMU_L1_GPT_BASE - \
(PLAT_QEMU_L0_GPT_SIZE + \
PLAT_QEMU_GPT_BITLOCK_SIZE))
#define PLAT_QEMU_L0_GPT_SIZE (2 * PAGE_SIZE)
/* Two pages so the L0 GPT is naturally aligned. */
#define PLAT_QEMU_GPT_BITLOCK_SIZE (2 * PAGE_SIZE)
PLAT_QEMU_L0_GPT_SIZE)
#define PLAT_QEMU_L0_GPT_SIZE SZ_8K
#define PLAT_QEMU_L1_GPT_BASE (SEC_DRAM_BASE + SEC_DRAM_SIZE - \
PLAT_QEMU_L1_GPT_SIZE)
#define PLAT_QEMU_L1_GPT_END (PLAT_QEMU_L1_GPT_BASE + \
PLAT_QEMU_L1_GPT_SIZE - 1U)
#define PLAT_QEMU_L1_GPT_SIZE UL(0x00100000) /* 1MB */
#define PLAT_QEMU_L1_GPT_SIZE SZ_1M
#define RME_GPT_DRAM_BASE PLAT_QEMU_L0_GPT_BASE
#define RME_GPT_DRAM_SIZE (PLAT_QEMU_L1_GPT_SIZE + \
PLAT_QEMU_L0_GPT_SIZE + \
PLAT_QEMU_GPT_BITLOCK_SIZE)
PLAT_QEMU_L0_GPT_SIZE)
#ifndef __ASSEMBLER__
/* L0 table greater than 4KB must be naturally aligned */
@ -379,8 +373,7 @@ CASSERT((PLAT_QEMU_L0_GPT_BASE & (PLAT_QEMU_L0_GPT_SIZE - 1)) == 0,
#define MAP_GPT_L0_REGION MAP_REGION_FLAT( \
PLAT_QEMU_L0_GPT_BASE, \
PLAT_QEMU_L0_GPT_SIZE + \
PLAT_QEMU_GPT_BITLOCK_SIZE, \
PLAT_QEMU_L0_GPT_SIZE, \
MT_MEMORY | MT_RW | EL3_PAS)
#define MAP_GPT_L1_REGION MAP_REGION_FLAT( \

View file

@ -103,7 +103,8 @@
GPT_GPI_REALM)
/* Cover 1TB with L0GTP */
#define PLATFORM_GPCCR_PPS GPCCR_PPS_1TB
#define PLAT_QEMU_GPCCR_PPS GPCCR_PPS_1TB
#define PLAT_QEMU_PPS SZ_1T
/* GPT Configuration options */
#define PLATFORM_L0GPTSZ GPCCR_L0GPTSZ_30BITS

View file

@ -405,24 +405,8 @@
*/
#define PLAT_QEMU_L0_GPT_SIZE (8 * PAGE_SIZE)
#define PLAT_QEMU_L0_GPT_BASE (PLAT_QEMU_L1_GPT_BASE - \
(PLAT_QEMU_L0_GPT_SIZE + \
PLAT_QEMU_GPT_BITLOCK_SIZE + \
PLAT_QEMU_GPT_ALIGNMENT))
PLAT_QEMU_L0_GPT_SIZE)
#if RME_GPT_BITLOCK_BLOCK
/*
* 4TB / (RME_GPT_BITLOCK_BLOCK * 512M * 8) == 1024
*/
#define PLAT_QEMU_GPT_BITLOCK_SIZE (1 * PAGE_SIZE)
/*
* PLAT_QEMU_L0_GPT_SIZE is 8 pages and PLAT_QEMU_GPT_BITLOCK_SIZE
* is 1 page. As such we need 7 pages to have an 8 page alignment.
*/
#define PLAT_QEMU_GPT_ALIGNMENT (7 * PAGE_SIZE)
#else /* RME_GPT_BITLOCK_BLOCK */
#define PLAT_QEMU_GPT_BITLOCK_SIZE 0
#define PLAT_QEMU_GPT_ALIGNMENT 0
#endif /* RME_GPT_BITLOCK_BLOCK */
/*
* If we have 1TB of RAM and each L1GPT covers 1GB, we need 1024 L1GPTs. With
@ -433,14 +417,10 @@
#define PLAT_QEMU_L1_GPT_SIZE UL(0x08020000)
#define PLAT_QEMU_L1_GPT_BASE (BL_RAM_BASE + BL_RAM_SIZE - \
PLAT_QEMU_L1_GPT_SIZE)
#define PLAT_QEMU_L1_GPT_END (PLAT_QEMU_L1_GPT_BASE + \
PLAT_QEMU_L1_GPT_SIZE - 1U)
#define RME_GPT_DRAM_BASE PLAT_QEMU_L0_GPT_BASE
#define RME_GPT_DRAM_SIZE (PLAT_QEMU_L1_GPT_SIZE + \
PLAT_QEMU_L0_GPT_SIZE + \
PLAT_QEMU_GPT_BITLOCK_SIZE + \
PLAT_QEMU_GPT_ALIGNMENT)
PLAT_QEMU_L0_GPT_SIZE)
#ifndef __ASSEMBLER__
/* L0 table greater than 4KB must be naturally aligned */
@ -462,9 +442,7 @@ CASSERT((PLAT_QEMU_L0_GPT_BASE & (PLAT_QEMU_L0_GPT_SIZE - 1)) == 0,
#define MAP_GPT_L0_REGION MAP_REGION_FLAT( \
PLAT_QEMU_L0_GPT_BASE, \
(PLAT_QEMU_L0_GPT_SIZE + \
PLAT_QEMU_GPT_BITLOCK_SIZE + \
PLAT_QEMU_GPT_ALIGNMENT), \
(PLAT_QEMU_L0_GPT_SIZE), \
MT_MEMORY | MT_RW | EL3_PAS)
#define MAP_GPT_L1_REGION MAP_REGION_FLAT( \

View file

@ -58,7 +58,8 @@
GPT_GPI_REALM)
/* Cover 4TB with L0GTP */
#define PLATFORM_GPCCR_PPS GPCCR_PPS_4TB
#define PLAT_QEMU_GPCCR_PPS GPCCR_PPS_4TB
#define PLAT_QEMU_PPS SZ_4T
/* GPT Configuration options */
#define PLATFORM_L0GPTSZ GPCCR_L0GPTSZ_30BITS