Merge "feat(rme): add SMMU and PCIe information to Boot manifest" into integration

This commit is contained in:
Soby Mathew 2025-03-25 12:35:47 +01:00 committed by TrustedFirmware Code Review
commit 90f9c9bef5
5 changed files with 572 additions and 103 deletions

View file

@ -768,47 +768,53 @@ _____
RMM-EL3 Boot Manifest structure RMM-EL3 Boot Manifest structure
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The RMM-EL3 Boot Manifest v0.4 structure contains platform boot information passed The RMM-EL3 Boot Manifest v0.5 structure contains platform boot information passed
from EL3 to RMM. The size of the Boot Manifest is 112 bytes. from EL3 to RMM. The size of the Boot Manifest is 160 bytes.
The members of the RMM-EL3 Boot Manifest structure are shown in the following The members of the RMM-EL3 Boot Manifest structure are shown in the following
table: table:
+--------------------+--------+-------------------+----------------------------------------------+ +-------------------+--------+-------------------+----------------------------------------------+
| Name | Offset | Type | Description | | Name | Offset | Type | Description |
+====================+========+===================+==============================================+ +===================+========+===================+==============================================+
| version | 0 | uint32_t | Boot Manifest version | | version | 0 | uint32_t | Boot Manifest version |
+--------------------+--------+-------------------+----------------------------------------------+ +-------------------+--------+-------------------+----------------------------------------------+
| padding | 4 | uint32_t | Reserved, set to 0 | | padding | 4 | uint32_t | Reserved, set to 0 |
+--------------------+--------+-------------------+----------------------------------------------+ +-------------------+--------+-------------------+----------------------------------------------+
| plat_data | 8 | uintptr_t | Pointer to Platform Data section | | plat_data | 8 | uint64_t | Pointer to Platform Data section |
+--------------------+--------+-------------------+----------------------------------------------+ +-------------------+--------+-------------------+----------------------------------------------+
| plat_dram | 16 | memory_info | NS DRAM Layout Info structure | | plat_dram | 16 | memory_info | NS DRAM Layout Info structure |
+--------------------+--------+-------------------+----------------------------------------------+ +-------------------+--------+-------------------+----------------------------------------------+
| plat_console | 40 | console_list | List of consoles available to RMM | | plat_console | 40 | console_list | List of consoles available to RMM |
+--------------------+--------+-------------------+----------------------------------------------+ +-------------------+--------+-------------------+----------------------------------------------+
| plat_ncoh_region | 64 | memory_info | Device non-coherent ranges Info structure | | plat_ncoh_region | 64 | memory_info | Device non-coherent ranges Info structure |
+--------------------+--------+-------------------+----------------------------------------------+ +-------------------+--------+-------------------+----------------------------------------------+
| plat_coh_region | 88 | memory_info | Device coherent ranges Info structure | | plat_coh_region | 88 | memory_info | Device coherent ranges Info structure |
+--------------------+--------+-------------------+----------------------------------------------+ +-------------------+--------+-------------------+----------------------------------------------+
| plat_smmu | 112 | smmu_list | List of SMMUs available to RMM |
| | | | (from Boot Manifest v0.5) |
+-------------------+--------+-------------------+----------------------------------------------+
| plat_root_complex | 136 | root_complex_list | List of PCIe root complexes available to RMM |
| | | | (from Boot Manifest v0.5) |
+-------------------+--------+-------------------+----------------------------------------------+
.. _memory_info_struct: .. _memory_info_struct:
Memory Info structure Memory Info structure
~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~
Memory Info structure contains information about platform memory layout. Memory Info structure contains information about platform memory layout.
The members of this structure are shown in the table below: The members of this structure are shown in the table below:
+-----------+--------+----------------+----------------------------------------+ +-----------+--------+---------------+----------------------------------------+
| Name | Offset | Type | Description | | Name | Offset | Type | Description |
+===========+========+================+========================================+ +===========+========+===============+========================================+
| num_banks | 0 | uint64_t | Number of memory banks/device regions | | num_banks | 0 | uint64_t | Number of memory banks/device regions |
+-----------+--------+----------------+----------------------------------------+ +-----------+--------+---------------+----------------------------------------+
| banks | 8 | memory_bank * | Pointer to 'memory_bank'[] array | | banks | 8 | memory_bank * | Pointer to 'memory_bank'[] array |
+-----------+--------+----------------+----------------------------------------+ +-----------+--------+---------------+----------------------------------------+
| checksum | 16 | uint64_t | Checksum | | checksum | 16 | uint64_t | Checksum |
+-----------+--------+----------------+----------------------------------------+ +-----------+--------+---------------+----------------------------------------+
Checksum is calculated as two's complement sum of 'num_banks', 'banks' pointer Checksum is calculated as two's complement sum of 'num_banks', 'banks' pointer
and memory banks data array pointed by it. and memory banks data array pointed by it.
@ -820,13 +826,13 @@ Memory Bank/Device region structure
Memory Bank structure contains information about each memory bank/device region: Memory Bank structure contains information about each memory bank/device region:
+-----------+--------+----------------+--------------------------------------------+ +------+--------+----------+--------------------------------------------+
| Name | Offset | Type | Description | | Name | Offset | Type | Description |
+===========+========+================+============================================+ +======+========+==========+============================================+
| base | 0 | uintptr_t | Base address | | base | 0 | uint64_t | Base address |
+-----------+--------+----------------+--------------------------------------------+ +------+--------+----------+--------------------------------------------+
| size | 8 | uint64_t | Size of memory bank/device region in bytes | | size | 8 | uint64_t | Size of memory bank/device region in bytes |
+-----------+--------+----------------+--------------------------------------------+ +------+--------+----------+--------------------------------------------+
.. _console_list_struct: .. _console_list_struct:
@ -836,15 +842,15 @@ Console List structure
Console List structure contains information about the available consoles for RMM. Console List structure contains information about the available consoles for RMM.
The members of this structure are shown in the table below: The members of this structure are shown in the table below:
+--------------+--------+----------------+-------------------------------------+ +--------------+--------+----------------+-----------------------------------+
| Name | Offset | Type | Description | | Name | Offset | Type | Description |
+==============+========+================+=====================================+ +==============+========+================+===================================+
| num_consoles | 0 | uint64_t | Number of consoles | | num_consoles | 0 | uint64_t | Number of consoles |
+--------------+--------+----------------+-------------------------------------+ +--------------+--------+----------------+-----------------------------------+
| consoles | 8 | console_info * | Pointer to 'console_info'[] array | | consoles | 8 | console_info * | Pointer to 'console_info'[] array |
+--------------+--------+----------------+-------------------------------------+ +--------------+--------+----------------+-----------------------------------+
| checksum | 16 | uint64_t | Checksum | | checksum | 16 | uint64_t | Checksum |
+--------------+--------+----------------+-------------------------------------+ +--------------+--------+----------------+-----------------------------------+
Checksum is calculated as two's complement sum of 'num_consoles', 'consoles' Checksum is calculated as two's complement sum of 'num_consoles', 'consoles'
pointer and the consoles array pointed by it. pointer and the consoles array pointed by it.
@ -856,21 +862,144 @@ Console Info structure
Console Info structure contains information about each Console available to RMM. Console Info structure contains information about each Console available to RMM.
+-----------+--------+---------------+-----------------------------------------+ +-----------+--------+----------+--------------------------------------+
| Name | Offset | Type | Description | | Name | Offset | Type | Description |
+===========+========+===============+=========================================+ +===========+========+==========+======================================+
| base | 0 | uintptr_t | Console Base address | | base | 0 | uint64_t | Console Base address |
+-----------+--------+---------------+-----------------------------------------+ +-----------+--------+----------+--------------------------------------+
| map_pages | 8 | uint64_t | Num of pages to map for console MMIO | | map_pages | 8 | uint64_t | Num of pages to map for console MMIO |
+-----------+--------+---------------+-----------------------------------------+ +-----------+--------+----------+--------------------------------------+
| name | 16 | char[8] | Name of console | | name | 16 | char[8] | Name of console |
+-----------+--------+---------------+-----------------------------------------+ +-----------+--------+----------+--------------------------------------+
| clk_in_hz | 24 | uint64_t | UART clock (in Hz) for console | | clk_in_hz | 24 | uint64_t | UART clock (in Hz) for console |
+-----------+--------+---------------+-----------------------------------------+ +-----------+--------+----------+--------------------------------------+
| baud_rate | 32 | uint64_t | Baud rate | | baud_rate | 32 | uint64_t | Baud rate |
+-----------+--------+---------------+-----------------------------------------+ +-----------+--------+----------+--------------------------------------+
| flags | 40 | uint64_t | Additional flags (RES0) | | flags | 40 | uint64_t | Additional flags (RES0) |
+-----------+--------+---------------+-----------------------------------------+ +-----------+--------+----------+--------------------------------------+
.. _smmu_list_struct:
SMMU List structure
~~~~~~~~~~~~~~~~~~~
SMMU List structure contains information about SMMUs available for RMM.
The members of this structure are shown in the table below:
+-----------+--------+-------------+--------------------------------+
| Name | Offset | Type | Description |
+===========+========+=============+================================+
| num_smmus | 0 | uint64_t | Number of SMMUs |
+-----------+--------+-------------+--------------------------------+
| smmus | 8 | smmu_info * | Pointer to 'smmu_info'[] array |
+-----------+--------+-------------+--------------------------------+
| checksum | 16 | uint64_t | Checksum |
+-----------+--------+-------------+--------------------------------+
.. _smmu_info_struct:
SMMU Info structure
~~~~~~~~~~~~~~~~~~~
SMMU Info structure contains information about each SMMU available to RMM.
+-------------+--------+----------+-------------------------------+
| Name | Offset | Type | Description |
+=============+========+==========+===============================+
| smmu_base | 0 | uint64_t | SMMU Base address |
+-------------+--------+----------+-------------------------------+
| smmu_r_base | 8 | uint64_t | SMMU Realm Pages base address |
+-------------+--------+----------+-------------------------------+
.. _root_complex_list_struct:
Root Complex List structure
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Root Complex List structure contains information about PCIe root complexes available for RMM.
The members of this structure are shown in the table below.
+------------------+--------+---------------------+-------------------------------------+
| Name | Offset | Type | Description |
+==================+========+=====================+=====================================+
| num_root_complex | 0 | uint64_t | Number of root complexes |
+------------------+--------+---------------------+-------------------------------------+
| rc_info_version | 8 | uint32_t | Root Complex Info structure version |
+------------------+--------+---------------------+-------------------------------------+
| padding | 12 | uint32_t | Reserved, set to 0 |
+------------------+--------+---------------------+-------------------------------------+
| root_complex | 16 | root_complex_info * | Pointer to 'root_complex'[] array |
+------------------+--------+---------------------+-------------------------------------+
| checksum | 24 | uint64_t | Checksum |
+------------------+--------+---------------------+-------------------------------------+
The checksum calculation of Root Complex List structure includes all data structures
referenced by 'root_complex_info' pointer.
.. _root_complex_info_struct:
Root Complex Info structure
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Root Complex Info structure contains information about each PCIe root complex available to RMM.
The table below describes the members of this structure as per v0.1.
+-----------------+--------+------------------+-------------------------------------+
| Name | Offset | Type | Description |
+=================+========+==================+=====================================+
| ecam_base | 0 | uint64_t | PCIe ECAM Base address |
+-----------------+--------+------------------+-------------------------------------+
| segment | 8 | uint8_t | PCIe segment identifier |
+-----------------+--------+------------------+-------------------------------------+
| padding[3] | 9 | uint8_t | Reserved, set to 0 |
+-----------------+--------+------------------+-------------------------------------+
| num_root_ports | 12 | uint32_t | Number of root ports |
+-----------------+--------+------------------+-------------------------------------+
| root_ports | 16 | root_port_info * | Pointer to 'root_port_info'[] array |
+-----------------+--------+------------------+-------------------------------------+
The Root Complex Info structure version uses the same numbering scheme as described in
:ref:`rmm_el3_ifc_versioning`.
.. _root_port_info_struct:
Root Port Info structure
~~~~~~~~~~~~~~~~~~~~~~~~
Root Complex Info structure contains information about each root port in PCIe root complex.
+------------------+--------+--------------------+---------------------------------------+
| Name | Offset | Type | Description |
+==================+========+====================+=======================================+
| root_port_id | 0 | uint16_t | Root Port identifier |
+------------------+--------+--------------------+---------------------------------------+
| padding | 2 | uint16_t | Reserved, set to 0 |
+------------------+--------+--------------------+---------------------------------------+
| num_bdf_mappings | 4 | uint32_t | Number of BDF mappings |
+------------------+--------+--------------------+---------------------------------------+
| bdf_mappings | 8 | bdf_mapping_info * | Pointer to 'bdf_mapping_info'[] array |
+------------------+--------+--------------------+---------------------------------------+
.. _bdf_mapping_info_struct:
BDF Mapping Info structure
~~~~~~~~~~~~~~~~~~~~~~~~~~
BDF Mapping Info structure contains information about each Device-Bus-Function (BDF) mapping
for PCIe root port.
+--------------+--------+----------+------------------------------------------------------+
| Name | Offset | Type | Description |
+==============+========+==========+======================================================+
| mapping_base | 0 | uint16_t | Base of BDF mapping (inclusive) |
+--------------+--------+----------+------------------------------------------------------+
| mapping_top | 2 | uint16_t | Top of BDF mapping (exclusive) |
+--------------+--------+----------+------------------------------------------------------+
| mapping_off | 4 | uint16_t | Mapping offset, as per Arm Base System Architecture: |
| | | | StreamID = RequesterID[N-1:0] + (1<<N)*Constant_B |
+--------------+--------+----------+------------------------------------------------------+
| smmu_idx | 6 | uint16_t | SMMU index in 'smmu_info'[] array |
+--------------+--------+----------+------------------------------------------------------+
.. _el3_token_sign_request_struct: .. _el3_token_sign_request_struct:

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2017-2025, ARM Limited and Contributors. All rights reserved.
* *
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
@ -58,6 +58,8 @@
/* SMMU_ROOT_IDR0 register fields */ /* SMMU_ROOT_IDR0 register fields */
#define SMMU_ROOT_IDR0_ROOT_IMPL (1UL << 0) #define SMMU_ROOT_IDR0_ROOT_IMPL (1UL << 0)
#define SMMU_ROOT_IDR0_BA_REALM_SHIFT 22U
#define SMMU_ROOT_IDR0_BA_REALM_MASK GENMASK_32(31U, SMMU_ROOT_IDR0_BA_REALM_SHIFT)
/* SMMU_ROOT_CR0 register fields */ /* SMMU_ROOT_CR0 register fields */
#define SMMU_ROOT_CR0_GPCEN (1UL << 1) #define SMMU_ROOT_CR0_GPCEN (1UL << 1)

