1Coding Style & Guidelines 2========================= 3 4The following sections contain TF coding guidelines. They are continually 5evolving and should not be considered "set in stone". Feel free to question them 6and provide feedback. 7 8Some of the guidelines may also apply to other codebases. 9 10.. note:: 11 The existing TF codebase does not necessarily comply with all the 12 below guidelines but the intent is for it to do so eventually. 13 14Checkpatch overrides 15-------------------- 16 17Some checkpatch warnings in the TF codebase are deliberately ignored. These 18include: 19 20- ``**WARNING: line over 80 characters**``: Although the codebase should 21 generally conform to the 80 character limit this is overly restrictive in some 22 cases. 23 24- ``**WARNING: Use of volatile is usually wrong``: see 25 `Why the “volatile” type class should not be used`_ . Although this document 26 contains some very useful information, there are several legitimate uses of 27 the volatile keyword within the TF codebase. 28 29Headers and inclusion 30--------------------- 31 32Header guards 33^^^^^^^^^^^^^ 34 35For a header file called "some_driver.h" the style used by the Trusted Firmware 36is: 37 38.. code:: c 39 40 #ifndef SOME_DRIVER_H 41 #define SOME_DRIVER_H 42 43 <header content> 44 45 #endif /* SOME_DRIVER_H */ 46 47Include statement ordering 48^^^^^^^^^^^^^^^^^^^^^^^^^^ 49 50All header files that are included by a source file must use the following, 51grouped ordering. This is to improve readability (by making it easier to quickly 52read through the list of headers) and maintainability. 53 54#. *System* includes: Header files from the standard *C* library, such as 55 ``stddef.h`` and ``string.h``. 56 57#. *Project* includes: Header files under the ``include/`` directory within TF 58 are *project* includes. 59 60#. *Platform* includes: Header files relating to a single, specific platform, 61 and which are located under the ``plat/<platform_name>`` directory within TF, 62 are *platform* includes. 63 64Within each group, ``#include`` statements must be in alphabetical order, 65taking both the file and directory names into account. 66 67Groups must be separated by a single blank line for clarity. 68 69The example below illustrates the ordering rules using some contrived header 70file names; this type of name reuse should be otherwise avoided. 71 72.. code:: c 73 74 #include <string.h> 75 76 #include <a_dir/example/a_header.h> 77 #include <a_dir/example/b_header.h> 78 #include <a_dir/test/a_header.h> 79 #include <b_dir/example/a_header.h> 80 81 #include "./a_header.h" 82 83Include statement variants 84^^^^^^^^^^^^^^^^^^^^^^^^^^ 85 86Two variants of the ``#include`` directive are acceptable in the TF codebase. 87Correct use of the two styles improves readability by suggesting the location 88of the included header and reducing ambiguity in cases where generic and 89platform-specific headers share a name. 90 91For header files that are in the same directory as the source file that is 92including them, use the ``"..."`` variant. 93 94For header files that are **not** in the same directory as the source file that 95is including them, use the ``<...>`` variant. 96 97Example (bl1_fwu.c): 98 99.. code:: c 100 101 #include <assert.h> 102 #include <errno.h> 103 #include <string.h> 104 105 #include "bl1_private.h" 106 107Platform include paths 108^^^^^^^^^^^^^^^^^^^^^^ 109 110Platforms are allowed to add more include paths to be passed to the compiler. 111The ``PLAT_INCLUDES`` variable is used for this purpose. This is needed in 112particular for the file ``platform_def.h``. 113 114Example: 115 116.. code:: c 117 118 PLAT_INCLUDES += -Iinclude/plat/myplat/include 119 120Types and typedefs 121------------------ 122 123Use of built-in *C* and *libc* data types 124^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 125 126The TF codebase should be kept as portable as possible, especially since both 12764-bit and 32-bit platforms are supported. To help with this, the following data 128type usage guidelines should be followed: 129 130- Where possible, use the built-in *C* data types for variable storage (for 131 example, ``char``, ``int``, ``long long``, etc) instead of the standard *C99* 132 types. Most code is typically only concerned with the minimum size of the 133 data stored, which the built-in *C* types guarantee. 134 135- Avoid using the exact-size standard *C99* types in general (for example, 136 ``uint16_t``, ``uint32_t``, ``uint64_t``, etc) since they can prevent the 137 compiler from making optimizations. There are legitimate uses for them, 138 for example to represent data of a known structure. When using them in struct 139 definitions, consider how padding in the struct will work across architectures. 140 For example, extra padding may be introduced in AArch32 systems if a struct 141 member crosses a 32-bit boundary. 142 143- Use ``int`` as the default integer type - it's likely to be the fastest on all 144 systems. Also this can be assumed to be 32-bit as a consequence of the 145 `Procedure Call Standard for the Arm Architecture`_ and the `Procedure Call 146 Standard for the Arm 64-bit Architecture`_ . 147 148- Avoid use of ``short`` as this may end up being slower than ``int`` in some 149 systems. If a variable must be exactly 16-bit, use ``int16_t`` or 150 ``uint16_t``. 151 152- Avoid use of ``long``. This is guaranteed to be at least 32-bit but, given 153 that `int` is 32-bit on Arm platforms, there is no use for it. For integers of 154 at least 64-bit, use ``long long``. 155 156- Use ``char`` for storing text. Use ``uint8_t`` for storing other 8-bit data. 157 158- Use ``unsigned`` for integers that can never be negative (counts, 159 indices, sizes, etc). TF intends to comply with MISRA "essential type" coding 160 rules (10.X), where signed and unsigned types are considered different 161 essential types. Choosing the correct type will aid this. MISRA static 162 analysers will pick up any implicit signed/unsigned conversions that may lead 163 to unexpected behaviour. 164 165- For pointer types: 166 167 - If an argument in a function declaration is pointing to a known type then 168 simply use a pointer to that type (for example: ``struct my_struct *``). 169 170 - If a variable (including an argument in a function declaration) is pointing 171 to a general, memory-mapped address, an array of pointers or another 172 structure that is likely to require pointer arithmetic then use 173 ``uintptr_t``. This will reduce the amount of casting required in the code. 174 Avoid using ``unsigned long`` or ``unsigned long long`` for this purpose; it 175 may work but is less portable. 176 177 - For other pointer arguments in a function declaration, use ``void *``. This 178 includes pointers to types that are abstracted away from the known API and 179 pointers to arbitrary data. This allows the calling function to pass a 180 pointer argument to the function without any explicit casting (the cast to 181 ``void *`` is implicit). The function implementation can then do the 182 appropriate casting to a specific type. 183 184 - Use ``ptrdiff_t`` to compare the difference between 2 pointers. 185 186- Use ``size_t`` when storing the ``sizeof()`` something. 187 188- Use ``ssize_t`` when returning the ``sizeof()`` something from a function that 189 can also return an error code; the signed type allows for a negative return 190 code in case of error. This practice should be used sparingly. 191 192- Use ``u_register_t`` when it's important to store the contents of a register 193 in its native size (32-bit in AArch32 and 64-bit in AArch64). This is not a 194 standard *C99* type but is widely available in libc implementations, 195 including the FreeBSD version included with the TF codebase. Where possible, 196 cast the variable to a more appropriate type before interpreting the data. For 197 example, the following struct in ``ep_info.h`` could use this type to minimize 198 the storage required for the set of registers: 199 200.. code:: c 201 202 typedef struct aapcs64_params { 203 u_register_t arg0; 204 u_register_t arg1; 205 u_register_t arg2; 206 u_register_t arg3; 207 u_register_t arg4; 208 u_register_t arg5; 209 u_register_t arg6; 210 u_register_t arg7; 211 } aapcs64_params_t; 212 213If some code wants to operate on ``arg0`` and knows that it represents a 32-bit 214unsigned integer on all systems, cast it to ``unsigned int``. 215 216These guidelines should be updated if additional types are needed. 217 218Avoid anonymous typedefs of structs/enums in headers 219^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 220 221For example, the following definition: 222 223.. code:: c 224 225 typedef struct { 226 int arg1; 227 int arg2; 228 } my_struct_t; 229 230 231is better written as: 232 233.. code:: c 234 235 struct my_struct { 236 int arg1; 237 int arg2; 238 }; 239 240This allows function declarations in other header files that depend on the 241struct/enum to forward declare the struct/enum instead of including the 242entire header: 243 244.. code:: c 245 246 #include <my_struct.h> 247 void my_func(my_struct_t *arg); 248 249instead of: 250 251.. code:: c 252 253 struct my_struct; 254 void my_func(struct my_struct *arg); 255 256Some TF definitions use both a struct/enum name **and** a typedef name. This 257is discouraged for new definitions as it makes it difficult for TF to comply 258with MISRA rule 8.3, which states that "All declarations of an object or 259function shall use the same names and type qualifiers". 260 261The Linux coding standards also discourage new typedefs and checkpatch emits 262a warning for this. 263 264Existing typedefs will be retained for compatibility. 265 266Libc functions that are banned or to be used with caution 267--------------------------------------------------------- 268 269Below is a list of functions that present security risks and either must not be 270used (Banned) or are discouraged from use and must be used with care (Caution). 271 272+------------------------+-----------+--------------------------------------+ 273| libc function | Status | Comments | 274+========================+===========+======================================+ 275| ``strcpy, wcscpy``, | Banned | use strlcpy instead | 276| ``strncpy`` | | | 277+------------------------+-----------+--------------------------------------+ 278| ``strcat, wcscat``, | Banned | use strlcat instead | 279| ``strncat`` | | | 280+------------------------+-----------+--------------------------------------+ 281| ``sprintf, vsprintf`` | Banned | use snprintf, vsnprintf | 282| | | instead | 283+------------------------+-----------+--------------------------------------+ 284| ``snprintf`` | Caution | ensure result fits in buffer | 285| | | i.e : snprintf(buf,size...) < size | 286+------------------------+-----------+--------------------------------------+ 287| ``vsnprintf`` | Caution | inspect va_list match types | 288| | | specified in format string | 289+------------------------+-----------+--------------------------------------+ 290| ``strtok`` | Banned | use strtok_r or strsep instead | 291+------------------------+-----------+--------------------------------------+ 292| ``strtok_r, strsep`` | Caution | inspect for terminated input buffer | 293+------------------------+-----------+--------------------------------------+ 294| ``ato*`` | Banned | use equivalent strto* functions | 295+------------------------+-----------+--------------------------------------+ 296| ``*toa`` | Banned | Use snprintf instead | 297+------------------------+-----------+--------------------------------------+ 298 299The `libc` component in the codebase will not add support for the banned APIs. 300 301Error handling and robustness 302----------------------------- 303 304Using CASSERT to check for compile time data errors 305^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 306 307Where possible, use the ``CASSERT`` macro to check the validity of data known at 308compile time instead of checking validity at runtime, to avoid unnecessary 309runtime code. 310 311For example, this can be used to check that the assembler's and compiler's views 312of the size of an array is the same. 313 314.. code:: c 315 316 #include <cassert.h> 317 318 define MY_STRUCT_SIZE 8 /* Used by assembler source files */ 319 320 struct my_struct { 321 uint32_t arg1; 322 uint32_t arg2; 323 }; 324 325 CASSERT(MY_STRUCT_SIZE == sizeof(struct my_struct), assert_my_struct_size_mismatch); 326 327 328If ``MY_STRUCT_SIZE`` in the above example were wrong then the compiler would 329emit an error like this: 330 331:: 332 333 my_struct.h:10:1: error: size of array ‘assert_my_struct_size_mismatch’ is negative 334 335 336Using assert() to check for programming errors 337^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 338 339In general, each secure world TF image (BL1, BL2, BL31 and BL32) should be 340treated as a tightly integrated package; the image builder should be aware of 341and responsible for all functionality within the image, even if code within that 342image is provided by multiple entities. This allows us to be more aggressive in 343interpreting invalid state or bad function arguments as programming errors using 344``assert()``, including arguments passed across platform porting interfaces. 345This is in contrast to code in a Linux environment, which is less tightly 346integrated and may attempt to be more defensive by passing the error back up the 347call stack. 348 349Where possible, badly written TF code should fail early using ``assert()``. This 350helps reduce the amount of untested conditional code. By default these 351statements are not compiled into release builds, although this can be overridden 352using the ``ENABLE_ASSERTIONS`` build flag. 353 354Examples: 355 356- Bad argument supplied to library function 357- Bad argument provided by platform porting function 358- Internal secure world image state is inconsistent 359 360 361Handling integration errors 362^^^^^^^^^^^^^^^^^^^^^^^^^^^ 363 364Each secure world image may be provided by a different entity (for example, a 365Trusted Boot vendor may provide the BL2 image, a TEE vendor may provide the BL32 366image and the OEM/SoC vendor may provide the other images). 367 368An image may contain bugs that are only visible when the images are integrated. 369The system integrator may not even have access to the debug variants of all the 370images in order to check if asserts are firing. For example, the release variant 371of BL1 may have already been burnt into the SoC. Therefore, TF code that detects 372an integration error should _not_ consider this a programming error, and should 373always take action, even in release builds. 374 375If an integration error is considered non-critical it should be treated as a 376recoverable error. If the error is considered critical it should be treated as 377an unexpected unrecoverable error. 378 379Handling recoverable errors 380^^^^^^^^^^^^^^^^^^^^^^^^^^^ 381 382The secure world **must not** crash when supplied with bad data from an external 383source. For example, data from the normal world or a hardware device. Similarly, 384the secure world **must not** crash if it detects a non-critical problem within 385itself or the system. It must make every effort to recover from the problem by 386emitting a ``WARN`` message, performing any necessary error handling and 387continuing. 388 389Examples: 390 391- Secure world receives SMC from normal world with bad arguments. 392- Secure world receives SMC from normal world at an unexpected time. 393- BL31 receives SMC from BL32 with bad arguments. 394- BL31 receives SMC from BL32 at unexpected time. 395- Secure world receives recoverable error from hardware device. Retrying the 396 operation may help here. 397- Non-critical secure world service is not functioning correctly. 398- BL31 SPD discovers minor configuration problem with corresponding SP. 399 400Handling unrecoverable errors 401^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 402 403In some cases it may not be possible for the secure world to recover from an 404error. This situation should be handled in one of the following ways: 405 4061. If the unrecoverable error is unexpected then emit an ``ERROR`` message and 407 call ``panic()``. This will end up calling the platform-specific function 408 ``plat_panic_handler()``. 4092. If the unrecoverable error is expected to occur in certain circumstances, 410 then emit an ``ERROR`` message and call the platform-specific function 411 ``plat_error_handler()``. 412 413Cases 1 and 2 are subtly different. A platform may implement ``plat_panic_handler`` 414and ``plat_error_handler`` in the same way (for example, by waiting for a secure 415watchdog to time-out or by invoking an interface on the platform's power 416controller to reset the platform). However, ``plat_error_handler`` may take 417additional action for some errors (for example, it may set a flag so the 418platform resets into a different mode). Also, ``plat_panic_handler()`` may 419implement additional debug functionality (for example, invoking a hardware 420breakpoint). 421 422Examples of unexpected unrecoverable errors: 423 424- BL32 receives an unexpected SMC response from BL31 that it is unable to 425 recover from. 426- BL31 Trusted OS SPD code discovers that BL2 has not loaded the corresponding 427 Trusted OS, which is critical for platform operation. 428- Secure world discovers that a critical hardware device is an unexpected and 429 unrecoverable state. 430- Secure world receives an unexpected and unrecoverable error from a critical 431 hardware device. 432- Secure world discovers that it is running on unsupported hardware. 433 434Examples of expected unrecoverable errors: 435 436- BL1/BL2 fails to load the next image due to missing/corrupt firmware on disk. 437- BL1/BL2 fails to authenticate the next image due to an invalid certificate. 438- Secure world continuously receives recoverable errors from a hardware device 439 but is unable to proceed without a valid response. 440 441Handling critical unresponsiveness 442^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 443 444If the secure world is waiting for a response from an external source (for 445example, the normal world or a hardware device) which is critical for continued 446operation, it must not wait indefinitely. It must have a mechanism (for example, 447a secure watchdog) for resetting itself and/or the external source to prevent 448the system from executing in this state indefinitely. 449 450Examples: 451 452- BL1 is waiting for the normal world to raise an SMC to proceed to the next 453 stage of the secure firmware update process. 454- A Trusted OS is waiting for a response from a proxy in the normal world that 455 is critical for continued operation. 456- Secure world is waiting for a hardware response that is critical for continued 457 operation. 458 459Security considerations 460----------------------- 461 462Part of the security of a platform is handling errors correctly, as described in 463the previous section. There are several other security considerations covered in 464this section. 465 466Do not leak secrets to the normal world 467^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 468 469The secure world **must not** leak secrets to the normal world, for example in 470response to an SMC. 471 472Handling Denial of Service attacks 473^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 474 475The secure world **should never** crash or become unusable due to receiving too 476many normal world requests (a *Denial of Service* or *DoS* attack). It should 477have a mechanism for throttling or ignoring normal world requests. 478 479Performance considerations 480-------------------------- 481 482Avoid printf and use logging macros 483^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 484 485``debug.h`` provides logging macros (for example, ``WARN`` and ``ERROR``) 486which wrap ``tf_log`` and which allow the logging call to be compiled-out 487depending on the ``make`` command. Use these macros to avoid print statements 488being compiled unconditionally into the binary. 489 490Each logging macro has a numerical log level: 491 492.. code:: c 493 494 #define LOG_LEVEL_NONE 0 495 #define LOG_LEVEL_ERROR 10 496 #define LOG_LEVEL_NOTICE 20 497 #define LOG_LEVEL_WARNING 30 498 #define LOG_LEVEL_INFO 40 499 #define LOG_LEVEL_VERBOSE 50 500 501 502By default, all logging statements with a log level ``<= LOG_LEVEL_INFO`` will 503be compiled into debug builds and all statements with a log level 504``<= LOG_LEVEL_NOTICE`` will be compiled into release builds. This can be 505overridden from the command line or by the platform makefile (although it may be 506necessary to clean the build directory first). For example, to enable 507``VERBOSE`` logging on FVP: 508 509``make PLAT=fvp LOG_LEVEL=50 all`` 510 511Use const data where possible 512^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 513 514For example, the following code: 515 516.. code:: c 517 518 struct my_struct { 519 int arg1; 520 int arg2; 521 }; 522 523 void init(struct my_struct *ptr); 524 525 void main(void) 526 { 527 struct my_struct x; 528 x.arg1 = 1; 529 x.arg2 = 2; 530 init(&x); 531 } 532 533is better written as: 534 535.. code:: c 536 537 struct my_struct { 538 int arg1; 539 int arg2; 540 }; 541 542 void init(const struct my_struct *ptr); 543 544 void main(void) 545 { 546 const struct my_struct x = { 1, 2 }; 547 init(&x); 548 } 549 550This allows the linker to put the data in a read-only data section instead of a 551writeable data section, which may result in a smaller and faster binary. Note 552that this may require dependent functions (``init()`` in the above example) to 553have ``const`` arguments, assuming they don't need to modify the data. 554 555Library and driver code 556----------------------- 557 558TF library code (under ``lib/`` and ``include/lib``) is any code that provides a 559reusable interface to other code, potentially even to code outside of TF. 560 561In some systems drivers must conform to a specific driver framework to provide 562services to the rest of the system. TF has no driver framework and the 563distinction between a driver and library is somewhat subjective. 564 565A driver (under ``drivers/`` and ``include/drivers/``) is defined as code that 566interfaces with hardware via a memory mapped interface. 567 568Some drivers (for example, the Arm CCI driver in ``include/drivers/arm/cci.h``) 569provide a general purpose API to that specific hardware. Other drivers (for 570example, the Arm PL011 console driver in ``drivers/arm/pl011/pl011_console.S``) 571provide a specific hardware implementation of a more abstract library API. In 572the latter case there may potentially be multiple drivers for the same hardware 573device. 574 575Neither libraries nor drivers should depend on platform-specific code. If they 576require platform-specific data (for example, a base address) to operate then 577they should provide an initialization function that takes the platform-specific 578data as arguments. 579 580TF common code (under ``common/`` and ``include/common/``) is code that is re-used 581by other generic (non-platform-specific) TF code. It is effectively internal 582library code. 583 584.. _`Why the “volatile” type class should not be used`: https://www.kernel.org/doc/html/latest/process/volatile-considered-harmful.html 585.. _`Procedure Call Standard for the Arm Architecture`: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042f/IHI0042F_aapcs.pdf 586.. _`Procedure Call Standard for the Arm 64-bit Architecture`: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf 587