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