View file

@ -14,20 +14,21 @@
#include <lib/cassert.h> #include <lib/cassert.h>
#define RMMD_MANIFEST_VERSION_MAJOR U(0) #define RMMD_MANIFEST_VERSION_MAJOR U(0)
#define RMMD_MANIFEST_VERSION_MINOR U(4) #define RMMD_MANIFEST_VERSION_MINOR U(5)
#define RMM_CONSOLE_MAX_NAME_LEN U(8) #define RMM_CONSOLE_MAX_NAME_LEN U(8)
/* /*
* Manifest version encoding: * Version encoding:
* - Bit[31] RES0 * - Bit[31] RES0
* - Bits [30:16] Major version * - Bits [30:16] Major version
* - Bits [15:0] Minor version * - Bits [15:0] Minor version
*/ */
#define SET_RMMD_MANIFEST_VERSION(_major, _minor) \ #define SET_VERSION(_major, _minor) \
((((_major) & 0x7FFF) << 16) | ((_minor) & 0xFFFF)) ((((_major) & 0x7FFF) << 16) | ((_minor) & 0xFFFF))
#define RMMD_MANIFEST_VERSION SET_RMMD_MANIFEST_VERSION( \ /* Boot Manifest version */
#define RMMD_MANIFEST_VERSION SET_VERSION( \
RMMD_MANIFEST_VERSION_MAJOR, \ RMMD_MANIFEST_VERSION_MAJOR, \
RMMD_MANIFEST_VERSION_MINOR) RMMD_MANIFEST_VERSION_MINOR)
@ -37,9 +38,17 @@
#define RMMD_GET_MANIFEST_VERSION_MINOR(_version) \ #define RMMD_GET_MANIFEST_VERSION_MINOR(_version) \
(_version & 0xFFFF) (_version & 0xFFFF)
#define PCIE_RC_INFO_VERSION_MAJOR U(0)
#define PCIE_RC_INFO_VERSION_MINOR U(1)
/* PCIe Root Complex info structure version */
#define PCIE_RC_INFO_VERSION SET_VERSION( \
PCIE_RC_INFO_VERSION_MAJOR, \
PCIE_RC_INFO_VERSION_MINOR)
/* Memory bank/device region structure */ /* Memory bank/device region structure */
struct memory_bank { struct memory_bank {
uintptr_t base; /* Base address */ uint64_t base; /* Base address */
uint64_t size; /* Size of memory bank/device region */ uint64_t size; /* Size of memory bank/device region */
}; };
@ -64,7 +73,7 @@ CASSERT(offsetof(struct memory_info, checksum) == 16UL,
/* Console info structure */ /* Console info structure */
struct console_info { struct console_info {
uintptr_t base; /* Console base address */ uint64_t base; /* Console base address */
uint64_t map_pages; /* Num of pages to be mapped in RMM for the console MMIO */ uint64_t map_pages; /* Num of pages to be mapped in RMM for the console MMIO */
char name[RMM_CONSOLE_MAX_NAME_LEN]; /* Name of console */ char name[RMM_CONSOLE_MAX_NAME_LEN]; /* Name of console */
uint64_t clk_in_hz; /* UART clock (in Hz) for the console */ uint64_t clk_in_hz; /* UART clock (in Hz) for the console */
@ -98,11 +107,105 @@ CASSERT(offsetof(struct console_list, consoles) == 8UL,
CASSERT(offsetof(struct console_list, checksum) == 16UL, CASSERT(offsetof(struct console_list, checksum) == 16UL,
rmm_manifest_console_list_checksum); rmm_manifest_console_list_checksum);
/* Boot manifest core structure as per v0.4 */ /* SMMUv3 Info structure */
struct smmu_info {
uint64_t smmu_base; /* SMMUv3 base address */
uint64_t smmu_r_base; /* SMMUv3 Realm Pages base address */
};
CASSERT(offsetof(struct smmu_info, smmu_base) == 0UL,
rmm_manifest_smmu_base);
CASSERT(offsetof(struct smmu_info, smmu_r_base) == 8UL,
rmm_manifest_smmu_r_base);
/* SMMUv3 Info List structure */
struct smmu_list {
uint64_t num_smmus; /* Number of smmu_info entries */
struct smmu_info *smmus; /* Pointer to smmu_info[] array */
uint64_t checksum; /* Checksum of smmu_list data */
};
CASSERT(offsetof(struct smmu_list, num_smmus) == 0UL,
rmm_manifest_num_smmus);
CASSERT(offsetof(struct smmu_list, smmus) == 8UL,
rmm_manifest_smmus);
CASSERT(offsetof(struct smmu_list, checksum) == 16UL,
rmm_manifest_smmu_list_checksum);
/* PCIe BDF Mapping Info structure */
struct bdf_mapping_info {
uint16_t mapping_base; /* Base of BDF mapping (inclusive) */
uint16_t mapping_top; /* Top of BDF mapping (exclusive) */
uint16_t mapping_off; /* Mapping offset, as per Arm Base System Architecture: */
/* StreamID = zero_extend(RequesterID[N-1:0]) + (1<<N)*Constant_B */
uint16_t smmu_idx; /* SMMU index in smmu_info[] array */
};
CASSERT(offsetof(struct bdf_mapping_info, mapping_base) == 0UL,
rmm_manifest_mapping_base);
CASSERT(offsetof(struct bdf_mapping_info, mapping_top) == 2UL,
rmm_manifest_mapping_top);
CASSERT(offsetof(struct bdf_mapping_info, mapping_off) == 4UL,
rmm_manifest_mapping_off);
CASSERT(offsetof(struct bdf_mapping_info, smmu_idx) == 6UL,
rmm_manifest_smmu_ptr);
/* PCIe Root Port Info structure */
struct root_port_info {
uint16_t root_port_id; /* Root Port identifier */
uint16_t padding; /* RES0 */
uint32_t num_bdf_mappings; /* Number of BDF mappings */
struct bdf_mapping_info *bdf_mappings; /* Pointer to bdf_mapping_info[] array */
};
CASSERT(offsetof(struct root_port_info, root_port_id) == 0UL,
rmm_manifest_root_port_id);
CASSERT(offsetof(struct root_port_info, num_bdf_mappings) == 4UL,
rmm_manifest_num_bdf_mappingss);
CASSERT(offsetof(struct root_port_info, bdf_mappings) == 8UL,
rmm_manifest_bdf_mappings);
/* PCIe Root Complex info structure v0.1 */
struct root_complex_info {
uint64_t ecam_base; /* ECAM base address. Size is implicitly 256MB */
uint8_t segment; /* PCIe segment identifier */
uint8_t padding[3]; /* RES0 */
uint32_t num_root_ports; /* Number of root ports */
struct root_port_info *root_ports; /* Pointer to root_port_info[] array */
};
CASSERT(offsetof(struct root_complex_info, ecam_base) == 0UL,
rmm_manifest_ecam_base);
CASSERT(offsetof(struct root_complex_info, segment) == 8UL,
rmm_manifest_segment);
CASSERT(offsetof(struct root_complex_info, num_root_ports) == 12UL,
rmm_manifest_num_root_ports);
CASSERT(offsetof(struct root_complex_info, root_ports) == 16UL,
rmm_manifest_root_ports);
/* PCIe Root Complex List structure */
struct root_complex_list {
uint64_t num_root_complex; /* Number of pci_rc_info entries */
uint32_t rc_info_version; /* PCIe Root Complex info structure version */
uint32_t padding; /* RES0 */
struct root_complex_info *root_complex; /* Pointer to pci_rc_info[] array */
uint64_t checksum; /* Checksum of pci_rc_list data */
};
CASSERT(offsetof(struct root_complex_list, num_root_complex) == 0UL,
rmm_manifest_num_root_complex);
CASSERT(offsetof(struct root_complex_list, rc_info_version) == 8UL,
rmm_manifest_rc_info_version);
CASSERT(offsetof(struct root_complex_list, root_complex) == 16UL,
rmm_manifest_root_complex);
CASSERT(offsetof(struct root_complex_list, checksum) == 24UL,
rmm_manifest_root_complex_list_checksum);
/* Boot manifest core structure as per v0.5 */
struct rmm_manifest { struct rmm_manifest {
uint32_t version; /* Manifest version */ uint32_t version; /* Manifest version */
uint32_t padding; /* RES0 */ uint32_t padding; /* RES0 */
uintptr_t plat_data; /* Manifest platform data */ uint64_t plat_data; /* Manifest platform data */
/* Platform NS DRAM data (v0.2) */ /* Platform NS DRAM data (v0.2) */
struct memory_info plat_dram; struct memory_info plat_dram;
/* Platform console list (v0.3) */ /* Platform console list (v0.3) */
@ -110,6 +213,10 @@ struct rmm_manifest {
/* Platform device address ranges (v0.4) */ /* Platform device address ranges (v0.4) */
struct memory_info plat_ncoh_region; struct memory_info plat_ncoh_region;
struct memory_info plat_coh_region; struct memory_info plat_coh_region;
/* Platform SMMUv3 list (v0.5) */
struct smmu_list plat_smmu;
/* Platform PCIe Root Complex list (v0.5) */
struct root_complex_list plat_root_complex;
}; };
CASSERT(offsetof(struct rmm_manifest, version) == 0UL, CASSERT(offsetof(struct rmm_manifest, version) == 0UL,
@ -124,5 +231,9 @@ CASSERT(offsetof(struct rmm_manifest, plat_ncoh_region) == 64UL,
rmm_manifest_plat_ncoh_region_unaligned); rmm_manifest_plat_ncoh_region_unaligned);
CASSERT(offsetof(struct rmm_manifest, plat_coh_region) == 88UL, CASSERT(offsetof(struct rmm_manifest, plat_coh_region) == 88UL,
rmm_manifest_plat_coh_region_unaligned); rmm_manifest_plat_coh_region_unaligned);
CASSERT(offsetof(struct rmm_manifest, plat_smmu) == 112UL,
rmm_manifest_plat_smmu_unaligned);
CASSERT(offsetof(struct rmm_manifest, plat_root_complex) == 136UL,
rmm_manifest_plat_root_complex);
#endif /* RMM_CORE_MANIFEST_H */ #endif /* RMM_CORE_MANIFEST_H */

View file

@ -343,7 +343,7 @@ int fconf_populate_dram_layout(uintptr_t config)
for (unsigned long i = 0UL; i < dram_layout.num_banks; i++) { for (unsigned long i = 0UL; i < dram_layout.num_banks; i++) {
int err = fdt_get_reg_props_by_index( int err = fdt_get_reg_props_by_index(
hw_config_dtb, node, (int)i, hw_config_dtb, node, (int)i,
&dram_layout.dram_bank[i].base, (uintptr_t *)&dram_layout.dram_bank[i].base,
(size_t *)&dram_layout.dram_bank[i].size); (size_t *)&dram_layout.dram_bank[i].size);
if (err < 0) { if (err < 0) {
ERROR("FCONF: Failed to read 'reg' property #%lu of 'memory' node\n", i); ERROR("FCONF: Failed to read 'reg' property #%lu of 'memory' node\n", i);

View file

@ -14,6 +14,7 @@
#include <drivers/arm/ccn.h> #include <drivers/arm/ccn.h>
#include <drivers/arm/gicv2.h> #include <drivers/arm/gicv2.h>
#include <drivers/arm/sp804_delay_timer.h> #include <drivers/arm/sp804_delay_timer.h>
#include <drivers/arm/smmu_v3.h>
#include <drivers/generic_delay_timer.h> #include <drivers/generic_delay_timer.h>
#include <fconf_hw_config_getter.h> #include <fconf_hw_config_getter.h>
#include <lib/mmio.h> #include <lib/mmio.h>
@ -43,6 +44,15 @@
#define FVP_RMM_CONSOLE_NAME "pl011" #define FVP_RMM_CONSOLE_NAME "pl011"
#define FVP_RMM_CONSOLE_COUNT UL(1) #define FVP_RMM_CONSOLE_COUNT UL(1)
/* Defines for RMM PCIe ECAM */
#define FVP_RMM_ECAM_BASE PCIE_EXP_BASE
#define FVP_RMM_ECAM_SEGMENT UL(0x0)
#define FVP_RMM_ECAM_BDF UL(0x0)
/* Defines for RMM SMMUv3 */
#define FVP_RMM_SMMU_BASE PLAT_FVP_SMMUV3_BASE
#define FVP_RMM_SMMU_COUNT UL(1)
/******************************************************************************* /*******************************************************************************
* arm_config holds the characteristics of the differences between the three FVP * arm_config holds the characteristics of the differences between the three FVP
* platforms (Base, A53_A57 & Foundation). It will be populated during cold boot * platforms (Base, A53_A57 & Foundation). It will be populated during cold boot
@ -563,6 +573,41 @@ int32_t plat_get_soc_revision(void)
} }
#if ENABLE_RME #if ENABLE_RME
/* BDF mappings for RP0 RC0 */
const struct bdf_mapping_info rc0rp0_bdf_data[] = {
/* BDF0 */
{0U, /* mapping_base */
0x8000U, /* mapping_top */
0U, /* mapping_off */
0U /* smmu_idx */
}
};
/* Root ports for RC0 */
const struct root_port_info rc0rp_data[] = {
/* RP0 */
{0U, /* root_port_id */
0U, /* padding */
ARRAY_SIZE(rc0rp0_bdf_data), /* num_bdf_mappings */
(struct bdf_mapping_info *)rc0rp0_bdf_data /* bdf_mappings */
}
};
/* Root complexes */
const struct root_complex_info rc_data[] = {
/* RC0 */
{PCIE_EXP_BASE, /* ecam_base */
0U, /* segment */
{0U, 0U, 0U}, /* padding */
ARRAY_SIZE(rc0rp_data), /* num_root_ports */
(struct root_port_info *)rc0rp_data /* root_ports */
}
};
/* Number of PCIe Root Complexes */
#define FVP_RMM_RC_COUNT ARRAY_SIZE(rc_data)
/* /*
* Get a pointer to the RMM-EL3 Shared buffer and return it * Get a pointer to the RMM-EL3 Shared buffer and return it
* through the pointer passed as parameter. * through the pointer passed as parameter.
@ -593,14 +638,14 @@ static uint64_t checksum_calc(uint64_t *buffer, size_t size)
return sum; return sum;
} }
/* /*
* Boot Manifest structure illustration, with two DRAM banks, * Boot Manifest v0.5 structure illustration, with two DRAM banks,
* a single console and one device memory with two PCIe device * a single console and one device memory with two PCIe device
* non-coherent address ranges. * non-coherent address ranges.
* *
* +--------------------------------------------------+ * +--------------------------------------------------+
* | offset | field | comment | * | offset | field | comment |
* +--------+--------------------+--------------------+ * +--------+--------------------+--------------------+
* | 0 | version | 0x00000004 | * | 0 | version | 0x00000005 |
* +--------+--------------------+--------------------+ * +--------+--------------------+--------------------+
* | 4 | padding | 0x00000000 | * | 4 | padding | 0x00000000 |
* +--------+--------------------+--------------------+ * +--------+--------------------+--------------------+
@ -629,42 +674,95 @@ static uint64_t checksum_calc(uint64_t *buffer, size_t size)
* | 96 | banks | plat_coh_region | | | | * | 96 | banks | plat_coh_region | | | |
* +--------+--------------------+ | | | | * +--------+--------------------+ | | | |
* | 104 | checksum | | | | | * | 104 | checksum | | | | |
* +--------+--------------------+--------------------+<-+ | | * +--------+--------------------+--------------------+ | | |
* | 112 | base 0 | | | | * | 112 | num_smmus | | | | |
* +--------+--------------------+ mem_bank[0] | | | * +--------+--------------------+ | | | |
* | 120 | size 0 | | | | * | 120 | smmus | plat_smmu +--|--|--|--+
* +--------+--------------------+--------------------+ | | * +--------+--------------------+ | | | | |
* | 128 | base 1 | | | | * | 128 | checksum | | | | | |
* +--------+--------------------+ mem_bank[1] | | | * +--------+--------------------+--------------------+ | | | |
* | 136 | size 1 | | | | * | 136 | num_root_complex | | | | | |
* +--------+--------------------+--------------------+<----+ | * +--------+--------------------+ | | | | |
* | 144 | base | | | * | 144 | rc_info_version | | | | | |
* +--------+--------------------+ | | * +--------+--------------------+ | | | | |
* | 152 | map_pages | | | * | 148 | padding | plat_root_complex +--|--|--|--|--+
* +--------+--------------------+ | | * +--------+--------------------+ | | | | | |
* | 160 | name | | | * | 152 | root_complex | | | | | | |
* +--------+--------------------+ consoles[0] | | * +--------+--------------------+ | | | | | |
* | 168 | clk_in_hz | | | * | 160 | checksum | | | | | | |
* +--------+--------------------+ | | * +--------+--------------------+--------------------+<-+ | | | |
* | 176 | baud_rate | | | * | 168 | base 0 | | | | | |
* +--------+--------------------+ | | * +--------+--------------------+ mem_bank[0] | | | | |
* | 184 | flags | | | * | 176 | size 0 | | | | | |
* +--------+--------------------+--------------------+<-------+ * +--------+--------------------+--------------------+ | | | |
* | 192 | base 0 | | * | 184 | base 1 | | | | | |
* +--------+--------------------+ ncoh_region[0] | * +--------+--------------------+ mem_bank[1] | | | | |
* | 200 | size 0 | | * | 192 | size 1 | | | | | |
* +--------+--------------------+--------------------+ * +--------+--------------------+--------------------+<----+ | | |
* | 208 | base 1 | | * | 200 | base | | | | |
* +--------+--------------------+ ncoh_region[1] | * +--------+--------------------+ | | | |
* | 216 | size 1 | | * | 208 | map_pages | | | | |
* +--------+--------------------+ | | | |
* | 216 | name | | | | |
* +--------+--------------------+ consoles[0] | | | |
* | 224 | clk_in_hz | | | | |
* +--------+--------------------+ | | | |
* | 232 | baud_rate | | | | |
* +--------+--------------------+ | | | |
* | 240 | flags | | | | |
* +--------+--------------------+--------------------+<-------+ | |
* | 248 | base 0 | | | |
* +--------+--------------------+ ncoh_region[0] | | |
* | 256 | size 0 | | | |
* +--------+--------------------+--------------------+ | |
* | 264 | base 1 | | | |
* +--------+--------------------+ ncoh_region[1] | | |
* | 272 | size 1 | | | |
* +--------+--------------------+--------------------+<----------+ |
* | 280 | smmu_base | | |
* +--------+--------------------+ smmus[0] | |
* | 288 | smmu_r_base | | |
* +--------+--------------------+--------------------+<-------------+
* | 296 | ecam_base | |
* +--------+--------------------+ |
* | 304 | segment | |
* +--------+--------------------+ |
* | 305 | padding | root_complex[0] +--+
* +--------+--------------------+ | |
* | 308 | num_root_ports | | |
* +--------+--------------------+ | |
* | 312 | root_ports | | |
* +--------+--------------------+--------------------+<-+
* | 320 | root_port_id | |
* +--------+--------------------+ |
* | 322 | padding | |
* +--------+--------------------+ root_ports[0] +--+
* | 324 | num_bdf_mappings | | |
* +--------+--------------------+ | |
* | 328 | bdf_mappings | | |
* +--------+--------------------+--------------------+<-+
* | 336 | mapping_base | |
* +--------+--------------------+ |
* | 338 | mapping_top | |
* +--------+--------------------+ bdf_mappings[0] |
* | 340 | mapping_off | |
* +--------+--------------------+ |
* | 342 | smmu_idx | |
* +--------+--------------------+--------------------+ * +--------+--------------------+--------------------+
*/ */
int plat_rmmd_load_manifest(struct rmm_manifest *manifest) int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
{ {
uint64_t checksum, num_banks, num_consoles; uint64_t checksum, num_banks, num_consoles;
uint64_t num_ncoh_regions, num_coh_regions; uint64_t num_ncoh_regions, num_coh_regions;
struct memory_bank *bank_ptr, *ncoh_region_ptr; uint64_t num_smmus, num_root_complex;
unsigned int num_root_ports, num_bdf_mappings;
uint32_t o_realm;
struct memory_bank *bank_ptr, *ncoh_region_ptr, *coh_region_ptr;
struct console_info *console_ptr; struct console_info *console_ptr;
struct smmu_info *smmu_ptr;
struct root_complex_info *root_complex_ptr, *rc_ptr;
struct root_port_info *root_port_ptr, *rp_ptr;
struct bdf_mapping_info *bdf_mapping_ptr, *bdf_ptr;
assert(manifest != NULL); assert(manifest != NULL);
@ -678,12 +776,36 @@ int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
/* Set number of device non-coherent address ranges based on DT */ /* Set number of device non-coherent address ranges based on DT */
num_ncoh_regions = FCONF_GET_PROPERTY(hw_config, pci_props, num_ncoh_regions); num_ncoh_regions = FCONF_GET_PROPERTY(hw_config, pci_props, num_ncoh_regions);
/* Set number of SMMUs */
num_smmus = FVP_RMM_SMMU_COUNT;
/* Set number of PCIe root complexes */
num_root_complex = FVP_RMM_RC_COUNT;
/* Calculate and set number of all PCIe root ports and BDF mappings */
num_root_ports = 0U;
num_bdf_mappings = 0U;
/* Scan all root complex entries */
for (unsigned long i = 0UL; i < num_root_complex; i++) {
num_root_ports += rc_data[i].num_root_ports;
/* Scan all root ports entries in root complex */
for (unsigned int j = 0U; j < rc_data[i].num_root_ports; j++) {
num_bdf_mappings += rc_data[i].root_ports[j].num_bdf_mappings;
}
}
manifest->version = RMMD_MANIFEST_VERSION; manifest->version = RMMD_MANIFEST_VERSION;
manifest->padding = 0U; /* RES0 */ manifest->padding = 0U; /* RES0 */
manifest->plat_data = 0UL; manifest->plat_data = 0UL;
manifest->plat_dram.num_banks = num_banks; manifest->plat_dram.num_banks = num_banks;
manifest->plat_console.num_consoles = num_consoles; manifest->plat_console.num_consoles = num_consoles;
manifest->plat_ncoh_region.num_banks = num_ncoh_regions; manifest->plat_ncoh_region.num_banks = num_ncoh_regions;
manifest->plat_smmu.num_smmus = num_smmus;
manifest->plat_root_complex.num_root_complex = num_root_complex;
manifest->plat_root_complex.rc_info_version = PCIE_RC_INFO_VERSION;
manifest->plat_root_complex.padding = 0U; /* RES0 */
/* FVP does not support device coherent address ranges */ /* FVP does not support device coherent address ranges */
num_coh_regions = 0UL; num_coh_regions = 0UL;
@ -699,9 +821,27 @@ int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
ncoh_region_ptr = (struct memory_bank *) ncoh_region_ptr = (struct memory_bank *)
((uintptr_t)console_ptr + (num_consoles * ((uintptr_t)console_ptr + (num_consoles *
sizeof(struct console_info))); sizeof(struct console_info)));
coh_region_ptr = (struct memory_bank *)
((uintptr_t)ncoh_region_ptr + (num_ncoh_regions *
sizeof(struct memory_bank)));
smmu_ptr = (struct smmu_info *)
((uintptr_t)coh_region_ptr + (num_coh_regions *
sizeof(struct memory_bank)));
root_complex_ptr = (struct root_complex_info *)
((uintptr_t)smmu_ptr + (num_smmus *
sizeof(struct smmu_info)));
root_port_ptr = (struct root_port_info *)
((uintptr_t)root_complex_ptr + (num_root_complex *
sizeof(struct root_complex_info)));
bdf_mapping_ptr = (struct bdf_mapping_info *)
((uintptr_t)root_port_ptr + (num_root_ports *
sizeof(struct root_port_info)));
manifest->plat_dram.banks = bank_ptr; manifest->plat_dram.banks = bank_ptr;
manifest->plat_console.consoles = console_ptr; manifest->plat_console.consoles = console_ptr;
manifest->plat_ncoh_region.banks = ncoh_region_ptr; manifest->plat_ncoh_region.banks = ncoh_region_ptr;
manifest->plat_smmu.smmus = smmu_ptr;
manifest->plat_root_complex.root_complex = root_complex_ptr;
/* Ensure the manifest is not larger than the shared buffer */ /* Ensure the manifest is not larger than the shared buffer */
assert((sizeof(struct rmm_manifest) + assert((sizeof(struct rmm_manifest) +
@ -712,7 +852,13 @@ int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
(sizeof(struct memory_bank) * (sizeof(struct memory_bank) *
manifest->plat_ncoh_region.num_banks) + manifest->plat_ncoh_region.num_banks) +
(sizeof(struct memory_bank) * (sizeof(struct memory_bank) *
manifest->plat_coh_region.num_banks)) manifest->plat_coh_region.num_banks) +
(sizeof(struct smmu_info) *
manifest->plat_smmu.num_smmus) +
(sizeof(struct root_complex_info) *
manifest->plat_root_complex.num_root_complex) +
(sizeof(struct root_port_info) * num_root_ports) +
(sizeof(struct bdf_mapping_info) * num_bdf_mappings))
<= ARM_EL3_RMM_SHARED_SIZE); <= ARM_EL3_RMM_SHARED_SIZE);
/* Calculate checksum of plat_dram structure */ /* Calculate checksum of plat_dram structure */
@ -775,6 +921,87 @@ int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
/* Checksum must be 0 */ /* Checksum must be 0 */
manifest->plat_ncoh_region.checksum = ~checksum + 1UL; manifest->plat_ncoh_region.checksum = ~checksum + 1UL;
/* Calculate the checksum of the plat_smmu structure */
checksum = num_smmus + (uint64_t)smmu_ptr;
smmu_ptr[0].smmu_base = FVP_RMM_SMMU_BASE;
/* Read SMMU_ROOT_IDR0.BA_REALM[31:22] register field */
o_realm = mmio_read_32(FVP_RMM_SMMU_BASE + SMMU_ROOT_IDR0) &
SMMU_ROOT_IDR0_BA_REALM_MASK;
/*
* Calculate the base address offset of Realm Register Page 0.
* O_REALM = 0x20000 + (BA_REALM * 0x10000)
* SMMU_REALM_BASE = SMMU_PAGE_0_BASE + O_REALM
*/
o_realm = 0x20000 + (o_realm >> (SMMU_ROOT_IDR0_BA_REALM_SHIFT - 16U));
smmu_ptr[0].smmu_r_base = FVP_RMM_SMMU_BASE + o_realm;
/* Update checksum */
checksum += checksum_calc((uint64_t *)smmu_ptr,
sizeof(struct smmu_info) * num_smmus);
/* Checksum must be 0 */
manifest->plat_smmu.checksum = ~checksum + 1UL;
/* Calculate the checksum of the plat_root_complex structure */
checksum = num_root_complex + (uint64_t)root_complex_ptr;
/* Zero out PCIe root complex info structures */
(void)memset((void *)root_complex_ptr, 0,
sizeof(struct root_complex_info) * num_root_complex);
/* Set pointers for data in manifest */
rc_ptr = root_complex_ptr;
rp_ptr = root_port_ptr;
bdf_ptr = bdf_mapping_ptr;
/* Fill PCIe root complex info structures */
for (unsigned long i = 0U; i < num_root_complex; i++) {
const struct root_complex_info *rc_info = &rc_data[i];
const struct root_port_info *rp_info = rc_info->root_ports;
/* Copy root complex data, except root_ports pointer */
(void)memcpy((void *)rc_ptr, (void *)rc_info,
sizeof(struct root_complex_info) - sizeof(struct root_port_info *));
/* Set root_ports for root complex */
rc_ptr->root_ports = rp_ptr;
/* Scan root ports */
for (unsigned int j = 0U; j < rc_ptr->num_root_ports; j++) {
const struct bdf_mapping_info *bdf_info = rp_info->bdf_mappings;
/* Copy root port data, except bdf_mappings pointer */
(void)memcpy((void *)rp_ptr, (void *)rp_info,
sizeof(struct root_port_info) - sizeof(struct bdf_mapping_info *));
/* Set bdf_mappings for root port */
rp_ptr->bdf_mappings = bdf_ptr;
/* Copy all BDF mappings for root port */
(void)memcpy((void *)bdf_ptr, (void *)bdf_info,
sizeof(struct bdf_mapping_info) * rp_ptr->num_bdf_mappings);
bdf_ptr += rp_ptr->num_bdf_mappings;
rp_ptr++;
rp_info++;
}
rc_ptr++;
}
/* Check that all data are written in manifest */
assert(rc_ptr == (root_complex_ptr + num_root_complex));
assert(rp_ptr == (root_port_ptr + num_root_ports));
assert(bdf_ptr == (bdf_mapping_ptr + num_bdf_mappings));
/* Update checksum for all PCIe data */
checksum += checksum_calc((uint64_t *)root_complex_ptr,
(uintptr_t)bdf_ptr - (uintptr_t)root_complex_ptr);
/* Checksum must be 0 */
manifest->plat_root_complex.checksum = ~checksum + 1UL;
return 0; return 0;
} }
@ -789,4 +1016,4 @@ int plat_rmmd_mecid_key_update(uint16_t mecid)
*/ */
return 0; return 0;
} }
#endif /* ENABLE_RME */ #endif /* ENABLE_RME */