1 2Realm Management Extension (RME) 3==================================== 4 5FEAT_RME (or RME for short) is an Armv9-A extension and is one component of the 6`Arm Confidential Compute Architecture (Arm CCA)`_. TF-A supports RME starting 7from version 2.6. This chapter discusses the changes to TF-A to support RME and 8provides instructions on how to build and run TF-A with RME. 9 10RME support in TF-A 11--------------------- 12 13The following diagram shows an Arm CCA software architecture with TF-A as the 14EL3 firmware. In the Arm CCA architecture there are two additional security 15states and address spaces: ``Root`` and ``Realm``. TF-A firmware runs in the 16Root world. In the realm world, a Realm Management Monitor firmware (RMM) 17manages the execution of Realm VMs and their interaction with the hypervisor. 18 19.. image:: ../resources/diagrams/arm-cca-software-arch.png 20 21RME is the hardware extension to support Arm CCA. To support RME, various 22changes have been introduced to TF-A. We discuss those changes below. 23 24Changes to translation tables library 25*************************************** 26RME adds Root and Realm Physical address spaces. To support this, two new 27memory type macros, ``MT_ROOT`` and ``MT_REALM``, have been added to the 28:ref:`Translation (XLAT) Tables Library`. These macros are used to configure 29memory regions as Root or Realm respectively. 30 31.. note:: 32 33 Only version 2 of the translation tables library supports the new memory 34 types. 35 36Changes to context management 37******************************* 38A new CPU context for the Realm world has been added. The existing 39:ref:`CPU context management API<PSCI Library Integration guide for Armv8-A 40AArch32 systems>` can be used to manage Realm context. 41 42Boot flow changes 43******************* 44In a typical TF-A boot flow, BL2 runs at Secure-EL1. However when RME is 45enabled, TF-A runs in the Root world at EL3. Therefore, the boot flow is 46modified to run BL2 at EL3 when RME is enabled. In addition to this, a 47Realm-world firmware (RMM) is loaded by BL2 in the Realm physical address 48space. 49 50The boot flow when RME is enabled looks like the following: 51 521. BL1 loads and executes BL2 at EL3 532. BL2 loads images including RMM 543. BL2 transfers control to BL31 554. BL31 initializes SPM (if SPM is enabled) 565. BL31 initializes RMM 576. BL31 transfers control to Normal-world software 58 59Granule Protection Tables (GPT) library 60***************************************** 61Isolation between the four physical address spaces is enforced by a process 62called Granule Protection Check (GPC) performed by the MMU downstream any 63address translation. GPC makes use of Granule Protection Table (GPT) in the 64Root world that describes the physical address space assignment of every 65page (granule). A GPT library that provides APIs to initialize GPTs and to 66transition granules between different physical address spaces has been added. 67More information about the GPT library can be found in the 68:ref:`Granule Protection Tables Library` chapter. 69 70RMM Dispatcher (RMMD) 71************************ 72RMMD is a new standard runtime service that handles the switch to the Realm 73world. It initializes the RMM and handles Realm Management Interface (RMI) 74SMC calls from Non-secure and Realm worlds. 75 76There is a contract between RMM and RMMD that defines the arguments that the 77former needs to take in order to initialize and also the possible return values. 78This contract is defined in the RMM Boot Interface, which can be found at 79:ref:`rmm_el3_boot_interface`. 80 81There is also a specification of the runtime services provided by TF-A 82to RMM. This can be found at :ref:`runtime_services_and_interface`. 83 84Test Realm Payload (TRP) 85************************* 86TRP is a small test payload that runs at R-EL2 and implements a subset of 87the Realm Management Interface (RMI) commands to primarily test EL3 firmware 88and the interface between R-EL2 and EL3. When building TF-A with RME enabled, 89if a path to an RMM image is not provided, TF-A builds the TRP by default 90and uses it as RMM image. 91 92Building and running TF-A with RME 93------------------------------------ 94 95This section describes how you can build and run TF-A with RME enabled. 96We assume you have all the :ref:`Prerequisites` to build TF-A. 97 98The following instructions show you how to build and run TF-A with RME 99for two scenarios: 100 101- Three-world execution: TF-A with TF-A Tests or Linux. 102 103 - NS (TF-A Test or Linux), 104 - Root (TF-A) 105 - Realm (RMM or TRP) 106 107- Four-world execution: TF-A, Hafnium and TF-A Tests or Linux. 108 109 - NS (TF-A Test or Linux), 110 - Root (TF-A) 111 - Realm (RMM or TRP) 112 - SPM (Hafnium) 113 114To run the tests, you need an FVP model. Please use the :ref:`latest version 115<Arm Fixed Virtual Platforms (FVP)>` of *FVP_Base_RevC-2xAEMvA* model. 116 117Three World Testing with TF-A Tests 118************************************* 119 120**1. Obtain and build TF-A Tests with Realm Payload** 121 122The full set of instructions to setup build host and build options for 123TF-A-Tests can be found in the `TFTF Getting Started`_. 124 125Use the following instructions to build TF-A with `TF-A Tests`_ as the 126non-secure payload (BL33). 127 128.. code:: shell 129 130 git clone https://git.trustedfirmware.org/TF-A/tf-a-tests.git 131 cd tf-a-tests 132 make CROSS_COMPILE=aarch64-none-elf- PLAT=fvp DEBUG=1 all pack_realm 133 134This produces a TF-A Tests binary (**tftf.bin**) with Realm payload packaged 135and **sp_layout.json** in the **build/fvp/debug** directory. 136 137**2. Obtain and build RMM Image** 138 139Please refer to the `RMM Getting Started`_ on how to setup 140Host Environment and build RMM. 141 142The below command shows how to build RMM using the default build options for FVP. 143 144.. code:: shell 145 146 git clone --recursive https://git.trustedfirmware.org/TF-RMM/tf-rmm.git 147 cd tf-rmm 148 cmake -DRMM_CONFIG=fvp_defcfg -S . -B build 149 cmake --build build 150 151This will generate **rmm.img** in **build** folder. 152 153**3. Build TF-A** 154 155The `TF-A Getting Started`_ has the necessary instructions to setup Host 156machine and build TF-A. 157 158To build for RME, set ``ENABLE_RME`` build option to 1 and provide the path to 159the RMM binary using the ``RMM`` build option. 160Currently, this feature is only supported for the FVP platform. 161 162.. note:: 163 164 ENABLE_RME build option is currently experimental. 165 166If the ``RMM`` option is not used, then the Test Realm Payload (TRP) in TF-A 167will be built and used as the RMM. 168 169.. code:: shell 170 171 git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git 172 cd trusted-firmware-a 173 make CROSS_COMPILE=aarch64-none-elf- \ 174 PLAT=fvp \ 175 ENABLE_RME=1 \ 176 RMM=<path/to/rmm.img> \ 177 FVP_HW_CONFIG_DTS=fdts/fvp-base-gicv3-psci-1t.dts \ 178 DEBUG=1 \ 179 BL33=<path/to/tftf.bin> \ 180 all fip 181 182This produces **bl1.bin** and **fip.bin** binaries in the **build/fvp/debug** directory. 183 184Running the tests for a 3 world FVP setup 185^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 186 187Use the following command to run the tests on FVP. TF-A Tests should boot 188and run the default tests including Realm world tests. 189 190.. code:: shell 191 192 FVP_Base_RevC-2xAEMvA \ 193 -C bp.refcounter.non_arch_start_at_default=1 \ 194 -C bp.secureflashloader.fname=<path/to/bl1.bin> \ 195 -C bp.flashloader0.fname=<path/to/fip.bin> \ 196 -C bp.refcounter.use_real_time=0 \ 197 -C bp.ve_sysregs.exit_on_shutdown=1 \ 198 -C cache_state_modelled=1 \ 199 -C bp.dram_size=2 \ 200 -C bp.secure_memory=1 \ 201 -C pci.pci_smmuv3.mmu.SMMU_ROOT_IDR0=3 \ 202 -C pci.pci_smmuv3.mmu.SMMU_ROOT_IIDR=0x43B \ 203 -C pci.pci_smmuv3.mmu.root_register_page_offset=0x20000 \ 204 -C cluster0.NUM_CORES=4 \ 205 -C cluster0.PA_SIZE=48 \ 206 -C cluster0.ecv_support_level=2 \ 207 -C cluster0.gicv3.cpuintf-mmap-access-level=2 \ 208 -C cluster0.gicv3.without-DS-support=1 \ 209 -C cluster0.gicv4.mask-virtual-interrupt=1 \ 210 -C cluster0.has_arm_v8-6=1 \ 211 -C cluster0.has_amu=1 \ 212 -C cluster0.has_branch_target_exception=1 \ 213 -C cluster0.rme_support_level=2 \ 214 -C cluster0.has_rndr=1 \ 215 -C cluster0.has_v8_7_pmu_extension=2 \ 216 -C cluster0.max_32bit_el=-1 \ 217 -C cluster0.stage12_tlb_size=1024 \ 218 -C cluster0.check_memory_attributes=0 \ 219 -C cluster0.ish_is_osh=1 \ 220 -C cluster0.restriction_on_speculative_execution=2 \ 221 -C cluster0.restriction_on_speculative_execution_aarch32=2 \ 222 -C cluster1.NUM_CORES=4 \ 223 -C cluster1.PA_SIZE=48 \ 224 -C cluster1.ecv_support_level=2 \ 225 -C cluster1.gicv3.cpuintf-mmap-access-level=2 \ 226 -C cluster1.gicv3.without-DS-support=1 \ 227 -C cluster1.gicv4.mask-virtual-interrupt=1 \ 228 -C cluster1.has_arm_v8-6=1 \ 229 -C cluster1.has_amu=1 \ 230 -C cluster1.has_branch_target_exception=1 \ 231 -C cluster1.rme_support_level=2 \ 232 -C cluster1.has_rndr=1 \ 233 -C cluster1.has_v8_7_pmu_extension=2 \ 234 -C cluster1.max_32bit_el=-1 \ 235 -C cluster1.stage12_tlb_size=1024 \ 236 -C cluster1.check_memory_attributes=0 \ 237 -C cluster1.ish_is_osh=1 \ 238 -C cluster1.restriction_on_speculative_execution=2 \ 239 -C cluster1.restriction_on_speculative_execution_aarch32=2 \ 240 -C pctl.startup=0.0.0.0 \ 241 -C bp.smsc_91c111.enabled=1 \ 242 -C bp.hostbridge.userNetworking=1 243 244The bottom of the output from *uart0* should look something like the following. 245 246.. code-block:: shell 247 248 ... 249 250 > Test suite 'FF-A Interrupt' 251 Passed 252 > Test suite 'SMMUv3 tests' 253 Passed 254 > Test suite 'PMU Leakage' 255 Passed 256 > Test suite 'DebugFS' 257 Passed 258 > Test suite 'RMI and SPM tests' 259 Passed 260 > Test suite 'Realm payload at EL1' 261 Passed 262 > Test suite 'Invalid memory access' 263 Passed 264 ... 265 266Building TF-A with RME enabled Linux Kernel 267^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 268 269If an RME enabled Linux kernel and filesystem is available for testing, 270and a suitable NS boot loader is not available, then this option can be used to 271launch kernel directly after BL31: 272 273.. code-block:: shell 274 275 cd trusted-firmware-a 276 make CROSS_COMPILE=aarch64-none-elf- \ 277 PLAT=fvp \ 278 ENABLE_RME=1 \ 279 RMM=<path/to/rmm.img> \ 280 FVP_HW_CONFIG_DTS=fdts/fvp-base-gicv3-psci-1t.dts \ 281 DEBUG=1 \ 282 ARM_LINUX_KERNEL_AS_BL33=1 \ 283 PRELOADED_BL33_BASE=0x84000000 \ 284 all fip 285 286Boot and run the RME enabled Linux Kernel 287^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 288 289Use the following additional arguments to boot the kernel on FVP. 290 291.. code-block:: shell 292 293 --data cluster0.cpu0=<path_to_kernel_Image>@0x84000000 \ 294 -C bp.virtioblockdevice.image_path=<path_to_rootfs.ext4> 295 296.. tip:: 297 298 Set the FVP option `cache_state_modelled=0` to run Linux based tests much faster. 299 300Four-world execution with Hafnium and TF-A Tests 301************************************************* 302 303Four-world execution involves software components in each security state: root, 304secure, realm and non-secure. This section describes how to build TF-A 305with four-world support. 306 307We use TF-A as the root firmware, `Hafnium SPM`_ is the reference Secure world component 308and the software components for the other 2 worlds (Realm and Non-Secure) 309are as described in the previous section. 310 311**1. Obtain and build Hafnium** 312 313.. code:: shell 314 315 git clone --recurse-submodules https://git.trustedfirmware.org/hafnium/hafnium.git 316 cd hafnium 317 # Use the default prebuilt LLVM/clang toolchain 318 PATH=$PWD/prebuilts/linux-x64/clang/bin:$PWD/prebuilts/linux-x64/dtc:$PATH 319 320Feature MTE needs to be disabled in Hafnium build, apply following patch to 321project/reference submodule 322 323.. code:: diff 324 325 diff --git a/BUILD.gn b/BUILD.gn 326 index cc6a78f..234b20a 100644 327 --- a/BUILD.gn 328 +++ b/BUILD.gn 329 @@ -83,7 +83,6 @@ aarch64_toolchains("secure_aem_v8a_fvp") { 330 pl011_base_address = "0x1c090000" 331 smmu_base_address = "0x2b400000" 332 smmu_memory_size = "0x100000" 333 - enable_mte = "1" 334 plat_log_level = "LOG_LEVEL_INFO" 335 } 336 } 337 338.. code:: shell 339 340 make PROJECT=reference 341 342The Hafnium binary should be located at 343*out/reference/secure_aem_v8a_fvp_clang/hafnium.bin* 344 345**2. Build TF-A** 346 347Build TF-A with RME as well as SPM enabled. 348 349Use sp_layout.json previously generated in tf-a-test build. 350 351.. code:: shell 352 353 make CROSS_COMPILE=aarch64-none-elf- \ 354 PLAT=fvp \ 355 ENABLE_RME=1 \ 356 FVP_HW_CONFIG_DTS=fdts/fvp-base-gicv3-psci-1t.dts \ 357 SPD=spmd \ 358 SPMD_SPM_AT_SEL2=1 \ 359 BRANCH_PROTECTION=1 \ 360 CTX_INCLUDE_PAUTH_REGS=1 \ 361 DEBUG=1 \ 362 SP_LAYOUT_FILE=<path/to/sp_layout.json> \ 363 BL32=<path/to/hafnium.bin> \ 364 BL33=<path/to/tftf.bin> \ 365 RMM=<path/to/rmm.img> \ 366 all fip 367 368Running the tests for a 4 world FVP setup 369^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 370 371Use the following arguments in addition to 372`Running the tests for a 3 world FVP setup`_ to run tests for 4 world setup. 373 374.. code:: shell 375 376 -C pci.pci_smmuv3.mmu.SMMU_AIDR=2 \ 377 -C pci.pci_smmuv3.mmu.SMMU_IDR0=0x0046123B \ 378 -C pci.pci_smmuv3.mmu.SMMU_IDR1=0x00600002 \ 379 -C pci.pci_smmuv3.mmu.SMMU_IDR3=0x1714 \ 380 -C pci.pci_smmuv3.mmu.SMMU_IDR5=0xFFFF0475 \ 381 -C pci.pci_smmuv3.mmu.SMMU_S_IDR1=0xA0000002 \ 382 -C pci.pci_smmuv3.mmu.SMMU_S_IDR2=0 \ 383 -C pci.pci_smmuv3.mmu.SMMU_S_IDR3=0 384 385.. _Arm Confidential Compute Architecture (Arm CCA): https://www.arm.com/why-arm/architecture/security-features/arm-confidential-compute-architecture 386.. _Arm Architecture Models website: https://developer.arm.com/tools-and-software/simulation-models/fixed-virtual-platforms/arm-ecosystem-models 387.. _TF-A Getting Started: https://trustedfirmware-a.readthedocs.io/en/latest/getting_started/index.html 388.. _TF-A Tests: https://trustedfirmware-a-tests.readthedocs.io/en/latest 389.. _TFTF Getting Started: https://trustedfirmware-a-tests.readthedocs.io/en/latest/getting_started/index.html 390.. _Hafnium SPM: https://www.trustedfirmware.org/projects/hafnium 391.. _RMM Getting Started: https://git.trustedfirmware.org/TF-RMM/tf-rmm.git/tree/docs/getting_started/index.rst 392