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.
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 the path to an RMM image is not provided, TF-A builds the TRP by default
90and uses it as the R-EL2 payload.
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 read the :ref:`Prerequisites` to build TF-A.
97
98The following instructions show you how to build and run TF-A with RME
99on FVP for two scenarios:
100
101- Three-world execution:  This is the configuration to use if Secure
102  world functionality is not needed. TF-A is tested with the following
103  software entities in each world as listed below:
104
105  - NS Host (RME capable Linux or TF-A Tests),
106  - Root (TF-A)
107  - R-EL2 (`RMM`_ or TRP)
108
109- Four-world execution: This is the configuration to use if both Secure
110  and Realm world functionality is needed. TF-A is tested with the following
111  software entities in each world as listed below:
112
113  - NS Host (RME capable Linux or TF-A Tests),
114  - Root (TF-A)
115  - R-EL2 (`RMM`_ or TRP)
116  - S-EL2 (Hafnium SPM)
117
118To run the tests, you need an FVP model. Please use the :ref:`latest version
119<Arm Fixed Virtual Platforms (FVP)>` of *FVP_Base_RevC-2xAEMvA* model. If NS
120Host is Linux, then the below instructions assume that a suitable RME enabled
121kernel image and associated root filesystem are available.
122
123Three-world execution
124*********************
125
126**1. Clone and build RMM Image**
127
128Please refer to the `RMM Getting Started`_ on how to setup
129Host Environment and build `RMM`_. The build commands assume that
130an AArch64 toolchain and CMake executable are available in the
131shell PATH variable and CROSS_COMPILE variable has been setup
132appropriately.
133
134To clone `RMM`_ and build using the default build options for FVP:
135
136.. code:: shell
137
138 git clone --recursive https://git.trustedfirmware.org/TF-RMM/tf-rmm.git
139 cd tf-rmm
140 cmake -DRMM_CONFIG=fvp_defcfg -S . -B build
141 cmake --build build
142
143This will generate **rmm.img** in **build/Release** folder.
144
145**2. Clone and build TF-A Tests with Realm Payload**
146
147This step is only needed if NS Host is TF-A Tests. The full set
148of instructions to setup build host and build options for
149TF-A-Tests can be found in the `TFTF Getting Started`_. TF-A Tests
150can test Realm world with either `RMM`_ or TRP in R-EL2. In the TRP case,
151some tests which are not applicable will be skipped.
152
153Use the following instructions to build TF-A with `TF-A Tests`_ as the
154non-secure payload (BL33).
155
156.. code:: shell
157
158 git clone https://git.trustedfirmware.org/TF-A/tf-a-tests.git
159 cd tf-a-tests
160 make CROSS_COMPILE=aarch64-none-elf- PLAT=fvp DEBUG=1 ENABLE_REALM_PAYLOAD_TESTS=1 all
161
162This produces a TF-A Tests binary (**tftf.bin**) with Realm payload packaged
163and **sp_layout.json** in the **build/fvp/debug** directory.
164
165
166**3. Build RME Enabled TF-A**
167
168The `TF-A Getting Started`_ has the necessary instructions to setup Host
169machine and build TF-A.
170
171To build for RME, set ``ENABLE_RME`` build option to 1 and provide the path to
172the `RMM`_ binary ``rmm.img`` using ``RMM`` build option.
173
174.. note::
175
176 ENABLE_RME build option is currently experimental.
177
178.. note::
179
180 If the ``RMM`` option is not specified, TF-A builds the TRP to load and
181 run at R-EL2.
182
183.. code:: shell
184
185 git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
186 cd trusted-firmware-a
187 make CROSS_COMPILE=aarch64-none-elf- \
188 PLAT=fvp \
189 ENABLE_RME=1 \
190 RMM=<path/to/rmm.img> \
191 FVP_HW_CONFIG_DTS=fdts/fvp-base-gicv3-psci-1t.dts \
192 DEBUG=1 \
193 BL33=<path/to/bl33> \
194 all fip
195
196``BL33`` can point to a Non Secure Bootloader like UEFI/U-Boot or
197the TF-A Tests binary(**tftf.bin**) from the previous step.
198
199This produces **bl1.bin** and **fip.bin** binaries in the **build/fvp/debug**
200directory.
201
202TF-A can also directly boot Linux kernel on the FVP. The kernel needs to be
203`preloaded` to a suitable memory location and this needs to be specified via
204``PRELOADED_BL33_BASE`` build option. Also TF-A should implement the Linux
205kernel register conventions for boot and this can be set using the
206``ARM_LINUX_KERNEL_AS_BL33`` option.
207
208.. code-block:: shell
209
210 cd trusted-firmware-a
211 make CROSS_COMPILE=aarch64-none-elf- \
212 PLAT=fvp \
213 ENABLE_RME=1 \
214 RMM=<path/to/rmm.img> \
215 FVP_HW_CONFIG_DTS=fdts/fvp-base-gicv3-psci-1t.dts \
216 DEBUG=1 \
217 ARM_LINUX_KERNEL_AS_BL33=1 \
218 PRELOADED_BL33_BASE=0x84000000 \
219 all fip
220
221The above command assumes that the Linux kernel will be placed in FVP
222memory at 0x84000000 via suitable FVP option (see the next step).
223
224.. _fvp_3_world_cmd:
225
226**4. Running FVP for 3 world setup**
227
228Use the following command to run the tests on FVP.
229
230.. code:: shell
231
232 FVP_Base_RevC-2xAEMvA                                          \
233 -C bp.refcounter.non_arch_start_at_default=1                   \
234 -C bp.secureflashloader.fname=<path/to/bl1.bin>                \
235 -C bp.flashloader0.fname=<path/to/fip.bin>                     \
236 -C bp.refcounter.use_real_time=0                               \
237 -C bp.ve_sysregs.exit_on_shutdown=1                            \
238 -C cache_state_modelled=1                                      \
239 -C bp.dram_size=4                                              \
240 -C bp.secure_memory=1                                          \
241 -C pci.pci_smmuv3.mmu.SMMU_ROOT_IDR0=3                         \
242 -C pci.pci_smmuv3.mmu.SMMU_ROOT_IIDR=0x43B                     \
243 -C pci.pci_smmuv3.mmu.root_register_page_offset=0x20000        \
244 -C cluster0.NUM_CORES=4                                        \
245 -C cluster0.PA_SIZE=48                                         \
246 -C cluster0.ecv_support_level=2                                \
247 -C cluster0.gicv3.cpuintf-mmap-access-level=2                  \
248 -C cluster0.gicv3.without-DS-support=1                         \
249 -C cluster0.gicv4.mask-virtual-interrupt=1                     \
250 -C cluster0.has_arm_v8-6=1                                     \
251 -C cluster0.has_amu=1                                          \
252 -C cluster0.has_branch_target_exception=1                      \
253 -C cluster0.rme_support_level=2                                \
254 -C cluster0.has_rndr=1                                         \
255 -C cluster0.has_v8_7_pmu_extension=2                           \
256 -C cluster0.max_32bit_el=-1                                    \
257 -C cluster0.stage12_tlb_size=1024                              \
258 -C cluster0.check_memory_attributes=0                          \
259 -C cluster0.ish_is_osh=1                                       \
260 -C cluster0.restriction_on_speculative_execution=2             \
261 -C cluster0.restriction_on_speculative_execution_aarch32=2     \
262 -C cluster1.NUM_CORES=4                                        \
263 -C cluster1.PA_SIZE=48                                         \
264 -C cluster1.ecv_support_level=2                                \
265 -C cluster1.gicv3.cpuintf-mmap-access-level=2                  \
266 -C cluster1.gicv3.without-DS-support=1                         \
267 -C cluster1.gicv4.mask-virtual-interrupt=1                     \
268 -C cluster1.has_arm_v8-6=1                                     \
269 -C cluster1.has_amu=1                                          \
270 -C cluster1.has_branch_target_exception=1                      \
271 -C cluster1.rme_support_level=2                                \
272 -C cluster1.has_rndr=1                                         \
273 -C cluster1.has_v8_7_pmu_extension=2                           \
274 -C cluster1.max_32bit_el=-1                                    \
275 -C cluster1.stage12_tlb_size=1024                              \
276 -C cluster1.check_memory_attributes=0                          \
277 -C cluster1.ish_is_osh=1                                       \
278 -C cluster1.restriction_on_speculative_execution=2             \
279 -C cluster1.restriction_on_speculative_execution_aarch32=2     \
280 -C pctl.startup=0.0.0.0                                        \
281 -C bp.smsc_91c111.enabled=1                                    \
282 -C bp.hostbridge.userNetworking=1                              \
283 -C bp.virtioblockdevice.image_path=<path/to/rootfs.ext4>
284
285The ``bp.virtioblockdevice.image_path`` option presents the rootfs as a
286virtio block device to Linux kernel. It can be ignored if NS Host is
287TF-A-Tests or rootfs is accessed by some other mechanism.
288
289If TF-A was built to expect a preloaded Linux kernel, then use the following
290FVP argument to load the kernel image at the expected address.
291
292.. code-block:: shell
293
294 --data cluster0.cpu0=<path_to_kernel_Image>@0x84000000         \
295
296
297.. tip::
298 Tips to boot and run Linux faster on the FVP :
299  1. Set the FVP option ``cache_state_modelled`` to 0.
300  2. Disable the CPU Idle driver in Linux either by setting the kernel command line
301     parameter "cpuidle.off=1" or by disabling the ``CONFIG_CPU_IDLE`` kernel config.
302
303If the NS Host is TF-A-Tests, then the default test suite in TFTF
304will execute on the FVP and this includes Realm world tests. The
305tail of the output from *uart0* should look something like the following.
306
307.. code-block:: shell
308
309 ...
310
311 > Test suite 'FF-A Interrupt'
312                                                                Passed
313 > Test suite 'SMMUv3 tests'
314                                                                Passed
315 > Test suite 'PMU Leakage'
316                                                                Passed
317 > Test suite 'DebugFS'
318                                                                Passed
319 > Test suite 'RMI and SPM tests'
320                                                                Passed
321 > Test suite 'Realm payload at EL1'
322                                                                Passed
323 > Test suite 'Invalid memory access'
324                                                                Passed
325 ...
326
327Four-world execution
328********************
329
330Four-world execution involves software components in each security state: root,
331secure, realm and non-secure. This section describes how to build TF-A
332with four-world support.
333
334We use TF-A as the root firmware, `Hafnium SPM`_ is the reference Secure world
335component running at S-EL2. `RMM`_ can be built as described in previous
336section. The examples below assume TF-A-Tests as the NS Host and utilize SPs
337from TF-A-Tests.
338
339**1. Obtain and build Hafnium SPM**
340
341.. code:: shell
342
343 git clone --recurse-submodules https://git.trustedfirmware.org/hafnium/hafnium.git
344 cd hafnium
345 #  Use the default prebuilt LLVM/clang toolchain
346 PATH=$PWD/prebuilts/linux-x64/clang/bin:$PWD/prebuilts/linux-x64/dtc:$PATH
347
348Feature MTE needs to be disabled in Hafnium build, apply following patch to
349project/reference submodule
350
351.. code:: diff
352
353 diff --git a/BUILD.gn b/BUILD.gn
354 index cc6a78f..234b20a 100644
355 --- a/BUILD.gn
356 +++ b/BUILD.gn
357 @@ -83,7 +83,6 @@ aarch64_toolchains("secure_aem_v8a_fvp") {
358     pl011_base_address = "0x1c090000"
359     smmu_base_address = "0x2b400000"
360     smmu_memory_size = "0x100000"
361 -    enable_mte = "1"
362     plat_log_level = "LOG_LEVEL_INFO"
363   }
364 }
365
366.. code:: shell
367
368 make PROJECT=reference
369
370The Hafnium binary should be located at
371*out/reference/secure_aem_v8a_fvp_clang/hafnium.bin*
372
373**2. Build RME enabled TF-A with SPM**
374
375Build TF-A with RME as well as SPM enabled.
376
377Use the ``sp_layout.json`` previously generated in TF-A Tests
378build to run SP tests.
379
380.. code:: shell
381
382 make CROSS_COMPILE=aarch64-none-elf- \
383 PLAT=fvp \
384 ENABLE_RME=1 \
385 FVP_HW_CONFIG_DTS=fdts/fvp-base-gicv3-psci-1t.dts \
386 SPD=spmd \
387 BRANCH_PROTECTION=1 \
388 CTX_INCLUDE_PAUTH_REGS=1 \
389 DEBUG=1 \
390 SP_LAYOUT_FILE=<path/to/sp_layout.json> \
391 BL32=<path/to/hafnium.bin> \
392 BL33=<path/to/tftf.bin> \
393 RMM=<path/to/rmm.img> \
394 all fip
395
396**3. Running the FVP for a 4 world setup**
397
398Use the following arguments in addition to the FVP options mentioned in
399:ref:`4. Running FVP for 3 world setup <fvp_3_world_cmd>` to run tests for
4004 world setup.
401
402.. code:: shell
403
404 -C pci.pci_smmuv3.mmu.SMMU_AIDR=2              \
405 -C pci.pci_smmuv3.mmu.SMMU_IDR0=0x0046123B     \
406 -C pci.pci_smmuv3.mmu.SMMU_IDR1=0x00600002     \
407 -C pci.pci_smmuv3.mmu.SMMU_IDR3=0x1714         \
408 -C pci.pci_smmuv3.mmu.SMMU_IDR5=0xFFFF0475     \
409 -C pci.pci_smmuv3.mmu.SMMU_S_IDR1=0xA0000002   \
410 -C pci.pci_smmuv3.mmu.SMMU_S_IDR2=0            \
411 -C pci.pci_smmuv3.mmu.SMMU_S_IDR3=0
412
413.. _Arm Confidential Compute Architecture (Arm CCA): https://www.arm.com/why-arm/architecture/security-features/arm-confidential-compute-architecture
414.. _Arm Architecture Models website: https://developer.arm.com/tools-and-software/simulation-models/fixed-virtual-platforms/arm-ecosystem-models
415.. _TF-A Getting Started: https://trustedfirmware-a.readthedocs.io/en/latest/getting_started/index.html
416.. _TF-A Tests: https://trustedfirmware-a-tests.readthedocs.io/en/latest
417.. _TFTF Getting Started: https://trustedfirmware-a-tests.readthedocs.io/en/latest/getting_started/index.html
418.. _Hafnium SPM: https://www.trustedfirmware.org/projects/hafnium
419.. _RMM Getting Started: https://tf-rmm.readthedocs.io/en/latest/getting_started/index.html
420.. _RMM: https://www.trustedfirmware.org/projects/tf-rmm/
421