1Coding Guidelines 2================= 3 4This document provides some additional guidelines to consider when writing 5|TF-A| code. These are not intended to be strictly-enforced rules like the 6contents of the :ref:`Coding Style`. 7 8Automatic Editor Configuration 9------------------------------ 10 11Many of the rules given below (such as indentation size, use of tabs, and 12newlines) can be set automatically using the `EditorConfig`_ configuration file 13in the root of the repository: ``.editorconfig``. With a supported editor, the 14rules set out in this file can be automatically applied when you are editing 15files in the |TF-A| repository. 16 17Several editors include built-in support for EditorConfig files, and many others 18support its functionality through plugins. 19 20Use of the EditorConfig file is suggested but is not required. 21 22 23Automatic Compliance Checking 24----------------------------- 25 26To assist with coding style compliance, the project Makefile contains two 27targets which both utilise the `checkpatch.pl` script that ships with the Linux 28source tree. The project also defines certain *checkpatch* options in the 29``.checkpatch.conf`` file in the top-level directory. 30 31.. note:: 32 Checkpatch errors will gate upstream merging of pull requests. 33 Checkpatch warnings will not gate merging but should be reviewed and fixed if 34 possible. 35 36To check the entire source tree, you must first download copies of 37``checkpatch.pl``, ``spelling.txt`` and ``const_structs.checkpatch`` available 38in the `Linux master tree`_ *scripts* directory, then set the ``CHECKPATCH`` 39environment variable to point to ``checkpatch.pl`` (with the other 2 files in 40the same directory) and build the `checkcodebase` target: 41 42.. code:: shell 43 44 make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkcodebase 45 46To just check the style on the files that differ between your local branch and 47the remote master, use: 48 49.. code:: shell 50 51 make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkpatch 52 53If you wish to check your patch against something other than the remote master, 54set the ``BASE_COMMIT`` variable to your desired branch. By default, 55``BASE_COMMIT`` is set to ``origin/master``. 56 57Ignored Checkpatch Warnings 58^^^^^^^^^^^^^^^^^^^^^^^^^^^ 59 60Some checkpatch warnings in the TF codebase are deliberately ignored. These 61include: 62 63- ``**WARNING: line over 80 characters**``: Although the codebase should 64 generally conform to the 80 character limit this is overly restrictive in some 65 cases. 66 67- ``**WARNING: Use of volatile is usually wrong``: see 68 `Why the “volatile” type class should not be used`_ . Although this document 69 contains some very useful information, there are several legimate uses of the 70 volatile keyword within the TF codebase. 71 72Performance considerations 73-------------------------- 74 75Avoid printf and use logging macros 76^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 77 78``debug.h`` provides logging macros (for example, ``WARN`` and ``ERROR``) 79which wrap ``tf_log`` and which allow the logging call to be compiled-out 80depending on the ``make`` command. Use these macros to avoid print statements 81being compiled unconditionally into the binary. 82 83Each logging macro has a numerical log level: 84 85.. code:: c 86 87 #define LOG_LEVEL_NONE 0 88 #define LOG_LEVEL_ERROR 10 89 #define LOG_LEVEL_NOTICE 20 90 #define LOG_LEVEL_WARNING 30 91 #define LOG_LEVEL_INFO 40 92 #define LOG_LEVEL_VERBOSE 50 93 94By default, all logging statements with a log level ``<= LOG_LEVEL_INFO`` will 95be compiled into debug builds and all statements with a log level 96``<= LOG_LEVEL_NOTICE`` will be compiled into release builds. This can be 97overridden from the command line or by the platform makefile (although it may be 98necessary to clean the build directory first). 99 100For example, to enable ``VERBOSE`` logging on FVP: 101 102.. code:: shell 103 104 make PLAT=fvp LOG_LEVEL=50 all 105 106Use const data where possible 107^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 108 109For example, the following code: 110 111.. code:: c 112 113 struct my_struct { 114 int arg1; 115 int arg2; 116 }; 117 118 void init(struct my_struct *ptr); 119 120 void main(void) 121 { 122 struct my_struct x; 123 x.arg1 = 1; 124 x.arg2 = 2; 125 init(&x); 126 } 127 128is better written as: 129 130.. code:: c 131 132 struct my_struct { 133 int arg1; 134 int arg2; 135 }; 136 137 void init(const struct my_struct *ptr); 138 139 void main(void) 140 { 141 const struct my_struct x = { 1, 2 }; 142 init(&x); 143 } 144 145This allows the linker to put the data in a read-only data section instead of a 146writeable data section, which may result in a smaller and faster binary. Note 147that this may require dependent functions (``init()`` in the above example) to 148have ``const`` arguments, assuming they don't need to modify the data. 149 150Libc functions that are banned or to be used with caution 151--------------------------------------------------------- 152 153Below is a list of functions that present security risks and either must not be 154used (Banned) or are discouraged from use and must be used with care (Caution). 155 156+------------------------+-----------+--------------------------------------+ 157| libc function | Status | Comments | 158+========================+===========+======================================+ 159| ``strcpy, wcscpy``, | Banned | use strlcpy instead | 160| ``strncpy`` | | | 161+------------------------+-----------+--------------------------------------+ 162| ``strcat, wcscat``, | Banned | use strlcat instead | 163| ``strncat`` | | | 164+------------------------+-----------+--------------------------------------+ 165| ``sprintf, vsprintf`` | Banned | use snprintf, vsnprintf | 166| | | instead | 167+------------------------+-----------+--------------------------------------+ 168| ``snprintf`` | Caution | ensure result fits in buffer | 169| | | i.e : snprintf(buf,size...) < size | 170+------------------------+-----------+--------------------------------------+ 171| ``vsnprintf`` | Caution | inspect va_list match types | 172| | | specified in format string | 173+------------------------+-----------+--------------------------------------+ 174| ``strtok`` | Banned | use strtok_r or strsep instead | 175+------------------------+-----------+--------------------------------------+ 176| ``strtok_r, strsep`` | Caution | inspect for terminated input buffer | 177+------------------------+-----------+--------------------------------------+ 178| ``ato*`` | Banned | use equivalent strto* functions | 179+------------------------+-----------+--------------------------------------+ 180| ``*toa`` | Banned | Use snprintf instead | 181+------------------------+-----------+--------------------------------------+ 182 183The `libc` component in the codebase will not add support for the banned APIs. 184 185Error handling and robustness 186----------------------------- 187 188Using CASSERT to check for compile time data errors 189^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 190 191Where possible, use the ``CASSERT`` macro to check the validity of data known at 192compile time instead of checking validity at runtime, to avoid unnecessary 193runtime code. 194 195For example, this can be used to check that the assembler's and compiler's views 196of the size of an array is the same. 197 198.. code:: c 199 200 #include <cassert.h> 201 202 define MY_STRUCT_SIZE 8 /* Used by assembler source files */ 203 204 struct my_struct { 205 uint32_t arg1; 206 uint32_t arg2; 207 }; 208 209 CASSERT(MY_STRUCT_SIZE == sizeof(struct my_struct), assert_my_struct_size_mismatch); 210 211 212If ``MY_STRUCT_SIZE`` in the above example were wrong then the compiler would 213emit an error like this: 214 215:: 216 217 my_struct.h:10:1: error: size of array ‘assert_my_struct_size_mismatch’ is negative 218 219 220Using assert() to check for programming errors 221^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 222 223In general, each secure world TF image (BL1, BL2, BL31 and BL32) should be 224treated as a tightly integrated package; the image builder should be aware of 225and responsible for all functionality within the image, even if code within that 226image is provided by multiple entities. This allows us to be more aggressive in 227interpreting invalid state or bad function arguments as programming errors using 228``assert()``, including arguments passed across platform porting interfaces. 229This is in contrast to code in a Linux environment, which is less tightly 230integrated and may attempt to be more defensive by passing the error back up the 231call stack. 232 233Where possible, badly written TF code should fail early using ``assert()``. This 234helps reduce the amount of untested conditional code. By default these 235statements are not compiled into release builds, although this can be overridden 236using the ``ENABLE_ASSERTIONS`` build flag. 237 238Examples: 239 240- Bad argument supplied to library function 241- Bad argument provided by platform porting function 242- Internal secure world image state is inconsistent 243 244 245Handling integration errors 246^^^^^^^^^^^^^^^^^^^^^^^^^^^ 247 248Each secure world image may be provided by a different entity (for example, a 249Trusted Boot vendor may provide the BL2 image, a TEE vendor may provide the BL32 250image and the OEM/SoC vendor may provide the other images). 251 252An image may contain bugs that are only visible when the images are integrated. 253The system integrator may not even have access to the debug variants of all the 254images in order to check if asserts are firing. For example, the release variant 255of BL1 may have already been burnt into the SoC. Therefore, TF code that detects 256an integration error should _not_ consider this a programming error, and should 257always take action, even in release builds. 258 259If an integration error is considered non-critical it should be treated as a 260recoverable error. If the error is considered critical it should be treated as 261an unexpected unrecoverable error. 262 263Handling recoverable errors 264^^^^^^^^^^^^^^^^^^^^^^^^^^^ 265 266The secure world **must not** crash when supplied with bad data from an external 267source. For example, data from the normal world or a hardware device. Similarly, 268the secure world **must not** crash if it detects a non-critical problem within 269itself or the system. It must make every effort to recover from the problem by 270emitting a ``WARN`` message, performing any necessary error handling and 271continuing. 272 273Examples: 274 275- Secure world receives SMC from normal world with bad arguments. 276- Secure world receives SMC from normal world at an unexpected time. 277- BL31 receives SMC from BL32 with bad arguments. 278- BL31 receives SMC from BL32 at unexpected time. 279- Secure world receives recoverable error from hardware device. Retrying the 280 operation may help here. 281- Non-critical secure world service is not functioning correctly. 282- BL31 SPD discovers minor configuration problem with corresponding SP. 283 284Handling unrecoverable errors 285^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 286 287In some cases it may not be possible for the secure world to recover from an 288error. This situation should be handled in one of the following ways: 289 2901. If the unrecoverable error is unexpected then emit an ``ERROR`` message and 291 call ``panic()``. This will end up calling the platform-specific function 292 ``plat_panic_handler()``. 2932. If the unrecoverable error is expected to occur in certain circumstances, 294 then emit an ``ERROR`` message and call the platform-specific function 295 ``plat_error_handler()``. 296 297Cases 1 and 2 are subtly different. A platform may implement 298``plat_panic_handler`` and ``plat_error_handler`` in the same way (for example, 299by waiting for a secure watchdog to time-out or by invoking an interface on the 300platform's power controller to reset the platform). However, 301``plat_error_handler`` may take additional action for some errors (for example, 302it may set a flag so the platform resets into a different mode). Also, 303``plat_panic_handler()`` may implement additional debug functionality (for 304example, invoking a hardware breakpoint). 305 306Examples of unexpected unrecoverable errors: 307 308- BL32 receives an unexpected SMC response from BL31 that it is unable to 309 recover from. 310- BL31 Trusted OS SPD code discovers that BL2 has not loaded the corresponding 311 Trusted OS, which is critical for platform operation. 312- Secure world discovers that a critical hardware device is an unexpected and 313 unrecoverable state. 314- Secure world receives an unexpected and unrecoverable error from a critical 315 hardware device. 316- Secure world discovers that it is running on unsupported hardware. 317 318Examples of expected unrecoverable errors: 319 320- BL1/BL2 fails to load the next image due to missing/corrupt firmware on disk. 321- BL1/BL2 fails to authenticate the next image due to an invalid certificate. 322- Secure world continuously receives recoverable errors from a hardware device 323 but is unable to proceed without a valid response. 324 325Handling critical unresponsiveness 326^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 327 328If the secure world is waiting for a response from an external source (for 329example, the normal world or a hardware device) which is critical for continued 330operation, it must not wait indefinitely. It must have a mechanism (for example, 331a secure watchdog) for resetting itself and/or the external source to prevent 332the system from executing in this state indefinitely. 333 334Examples: 335 336- BL1 is waiting for the normal world to raise an SMC to proceed to the next 337 stage of the secure firmware update process. 338- A Trusted OS is waiting for a response from a proxy in the normal world that 339 is critical for continued operation. 340- Secure world is waiting for a hardware response that is critical for continued 341 operation. 342 343Use of built-in *C* and *libc* data types 344----------------------------------------- 345 346The |TF-A| codebase should be kept as portable as possible, especially since 347both 64-bit and 32-bit platforms are supported. To help with this, the following 348data type usage guidelines should be followed: 349 350- Where possible, use the built-in *C* data types for variable storage (for 351 example, ``char``, ``int``, ``long long``, etc) instead of the standard *C99* 352 types. Most code is typically only concerned with the minimum size of the 353 data stored, which the built-in *C* types guarantee. 354 355- Avoid using the exact-size standard *C99* types in general (for example, 356 ``uint16_t``, ``uint32_t``, ``uint64_t``, etc) since they can prevent the 357 compiler from making optimizations. There are legitimate uses for them, 358 for example to represent data of a known structure. When using them in struct 359 definitions, consider how padding in the struct will work across architectures. 360 For example, extra padding may be introduced in |AArch32| systems if a struct 361 member crosses a 32-bit boundary. 362 363- Use ``int`` as the default integer type - it's likely to be the fastest on all 364 systems. Also this can be assumed to be 32-bit as a consequence of the 365 `Procedure Call Standard for the Arm Architecture`_ and the `Procedure Call 366 Standard for the Arm 64-bit Architecture`_ . 367 368- Avoid use of ``short`` as this may end up being slower than ``int`` in some 369 systems. If a variable must be exactly 16-bit, use ``int16_t`` or 370 ``uint16_t``. 371 372- Avoid use of ``long``. This is guaranteed to be at least 32-bit but, given 373 that `int` is 32-bit on Arm platforms, there is no use for it. For integers of 374 at least 64-bit, use ``long long``. 375 376- Use ``char`` for storing text. Use ``uint8_t`` for storing other 8-bit data. 377 378- Use ``unsigned`` for integers that can never be negative (counts, 379 indices, sizes, etc). TF intends to comply with MISRA "essential type" coding 380 rules (10.X), where signed and unsigned types are considered different 381 essential types. Choosing the correct type will aid this. MISRA static 382 analysers will pick up any implicit signed/unsigned conversions that may lead 383 to unexpected behaviour. 384 385- For pointer types: 386 387 - If an argument in a function declaration is pointing to a known type then 388 simply use a pointer to that type (for example: ``struct my_struct *``). 389 390 - If a variable (including an argument in a function declaration) is pointing 391 to a general, memory-mapped address, an array of pointers or another 392 structure that is likely to require pointer arithmetic then use 393 ``uintptr_t``. This will reduce the amount of casting required in the code. 394 Avoid using ``unsigned long`` or ``unsigned long long`` for this purpose; it 395 may work but is less portable. 396 397 - For other pointer arguments in a function declaration, use ``void *``. This 398 includes pointers to types that are abstracted away from the known API and 399 pointers to arbitrary data. This allows the calling function to pass a 400 pointer argument to the function without any explicit casting (the cast to 401 ``void *`` is implicit). The function implementation can then do the 402 appropriate casting to a specific type. 403 404 - Avoid pointer arithmetic generally (as this violates MISRA C 2012 rule 405 18.4) and especially on void pointers (as this is only supported via 406 language extensions and is considered non-standard). In TF-A, setting the 407 ``W`` build flag to ``W=3`` enables the *-Wpointer-arith* compiler flag and 408 this will emit warnings where pointer arithmetic is used. 409 410 - Use ``ptrdiff_t`` to compare the difference between 2 pointers. 411 412- Use ``size_t`` when storing the ``sizeof()`` something. 413 414- Use ``ssize_t`` when returning the ``sizeof()`` something from a function that 415 can also return an error code; the signed type allows for a negative return 416 code in case of error. This practice should be used sparingly. 417 418- Use ``u_register_t`` when it's important to store the contents of a register 419 in its native size (32-bit in |AArch32| and 64-bit in |AArch64|). This is not a 420 standard *C99* type but is widely available in libc implementations, 421 including the FreeBSD version included with the TF codebase. Where possible, 422 cast the variable to a more appropriate type before interpreting the data. For 423 example, the following struct in ``ep_info.h`` could use this type to minimize 424 the storage required for the set of registers: 425 426.. code:: c 427 428 typedef struct aapcs64_params { 429 u_register_t arg0; 430 u_register_t arg1; 431 u_register_t arg2; 432 u_register_t arg3; 433 u_register_t arg4; 434 u_register_t arg5; 435 u_register_t arg6; 436 u_register_t arg7; 437 } aapcs64_params_t; 438 439If some code wants to operate on ``arg0`` and knows that it represents a 32-bit 440unsigned integer on all systems, cast it to ``unsigned int``. 441 442These guidelines should be updated if additional types are needed. 443 444Favor C language over assembly language 445--------------------------------------- 446 447Generally, prefer code written in C over assembly. Assembly code is less 448portable, harder to understand, maintain and audit security wise. Also, static 449analysis tools generally don't analyze assembly code. 450 451There are, however, legitimate uses of assembly language. These include: 452 453 - Early boot code executed before the C runtime environment is setup. 454 455 - Exception handling code. 456 457 - Low-level code where the exact sequence of instructions executed on the CPU 458 matters, such as CPU reset sequences. 459 460 - Low-level code where specific system-level instructions must be used, such 461 as cache maintenance operations. 462 463-------------- 464 465*Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.* 466 467.. _`Linux master tree`: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/ 468.. _`Procedure Call Standard for the Arm Architecture`: https://developer.arm.com/docs/ihi0042/latest/ 469.. _`Procedure Call Standard for the Arm 64-bit Architecture`: https://developer.arm.com/docs/ihi0055/latest/ 470.. _`EditorConfig`: http://editorconfig.org/ 471.. _`Why the “volatile” type class should not be used`: https://www.kernel.org/doc/html/latest/process/volatile-considered-harmful.html 472.. _`MISRA C:2012 Guidelines`: https://www.misra.org.uk/Activities/MISRAC/tabid/160/Default.aspx 473.. _`a spreadsheet`: https://developer.trustedfirmware.org/file/download/lamajxif3w7c4mpjeoo5/PHID-FILE-fp7c7acszn6vliqomyhn/MISRA-and-TF-Analysis-v1.3.ods 474