feat(rme): add SMMU and PCIe information to Boot manifest

- Define information structures for SMMU, root complex,
  root port and BDF mappings.
- Add entries for SMMU and PCIe root complexes to Boot manifest.
- Update RMMD_MANIFEST_VERSION_MINOR from 4 to 5.

Change-Id: I0a76dc18edbaaff40116f376aeb56c750d57c7c1
Signed-off-by: AlexeiFedorov <Alexei.Fedorov@arm.com>
This commit is contained in:
AlexeiFedorov 2025-01-30 14:56:47 +00:00
parent 38b5f93a2b
commit 90552c612e
5 changed files with 572 additions and 103 deletions

View file

@ -768,47 +768,53 @@ _____
RMM-EL3 Boot Manifest structure
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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 RMM-EL3 Boot Manifest v0.5 structure contains platform boot information passed
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
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 | 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 |
+--------------------+--------+-------------------+----------------------------------------------+
+-------------------+--------+-------------------+----------------------------------------------+
| Name | Offset | Type | Description |
+===================+========+===================+==============================================+
| version | 0 | uint32_t | Boot Manifest version |
+-------------------+--------+-------------------+----------------------------------------------+
| padding | 4 | uint32_t | Reserved, set to 0 |
+-------------------+--------+-------------------+----------------------------------------------+
| plat_data | 8 | uint64_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 |
+-------------------+--------+-------------------+----------------------------------------------+
| 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 structure
~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~
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 memory banks/device regions |
+-----------+--------+----------------+----------------------------------------+
| banks | 8 | memory_bank * | Pointer to 'memory_bank'[] array |
+-----------+--------+----------------+----------------------------------------+
| checksum | 16 | uint64_t | Checksum |
+-----------+--------+----------------+----------------------------------------+
+-----------+--------+---------------+----------------------------------------+
| Name | Offset | Type | Description |
+===========+========+===============+========================================+
| num_banks | 0 | uint64_t | Number of memory banks/device regions |
+-----------+--------+---------------+----------------------------------------+
| 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 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:
+-----------+--------+----------------+--------------------------------------------+
| Name | Offset | Type | Description |
+===========+========+================+============================================+
| base | 0 | uintptr_t | Base address |
+-----------+--------+----------------+--------------------------------------------+
| size | 8 | uint64_t | Size of memory bank/device region in bytes |
+-----------+--------+----------------+--------------------------------------------+
+------+--------+----------+--------------------------------------------+
| Name | Offset | Type | Description |
+======+========+==========+============================================+
| base | 0 | uint64_t | Base address |
+------+--------+----------+--------------------------------------------+
| size | 8 | uint64_t | Size of memory bank/device region in bytes |
+------+--------+----------+--------------------------------------------+
.. _console_list_struct:
@ -836,15 +842,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.
@ -856,21 +862,144 @@ 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[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) |
+-----------+--------+---------------+-----------------------------------------+
+-----------+--------+----------+--------------------------------------+
| Name | Offset | Type | Description |
+===========+========+==========+======================================+
| base | 0 | uint64_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) |
+-----------+--------+----------+--------------------------------------+
.. _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:

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
*/
@ -58,6 +58,8 @@
/* SMMU_ROOT_IDR0 register fields */
#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 */
#define SMMU_ROOT_CR0_GPCEN (1UL << 1)

View file

