From 665a8fdf3aa372862d62c34d23ffd678798a265c Mon Sep 17 00:00:00 2001 From: AlexeiFedorov Date: Wed, 13 Mar 2024 17:52:37 +0000 Subject: [PATCH 1/9] feat(fvp): define single Root region For FVP model define single Root PAS which includes EL3 DRAM data, L1 GPTs and SCP TZC. This allows to decrease the number of PAS regions passed to GPT library and use GPT mapping with Contiguous descriptor of larger block size. Change-Id: I70f6babaebc14e5e0bce033783ec423c8a26c542 Signed-off-by: AlexeiFedorov --- include/plat/arm/common/arm_def.h | 6 ++-- plat/arm/board/fvp/fvp_bl2_setup.c | 2 ++ plat/arm/board/fvp/include/fvp_pas_def.h | 39 +++++++++++++----------- 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 3ce6a91dd..55b44b185 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -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) @@ -110,6 +109,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 (GPCCR_PPS_64GB, GPCCR_PGS_4K) */ #define ARM_L1_GPT_SIZE UL(0x00100000) /* 1MB */ /* 32MB - ARM_EL3_RMM_SHARED_SIZE */ #define ARM_REALM_SIZE (UL(0x02000000) - \ @@ -150,7 +150,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 + \ @@ -546,7 +546,7 @@ MEASURED_BOOT * configuration memory, 4KB aligned. */ #define ARM_L0_GPT_SIZE (PAGE_SIZE) -#define ARM_L0_GPT_BASE (ARM_FW_CONFIGS_LIMIT) +#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) diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c index 8dcdd62e5..be8a19c35 100644 --- a/plat/arm/board/fvp/fvp_bl2_setup.c +++ b/plat/arm/board/fvp/fvp_bl2_setup.c @@ -30,7 +30,9 @@ static pas_region_t pas_regions[] = { ARM_PAS_SECURE, ARM_PAS_REALM, ARM_PAS_EL3_DRAM, +#ifdef ARM_PAS_GPTS ARM_PAS_GPTS, +#endif ARM_PAS_KERNEL_1 }; diff --git a/plat/arm/board/fvp/include/fvp_pas_def.h b/plat/arm/board/fvp/include/fvp_pas_def.h index 468438724..928c33a3a 100644 --- a/plat/arm/board/fvp/include/fvp_pas_def.h +++ b/plat/arm/board/fvp/include/fvp_pas_def.h @@ -21,30 +21,27 @@ * ============================================================================ * 0GB | 1GB |L0 GPT|ANY |TBROM (EL3 code) |Fixed mapping * | | | |TSRAM (EL3 data) | - * 00000000 | | | |IO (incl.UARTs & GIC) | + * 00000000 | 40000000 | | |IO (incl.UARTs & GIC) | * ---------------------------------------------------------------------------- * 1GB | 1GB |L0 GPT|ANY |IO |Fixed mapping - * 40000000 | | | | | + * 40000000 | 40000000 | | | | * ---------------------------------------------------------------------------- - * 2GB |2GB-64MB |L1 GPT|NS |DRAM (NS Kernel) |Use T.Descrip - * 80000000 | | | | | + * 2GB | 2GB-64MB |L1 GPT|NS |DRAM (NS Kernel) |Use T.Descrip + * 80000000 | 7C000000 | | | | * ---------------------------------------------------------------------------- * 4GB-64MB |64MB-32MB-4MB|L1 GPT|SECURE|DRAM TZC |Use T.Descrip - * FC000000 | | | | | + * FC000000 | 1C00000 | | | | * ---------------------------------------------------------------------------- * 4GB-32MB | | | | | - * -3MB-1MB |32MB |L1 GPT|REALM |RMM |Use T.Descrip - * FDC00000 | | | | | + * -3MB-1MB | 32MB |L1 GPT|REALM |RMM |Use T.Descrip + * FDC00000 | 2000000 | | | | * ---------------------------------------------------------------------------- * 4GB-3MB | | | | | - * -1MB |3MB |L1 GPT|ROOT |EL3 DRAM data |Use T.Descrip - * FFC00000 | | | | | + * -1MB | 4MB |L1 GPT|ROOT |EL3 DRAM data, L1 GPTs, |Use T.Descrip + * FFC00000 | 400000 | | |SCP TZC | * ---------------------------------------------------------------------------- - * 4GB-1MB |1MB |L1 GPT|ROOT |DRAM (L1 GPTs, SCP TZC) |Fixed mapping - * FFF00000 | | | | | - * ---------------------------------------------------------------------------- - * 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 | | | | * ============================================================================ * * - 4KB of L0 GPT reside in TSRAM, on top of the CONFIG section. @@ -61,7 +58,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 +74,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, \ @@ -102,7 +99,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 +108,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 From bef44f60edaa763031bce6144c0267aefbb1f2bf Mon Sep 17 00:00:00 2001 From: AlexeiFedorov Date: Mon, 14 Oct 2024 15:23:34 +0100 Subject: [PATCH 2/9] feat(rmm): add PCIe IO info to Boot manifest - Add PCIe and SMMUv3 related information to DTS for configurations with ENABLE_RME=1. - Add entries for PCIe IO memory regions to Boot manifest - Update RMMD_MANIFEST_VERSION_MINOR from 3 to 4. - Read PCIe related information from DTB and write it to Boot manifest. - Rename structures that used to describe DRAM layout and now describe both DRAM and PCIe IO memory regions: - ns_dram_bank -> memory_bank - ns_dram_info -> memory_info. Change-Id: Ib75d1af86076f724f5c330074e231f1c2ba8e21d Signed-off-by: AlexeiFedorov --- common/fdt_wrappers.c | 2 +- docs/components/rmm-el3-comms-spec.rst | 130 ++++++------ fdts/fvp-base-psci-common.dtsi | 36 +++- include/common/fdt_wrappers.h | 2 + include/plat/arm/common/arm_def.h | 3 + include/services/rmm_core_manifest.h | 45 +++-- .../board/fvp/fconf/fconf_hw_config_getter.c | 96 ++++++++- plat/arm/board/fvp/fvp_common.c | 191 ++++++++++++------ .../fvp/include/fconf_hw_config_getter.h | 18 +- .../neoverse_rd/platform/rdv3/rdv3_common.c | 8 +- 10 files changed, 375 insertions(+), 156 deletions(-) diff --git a/common/fdt_wrappers.c b/common/fdt_wrappers.c index b213ffa47..863835154 100644 --- a/common/fdt_wrappers.c +++ b/common/fdt_wrappers.c @@ -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]); diff --git a/docs/components/rmm-el3-comms-spec.rst b/docs/components/rmm-el3-comms-spec.rst index 79e1d2cdf..f1ca031f7 100644 --- a/docs/components/rmm-el3-comms-spec.rst +++ b/docs/components/rmm-el3-comms-spec.rst @@ -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 | diff --git a/fdts/fvp-base-psci-common.dtsi b/fdts/fvp-base-psci-common.dtsi index 583bba70e..ff3a6ba27 100644 --- a/fdts/fvp-base-psci-common.dtsi +++ b/fdts/fvp-base-psci-common.dtsi @@ -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 @@ -249,4 +249,38 @@ <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>, + <0x2000000 0x40 0x00000000 0x40 0x00000000 0x40 0x00000000>; + 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 = , + , + , + ; + interrupt-names = "eventq", "gerror", "priq", "cmdq-sync"; + dma-coherent; + #iommu-cells = <1>; + msi-parent = <&its 0x10000>; + }; +#endif /* ENABLE_RME */ }; diff --git a/include/common/fdt_wrappers.h b/include/common/fdt_wrappers.h index de08f1db5..7f6af59c8 100644 --- a/include/common/fdt_wrappers.h +++ b/include/common/fdt_wrappers.h @@ -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; diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 55b44b185..073c157e5 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -246,6 +246,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 diff --git a/include/services/rmm_core_manifest.h b/include/services/rmm_core_manifest.h index 6b57267d8..2d6e71f09 100644 --- a/include/services/rmm_core_manifest.h +++ b/include/services/rmm_core_manifest.h @@ -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 #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 */ diff --git a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c index 43dc17bc8..662b8a464 100644 --- a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c +++ b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c @@ -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); diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index bdc2cacfb..19a340f2a 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -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 */ diff --git a/plat/arm/board/fvp/include/fconf_hw_config_getter.h b/plat/arm/board/fvp/include/fconf_hw_config_getter.h index b7a124726..351f13d82 100644 --- a/plat/arm/board/fvp/include/fconf_hw_config_getter.h +++ b/plat/arm/board/fvp/include/fconf_hw_config_getter.h @@ -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 */ diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c index 3ef9681e1..2402c0556 100644 --- a/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c +++ b/plat/arm/board/neoverse_rd/platform/rdv3/rdv3_common.c @@ -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; From 2e55a3d74d588780e04f1632c1b9d7ad33fb5f4f Mon Sep 17 00:00:00 2001 From: AlexeiFedorov Date: Tue, 21 Jan 2025 12:01:10 +0000 Subject: [PATCH 3/9] feat(fvp): change size of PCIe memory region 2 Change size of PCIe memory region 2 from 256GB to 3GB to fit in 1TB of GPT PPS. Change-Id: Ic769bb784dd17d390b54ccef53b7788334373cb4 Signed-off-by: AlexeiFedorov --- fdts/fvp-base-psci-common.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fdts/fvp-base-psci-common.dtsi b/fdts/fvp-base-psci-common.dtsi index ff3a6ba27..95ea2a114 100644 --- a/fdts/fvp-base-psci-common.dtsi +++ b/fdts/fvp-base-psci-common.dtsi @@ -259,7 +259,8 @@ device_type = "pci"; reg = <0x0 0x40000000 0x0 0x10000000>; ranges = <0x2000000 0x0 0x50000000 0x0 0x50000000 0x0 0x10000000>, - <0x2000000 0x40 0x00000000 0x40 0x00000000 0x40 0x00000000>; + /* 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>, From 7a4a07078b3d15648c1cbbd9f309b0c11da56165 Mon Sep 17 00:00:00 2001 From: AlexeiFedorov Date: Wed, 22 Jan 2025 15:12:08 +0000 Subject: [PATCH 4/9] feat(fvp): allocate L0 GPT at the top of SRAM This patch allocates level 0 GPT at the top of SRAM for FVP. This helps to meet L0 GPT alignment requirements and prevent the occurrence of possible unused gaps in SRAM. Load addresses for FVP TB_FW, SOC_FW and TOS_FW DTBs are defined in fvp_fw_config.dts via ARM_BL_RAM_BASE macro. Change-Id: Iaa52e302373779d9fdbaf4e1ba40c10aa8d1f8bd Signed-off-by: AlexeiFedorov --- include/plat/arm/common/arm_def.h | 33 +++++++++---------- plat/arm/board/fvp/fdts/fvp_fw_config.dts | 14 ++++---- .../common/include/nrd3/nrd_plat_arm_def3.h | 2 -- 3 files changed, 24 insertions(+), 25 deletions(-) diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 073c157e5..e94b32a6a 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -62,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(0x00001000) /* 4 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 @@ -355,7 +366,6 @@ MEASURED_BOOT ARM_EL3_RMM_SHARED_BASE, \ ARM_EL3_RMM_SHARED_SIZE, \ MT_MEMORY | MT_RW | MT_REALM) - #endif /* ENABLE_RME */ /* @@ -543,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 @@ -570,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 - \ diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts index 5d587311a..a11c1dea5 100644 --- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts @@ -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 #include +/* 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 = ; }; @@ -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 = ; }; @@ -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 = ; }; #endif - nt_fw-config { load-address = <0x0 0x80000000>; max-size = <0x200>; diff --git a/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_plat_arm_def3.h b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_plat_arm_def3.h index 7fa2b775d..49363449d 100644 --- a/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_plat_arm_def3.h +++ b/plat/arm/board/neoverse_rd/common/include/nrd3/nrd_plat_arm_def3.h @@ -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 ******************************************************************************/ From ac07f3ab6e82c8cbd36f2098a10b73efdd704c7d Mon Sep 17 00:00:00 2001 From: AlexeiFedorov Date: Wed, 22 Jan 2025 16:09:07 +0000 Subject: [PATCH 5/9] chore(gpt): define PPS in platform header files Define protected physical address size in bytes PLAT_ARM_PPS macro for FVP and RDV3 in platform_def.h files. Change-Id: I7f6529dfbb8df864091fbefc08131a0e6d689eb6 Signed-off-by: AlexeiFedorov --- include/plat/common/common_def.h | 6 +++++- plat/arm/board/fvp/include/platform_def.h | 3 +++ .../board/neoverse_rd/platform/rdv3/include/platform_def.h | 5 ++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/include/plat/common/common_def.h b/include/plat/common/common_def.h index ecec5bc9d..d9168572e 100644 --- a/include/plat/common/common_def.h +++ b/include/plat/common/common_def.h @@ -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,10 @@ #define SZ_1G UL(0x40000000) #define SZ_2G UL(0x80000000) + +#define SZ_1T UL(0x10000000000) + +#define SZ_1P UL(0x4000000000000) #else /* !__aarch64__ */ #define SZ_32 U(0x00000020) #define SZ_64 U(0x00000040) diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index df4be8f7c..25848e490 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -54,6 +54,9 @@ #if ENABLE_RME #define PLAT_ARM_RMM_BASE (RMM_BASE) #define PLAT_ARM_RMM_SIZE (RMM_LIMIT - RMM_BASE) + +/* Protected physical address size */ +#define PLAT_ARM_PPS (64 * SZ_1G) #endif /* diff --git a/plat/arm/board/neoverse_rd/platform/rdv3/include/platform_def.h b/plat/arm/board/neoverse_rd/platform/rdv3/include/platform_def.h index b55dbe803..0d0db773b 100644 --- a/plat/arm/board/neoverse_rd/platform/rdv3/include/platform_def.h +++ b/plat/arm/board/neoverse_rd/platform/rdv3/include/platform_def.h @@ -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 */ From b0f1c84035fb25e331b21f08f3f3e8e643c3394d Mon Sep 17 00:00:00 2001 From: AlexeiFedorov Date: Fri, 24 Jan 2025 15:53:50 +0000 Subject: [PATCH 6/9] feat(gpt): statically allocate bitlocks array Statically allocate 'gpt_bitlock' array of fine-grained 'bitlock_t' data structures in arm_bl31_setup.c. The amount of memory needed for this array is controlled by 'RME_GPT_BITLOCK_BLOCK' build option and 'PLAT_ARM_PPS' macro defined in platform_def.h which specifies the size of protected physical address space in bytes. 'PLAT_ARM_PPS' takes values from 4GB to 4PB supported by Arm architecture. Change-Id: Icf620b5039e45df6828d58fca089cad83b0bc669 Signed-off-by: AlexeiFedorov --- .../granule-protection-tables-design.rst | 36 +++-- include/lib/gpt_rme/gpt_rme.h | 19 ++- lib/gpt_rme/gpt_rme.c | 152 ++++++++---------- lib/gpt_rme/gpt_rme.mk | 15 +- lib/gpt_rme/gpt_rme_private.h | 8 +- plat/arm/board/fvp/include/platform_def.h | 2 +- plat/arm/common/arm_bl31_setup.c | 24 ++- 7 files changed, 138 insertions(+), 118 deletions(-) diff --git a/docs/components/granule-protection-tables-design.rst b/docs/components/granule-protection-tables-design.rst index 78d2f12aa..91673c6fd 100644 --- a/docs/components/granule-protection-tables-design.rst +++ b/docs/components/granule-protection-tables-design.rst @@ -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) diff --git a/include/lib/gpt_rme/gpt_rme.h b/include/lib/gpt_rme/gpt_rme.h index 94a88b0d5..135a94844 100644 --- a/include/lib/gpt_rme/gpt_rme.h +++ b/include/lib/gpt_rme/gpt_rme.h @@ -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 - -#include +#include /******************************************************************************/ /* 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 diff --git a/lib/gpt_rme/gpt_rme.c b/lib/gpt_rme/gpt_rme.c index 79c4ea5da..115f50dfd 100644 --- a/lib/gpt_rme/gpt_rme.c +++ b/lib/gpt_rme/gpt_rme.c @@ -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 #include -#include #include -#include "gpt_rme_private.h" #include #include -#include #include +#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; diff --git a/lib/gpt_rme/gpt_rme.mk b/lib/gpt_rme/gpt_rme.mk index 7d6b61f94..6878489e3 100644 --- a/lib/gpt_rme/gpt_rme.mk +++ b/lib/gpt_rme/gpt_rme.mk @@ -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 diff --git a/lib/gpt_rme/gpt_rme_private.h b/lib/gpt_rme/gpt_rme_private.h index 31dad20c7..78d1cecd7 100644 --- a/lib/gpt_rme/gpt_rme_private.h +++ b/lib/gpt_rme/gpt_rme_private.h @@ -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 #include -#include #include /******************************************************************************/ @@ -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(); */ diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index 25848e490..f597f4b12 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -57,7 +57,7 @@ /* Protected physical address size */ #define PLAT_ARM_PPS (64 * SZ_1G) -#endif +#endif /* ENABLE_RME */ /* * Max size of SPMC is 2MB for fvp. With SPMD enabled this value corresponds to diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index ce1545f5e..0503acf10 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -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(); } From aeec55c8760f384bee46e1999287b0a757227c69 Mon Sep 17 00:00:00 2001 From: AlexeiFedorov Date: Wed, 5 Feb 2025 11:53:25 +0000 Subject: [PATCH 7/9] feat(fvp): increase GPT PPS to 1TB - Increase PPS for FVP from 64GB to 1TB. - GPT L0 table for 1TB PPS requires 8KB memory. - Set FVP_TRUSTED_SRAM_SIZE to 384 with ENABLE_RME=1 option. - Add 256MB of PCIe memory region 1 and 3GB of PCIe memory region 2 to FVP PAS regions array. Change-Id: Icadd528576f53c55b5d461ff4dcd357429ba622a Signed-off-by: AlexeiFedorov --- docs/plat/arm/arm-build-options.rst | 3 +- include/plat/arm/common/arm_def.h | 4 +- plat/arm/board/fvp/fvp_bl2_setup.c | 18 ++++---- plat/arm/board/fvp/include/fvp_pas_def.h | 52 ++++++++++++++--------- plat/arm/board/fvp/include/platform_def.h | 19 +++++++-- plat/arm/board/fvp/platform.mk | 8 +++- 6 files changed, 68 insertions(+), 36 deletions(-) diff --git a/docs/plat/arm/arm-build-options.rst b/docs/plat/arm/arm-build-options.rst index a086a98db..3fad56694 100644 --- a/docs/plat/arm/arm-build-options.rst +++ b/docs/plat/arm/arm-build-options.rst @@ -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 ---------------------- diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index e94b32a6a..cc1dcde3d 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -67,7 +67,7 @@ #define ARM_L0_GPT_BASE (ARM_TRUSTED_SRAM_BASE + \ PLAT_ARM_TRUSTED_SRAM_SIZE - \ ARM_L0_GPT_SIZE) -#define ARM_L0_GPT_SIZE UL(0x00001000) /* 4 KB */ +#define ARM_L0_GPT_SIZE UL(0x00002000) /* 8 KB */ #else #define ARM_L0_GPT_SIZE UL(0) #endif @@ -120,7 +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 (GPCCR_PPS_64GB, GPCCR_PGS_4K) */ +/* 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) - \ diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c index be8a19c35..90d9608ca 100644 --- a/plat/arm/board/fvp/fvp_bl2_setup.c +++ b/plat/arm/board/fvp/fvp_bl2_setup.c @@ -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 */ @@ -33,20 +33,22 @@ static pas_region_t pas_regions[] = { #ifdef ARM_PAS_GPTS ARM_PAS_GPTS, #endif - ARM_PAS_KERNEL_1 + 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) { diff --git a/plat/arm/board/fvp/include/fvp_pas_def.h b/plat/arm/board/fvp/include/fvp_pas_def.h index 928c33a3a..6b9728618 100644 --- a/plat/arm/board/fvp/include/fvp_pas_def.h +++ b/plat/arm/board/fvp/include/fvp_pas_def.h @@ -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,31 +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 | 40000000 | | |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 | 40000000 | | | | + * 1GB | 1GB |L0 GPT|ANY |IO |Fixed mapping + * 40000000 | 40000000 | | | | * ---------------------------------------------------------------------------- - * 2GB | 2GB-64MB |L1 GPT|NS |DRAM (NS Kernel) |Use T.Descrip - * 80000000 | 7C000000 | | | | + * 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 | 1C00000 | | | | + * 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 | 2000000 | | | | + * 4GB-64MB |64MB-32MB-4MB|L1 GPT|SECURE|DRAM TZC |Use T.Descrip + * FC000000 | 1C00000 | | | | * ---------------------------------------------------------------------------- - * 4GB-3MB | | | | | - * -1MB | 4MB |L1 GPT|ROOT |EL3 DRAM data, L1 GPTs, |Use T.Descrip - * FFC00000 | 400000 | | |SCP TZC | + * 4GB-32MB | | | | | + * -3MB-1MB | 32MB |L1 GPT|REALM |RMM |Use T.Descrip + * FDC00000 | 2000000 | | | | * ---------------------------------------------------------------------------- - * 34GB | 2GB |L1 GPT|NS |DRAM (NS Kernel) |Use T.Descrip - * 880000000| 80000000 | | | | + * 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 | 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. @@ -91,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. diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index f597f4b12..f5be8f2d2 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -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 */ @@ -56,7 +56,7 @@ #define PLAT_ARM_RMM_SIZE (RMM_LIMIT - RMM_BASE) /* Protected physical address size */ -#define PLAT_ARM_PPS (64 * SZ_1G) +#define PLAT_ARM_PPS (SZ_1T) #endif /* ENABLE_RME */ /* @@ -68,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 */ @@ -402,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 * diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index ce0614652..05bd913e3 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -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 From 991f5360b68d6cdfbda2950100dbf78ac1c482cc Mon Sep 17 00:00:00 2001 From: Jens Wiklander Date: Fri, 7 Feb 2025 07:51:07 +0100 Subject: [PATCH 8/9] feat(qemu): update for renamed struct memory_bank The struct ns_dram_bank has been renamed to struct memory_bank, so update plat/qemu accordingly. Signed-off-by: Jens Wiklander Change-Id: If5ed92edd132c977009a7371ec53eca0ee35ef00 --- plat/qemu/common/qemu_common.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plat/qemu/common/qemu_common.c b/plat/qemu/common/qemu_common.c index 5dc39a1ec..a88297da8 100644 --- a/plat/qemu/common/qemu_common.c +++ b/plat/qemu/common/qemu_common.c @@ -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; From a32a77f9c7567141556a823c0b9d4d5488c95722 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Brucker Date: Tue, 11 Feb 2025 14:10:34 +0000 Subject: [PATCH 9/9] fix(qemu): statically allocate bitlocks array gpt_runtime_init() now takes the bitlock array's address and size as argument. Rather than reserving space at the end of the L0 GPT for storing bitlocks, allocate a static array and pass its address to gpt_runtime_init(). This frees up a little bit of space formerly reserved for alignment of the GPT. Change-Id: I48a1a2bc230f64e13e3ed08b18ebdc2d387d77d0 Signed-off-by: Jean-Philippe Brucker --- include/plat/common/common_def.h | 1 + plat/qemu/common/qemu_bl31_setup.c | 31 ++++++++++++++++--- plat/qemu/qemu/include/platform_def.h | 17 +++------- plat/qemu/qemu/include/qemu_pas_def.h | 3 +- plat/qemu/qemu_sbsa/include/platform_def.h | 28 ++--------------- .../qemu_sbsa/include/qemu_sbsa_pas_def.h | 3 +- 6 files changed, 40 insertions(+), 43 deletions(-) diff --git a/include/plat/common/common_def.h b/include/plat/common/common_def.h index d9168572e..3cfab4fe7 100644 --- a/include/plat/common/common_def.h +++ b/include/plat/common/common_def.h @@ -45,6 +45,7 @@ #define SZ_2G UL(0x80000000) #define SZ_1T UL(0x10000000000) +#define SZ_4T UL(0x40000000000) #define SZ_1P UL(0x4000000000000) #else /* !__aarch64__ */ diff --git a/plat/qemu/common/qemu_bl31_setup.c b/plat/qemu/common/qemu_bl31_setup.c index 81ce1023a..1c5e0eaf7 100644 --- a/plat/qemu/common/qemu_bl31_setup.c +++ b/plat/qemu/common/qemu_bl31_setup.c @@ -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(); } diff --git a/plat/qemu/qemu/include/platform_def.h b/plat/qemu/qemu/include/platform_def.h index 0c85b1edc..7dd7dcda5 100644 --- a/plat/qemu/qemu/include/platform_def.h +++ b/plat/qemu/qemu/include/platform_def.h @@ -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( \ diff --git a/plat/qemu/qemu/include/qemu_pas_def.h b/plat/qemu/qemu/include/qemu_pas_def.h index 30934f0f0..379519f33 100644 --- a/plat/qemu/qemu/include/qemu_pas_def.h +++ b/plat/qemu/qemu/include/qemu_pas_def.h @@ -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 diff --git a/plat/qemu/qemu_sbsa/include/platform_def.h b/plat/qemu/qemu_sbsa/include/platform_def.h index 06e8abf56..5cc20b97d 100644 --- a/plat/qemu/qemu_sbsa/include/platform_def.h +++ b/plat/qemu/qemu_sbsa/include/platform_def.h @@ -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( \ diff --git a/plat/qemu/qemu_sbsa/include/qemu_sbsa_pas_def.h b/plat/qemu/qemu_sbsa/include/qemu_sbsa_pas_def.h index c73a16255..cf43a781e 100644 --- a/plat/qemu/qemu_sbsa/include/qemu_sbsa_pas_def.h +++ b/plat/qemu/qemu_sbsa/include/qemu_sbsa_pas_def.h @@ -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