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