@ -14,20 +14,21 @@
#include <lib/cassert.h>
#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)
/*
* Manifest version encoding:
* Version encoding:
* - Bit[31] RES0
* - Bits [30:16] Major version
* - Bits [15:0] Minor version
*/
#define SET_RMMD_MANIFEST_VERSION(_major, _minor) \
#define SET_VERSION(_major, _minor) \
((((_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_MINOR)
@ -37,9 +38,17 @@
#define RMMD_GET_MANIFEST_VERSION_MINOR(_version) \
(_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 */
struct memory_bank {
uintptr_t base; /* Base address */
uint64_t base; /* Base address */
uint64_t size; /* Size of memory bank/device region */
};
@ -64,7 +73,7 @@ CASSERT(offsetof(struct memory_info, checksum) == 16UL,
/* Console info structure */
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 */
char name[RMM_CONSOLE_MAX_NAME_LEN]; /* Name of 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,
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 {
uint32_t version; /* Manifest version */
uint32_t padding; /* RES0 */
uintptr_t plat_data; /* Manifest platform data */
uint64_t plat_data; /* Manifest platform data */
/* Platform NS DRAM data (v0.2) */
struct memory_info plat_dram;
/* Platform console list (v0.3) */
@ -110,6 +213,10 @@ struct rmm_manifest {
/* Platform device address ranges (v0.4) */
struct memory_info plat_ncoh_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,
@ -124,5 +231,9 @@ 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);
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 */

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++) {
int err = fdt_get_reg_props_by_index(
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);
if (err < 0) {
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/gicv2.h>
#include <drivers/arm/sp804_delay_timer.h>
#include <drivers/arm/smmu_v3.h>
#include <drivers/generic_delay_timer.h>
#include <fconf_hw_config_getter.h>
#include <lib/mmio.h>
@ -43,6 +44,15 @@
#define FVP_RMM_CONSOLE_NAME "pl011"
#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
* 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
/* 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
* through the pointer passed as parameter.
@ -593,14 +638,14 @@ static uint64_t checksum_calc(uint64_t *buffer, size_t size)
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
* non-coherent address ranges.
*
* +--------------------------------------------------+
* | offset | field | comment |
* +--------+--------------------+--------------------+
* | 0 | version | 0x00000004 |
* | 0 | version | 0x00000005 |
* +--------+--------------------+--------------------+
* | 4 | padding | 0x00000000 |
* +--------+--------------------+--------------------+
@ -629,42 +674,95 @@ static uint64_t checksum_calc(uint64_t *buffer, size_t size)
* | 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 | |
* +--------+--------------------+--------------------+ | | |
* | 112 | num_smmus | | | | |
* +--------+--------------------+ | | | |
* | 120 | smmus | plat_smmu +--|--|--|--+
* +--------+--------------------+ | | | | |
* | 128 | checksum | | | | | |
* +--------+--------------------+--------------------+ | | | |
* | 136 | num_root_complex | | | | | |
* +--------+--------------------+ | | | | |
* | 144 | rc_info_version | | | | | |
* +--------+--------------------+ | | | | |
* | 148 | padding | plat_root_complex +--|--|--|--|--+
* +--------+--------------------+ | | | | | |
* | 152 | root_complex | | | | | | |
* +--------+--------------------+ | | | | | |
* | 160 | checksum | | | | | | |
* +--------+--------------------+--------------------+<-+ | | | |
* | 168 | base 0 | | | | | |
* +--------+--------------------+ mem_bank[0] | | | | |
* | 176 | size 0 | | | | | |
* +--------+--------------------+--------------------+ | | | |
* | 184 | base 1 | | | | | |
* +--------+--------------------+ mem_bank[1] | | | | |
* | 192 | size 1 | | | | | |
* +--------+--------------------+--------------------+<----+ | | |
* | 200 | base | | | | |
* +--------+--------------------+ | | | |
* | 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)
{
uint64_t checksum, num_banks, num_consoles;
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 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);
@ -678,12 +776,36 @@ int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
/* Set number of device non-coherent address ranges based on DT */
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->padding = 0U; /* RES0 */
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;
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 */
num_coh_regions = 0UL;
@ -699,9 +821,27 @@ int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
ncoh_region_ptr = (struct memory_bank *)
((uintptr_t)console_ptr + (num_consoles *
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_console.consoles = console_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 */
assert((sizeof(struct rmm_manifest) +
@ -712,7 +852,13 @@ int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
(sizeof(struct memory_bank) *
manifest->plat_ncoh_region.num_banks) +
(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);
/* Calculate checksum of plat_dram structure */
@ -775,6 +921,87 @@ int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
/* Checksum must be 0 */
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;
}
@ -789,4 +1016,4 @@ int plat_rmmd_mecid_key_update(uint16_t mecid)
*/
return 0;
}
#endif /* ENABLE_RME */
#endif /* ENABLE_RME */