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