Jimmy Brisson | 0862f01 | 2020-04-02 15:19:12 -0500 | [diff] [blame] | 1 | Framework Design |
| 2 | ================ |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 3 | |
| 4 | This document provides some details about the internals of the TF-A Tests |
| 5 | design. It is incomplete at the moment. |
| 6 | |
Jimmy Brisson | 4844dc9 | 2020-04-02 15:19:34 -0500 | [diff] [blame] | 7 | .. _design_high_level_behaviour: |
| 8 | |
Jimmy Brisson | ff08d3e | 2020-04-02 15:19:27 -0500 | [diff] [blame] | 9 | High-Level Behaviour |
| 10 | -------------------- |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 11 | |
| 12 | The EL3 firmware is expected to hand over to the TF-A tests with all secondary |
| 13 | cores powered down, i.e. only the primary core should enter the TF-A tests. |
| 14 | |
| 15 | The primary CPU initialises the platform and the TF-A tests internal data |
| 16 | structures. |
| 17 | |
| 18 | Then the test session begins. The TF-A tests are executed one after the |
| 19 | other. Tests results are saved in non-volatile memory as we go along. |
| 20 | |
Sandrine Bailleux | 68d76a2 | 2018-11-07 16:31:23 +0100 | [diff] [blame] | 21 | Once all tests have completed, a report is printed over the serial console. |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 22 | |
| 23 | Global Code Structure |
| 24 | --------------------- |
| 25 | |
| 26 | The code is organised into the following categories (present as directories at |
| 27 | the top level or under the ``tftf/`` directory): |
| 28 | |
| 29 | - **Drivers.** |
| 30 | |
| 31 | Some examples follow, this list might not be exhaustive. |
| 32 | |
| 33 | - Generic GIC driver. |
| 34 | |
| 35 | ``arm_gic.h`` contains the public APIs that tests might use. Both GIC |
| 36 | architecture versions 2 and 3 are supported. |
| 37 | |
| 38 | - PL011 UART driver. |
| 39 | |
| 40 | - VExpress NOR flash driver. |
| 41 | |
| 42 | Note that tests are not expected to use this driver in most |
| 43 | cases. Instead, they should use the ``tftf_nvm_read()`` and |
| 44 | ``tftf_nvm_write()`` wrapper APIs. See definitions in |
| 45 | ``tftf/framework/include/nvm.h``. See also the NVM validation test cases |
| 46 | (``tftf/tests/framework_validation_tests/test_validation_nvm.c``) for an |
| 47 | example of usage of these functions. |
| 48 | |
| 49 | - SP805 watchdog. |
| 50 | |
| 51 | Used solely to generate an interrupt that will reset the system on purpose |
| 52 | (used in ``tftf_plat_reset()``). |
| 53 | |
| 54 | - SP804 timer. |
| 55 | |
| 56 | This is used as the system timer on Juno. It is configured such that an |
| 57 | interrupt is generated when it reaches 0. It is programmed in one-shot |
| 58 | mode, i.e. it must be rearmed every time it reaches 0. |
| 59 | |
| 60 | - **Framework.** |
| 61 | |
| 62 | Core features of the test framework. |
| 63 | |
| 64 | - **Library code.** |
| 65 | |
Ambroise Vincent | d6e806d | 2019-02-11 14:34:26 +0000 | [diff] [blame] | 66 | Firstly, there is ``include/libc/`` which provides standard C library |
John Tsichritzis | 4586e0d | 2018-10-18 10:00:28 +0100 | [diff] [blame] | 67 | functions like ``memcpy()``, ``printf()`` and so on. |
| 68 | Additionally, various other APIs are provided under ``include/lib/``. The |
| 69 | below list gives some examples but might not be exhaustive. |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 70 | |
| 71 | - ``aarch64/`` |
| 72 | |
| 73 | Architecture helper functions for e.g. system registers access, cache |
| 74 | maintenance operations, MMU configuration, ... |
| 75 | |
| 76 | - ``events.h`` |
| 77 | |
| 78 | Events API. Used to create synchronisation points between CPUs in tests. |
| 79 | |
| 80 | - ``irq.h`` |
| 81 | |
| 82 | IRQ handling support. Used to configure IRQs and register/unregister |
| 83 | handlers called upon reception of a specific IRQ. |
| 84 | |
| 85 | - ``power_management.h`` |
| 86 | |
| 87 | Power management operations (CPU ON/OFF, CPU suspend, etc.). |
| 88 | |
| 89 | - ``sgi.h`` |
| 90 | |
| 91 | Software Generated Interrupt support. Used as an inter-CPU communication |
| 92 | mechanism. |
| 93 | |
| 94 | - ``spinlock.h`` |
| 95 | |
| 96 | Lightweight implementation of synchronisation locks. Used to prevent |
| 97 | concurrent accesses to shared data structures. |
| 98 | |
| 99 | - ``timer.h`` |
| 100 | |
| 101 | Support for programming the timer. Any timer which is in the `always-on` |
| 102 | power domain can be used to exit CPUs from suspend state. |
| 103 | |
| 104 | - ``tftf_lib.h`` |
| 105 | |
| 106 | Miscellaneous helper functions/macros: MP-safe ``printf()``, low-level |
| 107 | PSCI wrappers, insertion of delays, raw SMC interface, support for writing |
| 108 | a string in the test report, macros to skip tests on platforms that do not |
| 109 | meet topology requirements, etc. |
| 110 | |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 111 | - ``io_storage.h`` |
| 112 | |
| 113 | Low-level IO operations. Tests are not expected to use these APIs |
| 114 | directly. They should use higher-level APIs like ``tftf_nvm_read()`` |
| 115 | and ``tftf_nvm_write()``. |
| 116 | |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 117 | - **Platform specific.** |
| 118 | |
| 119 | Note that ``include/plat/common/plat_topology.h`` provides the interfaces |
| 120 | that a platform must implement to support topology discovery (i.e. how many |
| 121 | CPUs and clusters there are). |
| 122 | |
| 123 | - **Tests.** |
| 124 | |
John Tsichritzis | 88a956f | 2018-10-19 10:30:00 +0100 | [diff] [blame] | 125 | The tests are divided into the following categories (present as directories in |
| 126 | the ``tftf/tests/`` directory): |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 127 | |
John Tsichritzis | 88a956f | 2018-10-19 10:30:00 +0100 | [diff] [blame] | 128 | - **Framework validation tests.** |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 129 | |
John Tsichritzis | 88a956f | 2018-10-19 10:30:00 +0100 | [diff] [blame] | 130 | Tests that exercise the core features of the framework. Verify that the test |
| 131 | framework itself works properly. |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 132 | |
John Tsichritzis | 88a956f | 2018-10-19 10:30:00 +0100 | [diff] [blame] | 133 | - **Runtime services tests.** |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 134 | |
John Tsichritzis | 88a956f | 2018-10-19 10:30:00 +0100 | [diff] [blame] | 135 | Tests that exercise the runtime services offered by the EL3 Firmware to the |
| 136 | Normal World software. For example, this includes tests for the Standard |
| 137 | Service (to which PSCI belongs to), the Trusted OS service or the SiP |
| 138 | service. |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 139 | |
John Tsichritzis | 88a956f | 2018-10-19 10:30:00 +0100 | [diff] [blame] | 140 | - **CPU extensions tests.** |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 141 | |
John Tsichritzis | 88a956f | 2018-10-19 10:30:00 +0100 | [diff] [blame] | 142 | Tests some CPU extensions features. For example, the AMU tests ensure that |
| 143 | the counters provided by the Activity Monitor Unit are behaving correctly. |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 144 | |
John Tsichritzis | 88a956f | 2018-10-19 10:30:00 +0100 | [diff] [blame] | 145 | - **Firmware Update tests.** |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 146 | |
John Tsichritzis | 88a956f | 2018-10-19 10:30:00 +0100 | [diff] [blame] | 147 | Tests that exercise the `Firmware Update`_ feature of TF-A. |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 148 | |
John Tsichritzis | 88a956f | 2018-10-19 10:30:00 +0100 | [diff] [blame] | 149 | - **Template tests.** |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 150 | |
John Tsichritzis | 88a956f | 2018-10-19 10:30:00 +0100 | [diff] [blame] | 151 | Sample test code showing how to write tests in practice. Serves as |
| 152 | documentation. |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 153 | |
John Tsichritzis | 88a956f | 2018-10-19 10:30:00 +0100 | [diff] [blame] | 154 | - **Performance tests.** |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 155 | |
John Tsichritzis | 88a956f | 2018-10-19 10:30:00 +0100 | [diff] [blame] | 156 | Simple tests measuring the latency of an SMC call. |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 157 | |
John Tsichritzis | 88a956f | 2018-10-19 10:30:00 +0100 | [diff] [blame] | 158 | - **Miscellaneous tests.** |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 159 | |
John Tsichritzis | 88a956f | 2018-10-19 10:30:00 +0100 | [diff] [blame] | 160 | Tests for RAS support, correct system setup, ... |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 161 | |
| 162 | All assembler files have the ``.S`` extension. The linker source file has the |
| 163 | extension ``.ld.S``. This is processed by GCC to create the linker script which |
| 164 | has the extension ``.ld``. |
| 165 | |
| 166 | Detailed Code Structure |
| 167 | ----------------------- |
| 168 | |
| 169 | The cold boot entry point is ``tftf_entrypoint`` (see |
Jimmy Brisson | 4844dc9 | 2020-04-02 15:19:34 -0500 | [diff] [blame] | 170 | ``tftf/framework/aarch64/entrypoint.S``). As explained in |
| 171 | :ref:`design_high_level_behaviour`, only the primary CPU is expected to |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 172 | execute this code. |
| 173 | |
| 174 | Tests can power on other CPUs using the function ``tftf_cpu_on()``. This uses |
| 175 | the PSCI ``CPU_ON`` API of the EL3 Firmware. When entering the Normal World, |
| 176 | execution starts at the warm boot entry point, which is ``tftf_hotplug_entry()`` |
| 177 | (see ``tftf/framework/aarch64/entrypoint.S``). |
| 178 | |
| 179 | Information about the progression of the test session and tests results are |
| 180 | written into Non-Volatile Memory as we go along. This consists of the following |
| 181 | data (see struct ``tftf_state_t`` typedef in ``tftf/framework/include/nvm.h``): |
| 182 | |
| 183 | - ``test_to_run`` |
| 184 | |
| 185 | Reference to the test to run. |
| 186 | |
| 187 | - ``test_progress`` |
| 188 | |
| 189 | Progress in the execution of ``test_to_run``. This is used to implement the |
| 190 | following state machine: |
| 191 | |
| 192 | :: |
| 193 | |
| 194 | +-> TEST_READY (initial state of the test) <--------------+ |
| 195 | | | | |
| 196 | | | Test framework prepares the test environment. | |
| 197 | | | | |
| 198 | | v | |
| 199 | | TEST_IN_PROGRESS | |
| 200 | | | | |
| 201 | | | Hand over to the test function. | |
| 202 | | | If the test wants to reboot the platform ---> TEST_REBOOTING | |
| 203 | | | | | |
| 204 | | | Test function returns into framework. | Reboot | |
| 205 | | | | | |
| 206 | | | +---------+ |
| 207 | | v |
| 208 | | TEST_COMPLETE |
| 209 | | | |
| 210 | | | Do some framework management. |
| 211 | | | Move to next test. |
| 212 | +--------+ |
| 213 | |
| 214 | - ``testcase_buffer`` |
| 215 | |
| 216 | A buffer that the test can use as a scratch area for whatever it is doing. |
| 217 | |
| 218 | - ``testcase_results`` |
| 219 | |
| 220 | - ``result_buffer_size`` |
| 221 | |
| 222 | - ``result_buffer`` |
| 223 | |
| 224 | Buffer holding the tests output. Tests output are concatenated. |
| 225 | |
Jimmy Brisson | ff08d3e | 2020-04-02 15:19:27 -0500 | [diff] [blame] | 226 | Interrupt Management |
| 227 | -------------------- |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 228 | |
| 229 | The TF-A tests expect SGIs #0 to #7 to be available for their own usage. In |
| 230 | particular, this means that Trusted World software must configure them as |
| 231 | non-secure interrupts. |
| 232 | |
| 233 | SGI #7 has a special status. It is the SGI that the timer management framework |
| 234 | sends to all CPUs when the system timer fires off (see the definition of the |
| 235 | constant ``IRQ_WAKE_SGI`` in the header file ``include/lib/irq.h``). Although |
| 236 | test cases can use this specific SGI - e.g. they can register an IRQ handler for |
| 237 | it and use it as an inter-CPU communication mechanism - they have to be aware of |
| 238 | the underlying consequences. Some tests, like the PSCI ``CPU_SUSPEND`` tests, |
| 239 | rely on this SGI to be enabled in order to wake up CPUs from their suspend |
| 240 | state. If it is disabled, these tests will leave the system in an unresponsive |
| 241 | state. |
| 242 | |
| 243 | -------------- |
| 244 | |
Sandrine Bailleux | dd84275 | 2019-04-10 09:30:10 +0200 | [diff] [blame] | 245 | *Copyright (c) 2018-2019, Arm Limited. All rights reserved.* |
Sandrine Bailleux | 3cd87d7 | 2018-10-09 11:12:55 +0200 | [diff] [blame] | 246 | |
Jimmy Brisson | 4844dc9 | 2020-04-02 15:19:34 -0500 | [diff] [blame] | 247 | .. _Firmware update: https://trustedfirmware-a.readthedocs.io/en/latest/components/firmware-update.html |