blob: e8f365b365b565fa12b8c2fdd70f94f74cec28f8 [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 Beesleye5f0f0a2019-01-31 11:39:01 +000075
Paul Beesleyfd688342019-01-21 16:11:28 +000076.. code:: c
77
Paul Beesley5981d112019-01-22 11:36:41 +000078 #include <string.h>
79
80 #include <a_dir/example/a_header.h>
81 #include <a_dir/example/b_header.h>
82 #include <a_dir/test/a_header.h>
83 #include <b_dir/example/a_header.h>
84
85 #include "./a_header.h"
86
87Include statement variants
Sandrine Bailleuxf5a91002019-02-08 10:50:28 +010088^^^^^^^^^^^^^^^^^^^^^^^^^^
Paul Beesley5981d112019-01-22 11:36:41 +000089
90Two variants of the ``#include`` directive are acceptable in the TF codebase.
91Correct use of the two styles improves readability by suggesting the location
92of the included header and reducing ambiguity in cases where generic and
93platform-specific headers share a name.
94
95For header files that are in the same directory as the source file that is
96including them, use the ``"..."`` variant.
Paul Beesleyfd688342019-01-21 16:11:28 +000097
Paul Beesley5981d112019-01-22 11:36:41 +000098For header files that are **not** in the same directory as the source file that
99is including them, use the ``<...>`` variant.
Paul Beesleyfd688342019-01-21 16:11:28 +0000100
Paul Beesley5981d112019-01-22 11:36:41 +0000101Example (bl1_fwu.c):
Paul Beesleye5f0f0a2019-01-31 11:39:01 +0000102
Paul Beesley5981d112019-01-22 11:36:41 +0000103.. code:: c
104
105 #include <assert.h>
106 #include <errno.h>
107 #include <string.h>
108
109 #include "bl1_private.h"
110
111Platform include paths
112^^^^^^^^^^^^^^^^^^^^^^
113
114Platforms are allowed to add more include paths to be passed to the compiler.
115The ``PLAT_INCLUDES`` variable is used for this purpose. This is needed in
116particular for the file ``platform_def.h``.
117
118Example:
Paul Beesleye5f0f0a2019-01-31 11:39:01 +0000119
Paul Beesley5981d112019-01-22 11:36:41 +0000120.. code:: c
121
122 PLAT_INCLUDES += -Iinclude/plat/myplat/include
Paul Beesleyfd688342019-01-21 16:11:28 +0000123
124Types and typedefs
125------------------
126
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000127Use of built-in *C* and *libc* data types
Sandrine Bailleuxf5a91002019-02-08 10:50:28 +0100128^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000129
130The TF codebase should be kept as portable as possible, especially since both
13164-bit and 32-bit platforms are supported. To help with this, the following data
132type usage guidelines should be followed:
133
134- Where possible, use the built-in *C* data types for variable storage (for
135 example, ``char``, ``int``, ``long long``, etc) instead of the standard *C99*
136 types. Most code is typically only concerned with the minimum size of the
137 data stored, which the built-in *C* types guarantee.
138
139- Avoid using the exact-size standard *C99* types in general (for example,
140 ``uint16_t``, ``uint32_t``, ``uint64_t``, etc) since they can prevent the
141 compiler from making optimizations. There are legitimate uses for them,
142 for example to represent data of a known structure. When using them in struct
143 definitions, consider how padding in the struct will work across architectures.
144 For example, extra padding may be introduced in AArch32 systems if a struct
145 member crosses a 32-bit boundary.
146
147- Use ``int`` as the default integer type - it's likely to be the fastest on all
148 systems. Also this can be assumed to be 32-bit as a consequence of the
Paul Beesley54c83cf2019-01-21 11:57:42 +0000149 `Procedure Call Standard for the Arm Architecture`_ and the `Procedure Call
150 Standard for the Arm 64-bit Architecture`_ .
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000151
152- Avoid use of ``short`` as this may end up being slower than ``int`` in some
153 systems. If a variable must be exactly 16-bit, use ``int16_t`` or
154 ``uint16_t``.
155
156- Avoid use of ``long``. This is guaranteed to be at least 32-bit but, given
157 that `int` is 32-bit on Arm platforms, there is no use for it. For integers of
158 at least 64-bit, use ``long long``.
159
160- Use ``char`` for storing text. Use ``uint8_t`` for storing other 8-bit data.
161
162- Use ``unsigned`` for integers that can never be negative (counts,
163 indices, sizes, etc). TF intends to comply with MISRA "essential type" coding
164 rules (10.X), where signed and unsigned types are considered different
165 essential types. Choosing the correct type will aid this. MISRA static
166 analysers will pick up any implicit signed/unsigned conversions that may lead
167 to unexpected behaviour.
168
169- For pointer types:
170
171 - If an argument in a function declaration is pointing to a known type then
172 simply use a pointer to that type (for example: ``struct my_struct *``).
173
174 - If a variable (including an argument in a function declaration) is pointing
175 to a general, memory-mapped address, an array of pointers or another
176 structure that is likely to require pointer arithmetic then use
177 ``uintptr_t``. This will reduce the amount of casting required in the code.
178 Avoid using ``unsigned long`` or ``unsigned long long`` for this purpose; it
179 may work but is less portable.
180
181 - For other pointer arguments in a function declaration, use ``void *``. This
182 includes pointers to types that are abstracted away from the known API and
183 pointers to arbitrary data. This allows the calling function to pass a
184 pointer argument to the function without any explicit casting (the cast to
185 ``void *`` is implicit). The function implementation can then do the
186 appropriate casting to a specific type.
187
188 - Use ``ptrdiff_t`` to compare the difference between 2 pointers.
189
190- Use ``size_t`` when storing the ``sizeof()`` something.
191
Paul Beesley244c7832019-01-21 12:02:09 +0000192- Use ``ssize_t`` when returning the ``sizeof()`` something from a function that
193 can also return an error code; the signed type allows for a negative return
194 code in case of error. This practice should be used sparingly.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000195
196- Use ``u_register_t`` when it's important to store the contents of a register
197 in its native size (32-bit in AArch32 and 64-bit in AArch64). This is not a
198 standard *C99* type but is widely available in libc implementations,
199 including the FreeBSD version included with the TF codebase. Where possible,
200 cast the variable to a more appropriate type before interpreting the data. For
201 example, the following struct in ``ep_info.h`` could use this type to minimize
202 the storage required for the set of registers:
203
204.. code:: c
205
206 typedef struct aapcs64_params {
207 u_register_t arg0;
208 u_register_t arg1;
209 u_register_t arg2;
210 u_register_t arg3;
211 u_register_t arg4;
212 u_register_t arg5;
213 u_register_t arg6;
214 u_register_t arg7;
215 } aapcs64_params_t;
216
Sandrine Bailleuxf5a91002019-02-08 10:50:28 +0100217If some code wants to operate on ``arg0`` and knows that it represents a 32-bit
218unsigned integer on all systems, cast it to ``unsigned int``.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000219
220These guidelines should be updated if additional types are needed.
221
Paul Beesleyfd688342019-01-21 16:11:28 +0000222Avoid anonymous typedefs of structs/enums in headers
223^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000224
Paul Beesleyfd688342019-01-21 16:11:28 +0000225For example, the following definition:
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000226
Paul Beesleyfd688342019-01-21 16:11:28 +0000227.. code:: c
228
229 typedef struct {
230 int arg1;
231 int arg2;
232 } my_struct_t;
233
234
235is better written as:
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000236
237.. code:: c
238
Paul Beesleyfd688342019-01-21 16:11:28 +0000239 struct my_struct {
240 int arg1;
241 int arg2;
242 };
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000243
Paul Beesleyfd688342019-01-21 16:11:28 +0000244This allows function declarations in other header files that depend on the
245struct/enum to forward declare the struct/enum instead of including the
246entire header:
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000247
Paul Beesleyfd688342019-01-21 16:11:28 +0000248.. code:: c
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000249
Paul Beesleyfd688342019-01-21 16:11:28 +0000250 #include <my_struct.h>
251 void my_func(my_struct_t *arg);
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000252
Paul Beesleyfd688342019-01-21 16:11:28 +0000253instead of:
254
255.. code:: c
256
257 struct my_struct;
258 void my_func(struct my_struct *arg);
259
260Some TF definitions use both a struct/enum name **and** a typedef name. This
261is discouraged for new definitions as it makes it difficult for TF to comply
262with MISRA rule 8.3, which states that "All declarations of an object or
263function shall use the same names and type qualifiers".
264
265The Linux coding standards also discourage new typedefs and checkpatch emits
266a warning for this.
267
268Existing typedefs will be retained for compatibility.
269
270Error handling and robustness
271-----------------------------
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000272
273Using CASSERT to check for compile time data errors
274^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
275
276Where possible, use the ``CASSERT`` macro to check the validity of data known at
277compile time instead of checking validity at runtime, to avoid unnecessary
278runtime code.
279
280For example, this can be used to check that the assembler's and compiler's views
281of the size of an array is the same.
282
283.. code:: c
284
285 #include <cassert.h>
286
287 define MY_STRUCT_SIZE 8 /* Used by assembler source files */
288
289 struct my_struct {
290 uint32_t arg1;
291 uint32_t arg2;
292 };
293
294 CASSERT(MY_STRUCT_SIZE == sizeof(struct my_struct), assert_my_struct_size_mismatch);
295
296
297If ``MY_STRUCT_SIZE`` in the above example were wrong then the compiler would
298emit an error like this:
299
300.. code:: c
301
302 my_struct.h:10:1: error: size of array ‘assert_my_struct_size_mismatch’ is negative
303
304
305Using assert() to check for programming errors
306^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
307
308In general, each secure world TF image (BL1, BL2, BL31 and BL32) should be
309treated as a tightly integrated package; the image builder should be aware of
310and responsible for all functionality within the image, even if code within that
311image is provided by multiple entities. This allows us to be more aggressive in
312interpreting invalid state or bad function arguments as programming errors using
313``assert()``, including arguments passed across platform porting interfaces.
314This is in contrast to code in a Linux environment, which is less tightly
315integrated and may attempt to be more defensive by passing the error back up the
316call stack.
317
318Where possible, badly written TF code should fail early using ``assert()``. This
319helps reduce the amount of untested conditional code. By default these
320statements are not compiled into release builds, although this can be overridden
321using the ``ENABLE_ASSERTIONS`` build flag.
322
323Examples:
324
325- Bad argument supplied to library function
326- Bad argument provided by platform porting function
327- Internal secure world image state is inconsistent
328
329
330Handling integration errors
331^^^^^^^^^^^^^^^^^^^^^^^^^^^
332
333Each secure world image may be provided by a different entity (for example, a
334Trusted Boot vendor may provide the BL2 image, a TEE vendor may provide the BL32
335image and the OEM/SoC vendor may provide the other images).
336
337An image may contain bugs that are only visible when the images are integrated.
338The system integrator may not even have access to the debug variants of all the
339images in order to check if asserts are firing. For example, the release variant
340of BL1 may have already been burnt into the SoC. Therefore, TF code that detects
341an integration error should _not_ consider this a programming error, and should
342always take action, even in release builds.
343
344If an integration error is considered non-critical it should be treated as a
345recoverable error. If the error is considered critical it should be treated as
346an unexpected unrecoverable error.
347
348Handling recoverable errors
349^^^^^^^^^^^^^^^^^^^^^^^^^^^
350
351The secure world **must not** crash when supplied with bad data from an external
352source. For example, data from the normal world or a hardware device. Similarly,
353the secure world **must not** crash if it detects a non-critical problem within
354itself or the system. It must make every effort to recover from the problem by
355emitting a ``WARN`` message, performing any necessary error handling and
356continuing.
357
358Examples:
359
360- Secure world receives SMC from normal world with bad arguments.
361- Secure world receives SMC from normal world at an unexpected time.
362- BL31 receives SMC from BL32 with bad arguments.
363- BL31 receives SMC from BL32 at unexpected time.
364- Secure world receives recoverable error from hardware device. Retrying the
365 operation may help here.
366- Non-critical secure world service is not functioning correctly.
367- BL31 SPD discovers minor configuration problem with corresponding SP.
368
369Handling unrecoverable errors
370^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
371
372In some cases it may not be possible for the secure world to recover from an
373error. This situation should be handled in one of the following ways:
374
3751. If the unrecoverable error is unexpected then emit an ``ERROR`` message and
376 call ``panic()``. This will end up calling the platform-specific function
377 ``plat_panic_handler()``.
3782. If the unrecoverable error is expected to occur in certain circumstances,
379 then emit an ``ERROR`` message and call the platform-specific function
380 ``plat_error_handler()``.
381
382Cases 1 and 2 are subtly different. A platform may implement ``plat_panic_handler``
383and ``plat_error_handler`` in the same way (for example, by waiting for a secure
384watchdog to time-out or by invoking an interface on the platform's power
385controller to reset the platform). However, ``plat_error_handler`` may take
386additional action for some errors (for example, it may set a flag so the
387platform resets into a different mode). Also, ``plat_panic_handler()`` may
388implement additional debug functionality (for example, invoking a hardware
389breakpoint).
390
391Examples of unexpected unrecoverable errors:
392
393- BL32 receives an unexpected SMC response from BL31 that it is unable to
394 recover from.
395- BL31 Trusted OS SPD code discovers that BL2 has not loaded the corresponding
396 Trusted OS, which is critical for platform operation.
397- Secure world discovers that a critical hardware device is an unexpected and
398 unrecoverable state.
399- Secure world receives an unexpected and unrecoverable error from a critical
400 hardware device.
401- Secure world discovers that it is running on unsupported hardware.
402
403Examples of expected unrecoverable errors:
404
405- BL1/BL2 fails to load the next image due to missing/corrupt firmware on disk.
406- BL1/BL2 fails to authenticate the next image due to an invalid certificate.
407- Secure world continuously receives recoverable errors from a hardware device
408 but is unable to proceed without a valid response.
409
410Handling critical unresponsiveness
411^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
412
413If the secure world is waiting for a response from an external source (for
414example, the normal world or a hardware device) which is critical for continued
415operation, it must not wait indefinitely. It must have a mechanism (for example,
416a secure watchdog) for resetting itself and/or the external source to prevent
417the system from executing in this state indefinitely.
418
419Examples:
420
421- BL1 is waiting for the normal world to raise an SMC to proceed to the next
422 stage of the secure firmware update process.
423- A Trusted OS is waiting for a response from a proxy in the normal world that
424 is critical for continued operation.
425- Secure world is waiting for a hardware response that is critical for continued
426 operation.
427
428Security considerations
429-----------------------
430
431Part of the security of a platform is handling errors correctly, as described in
432the previous section. There are several other security considerations covered in
433this section.
434
435Do not leak secrets to the normal world
436^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
437
438The secure world **must not** leak secrets to the normal world, for example in
439response to an SMC.
440
441Handling Denial of Service attacks
442^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
443
444The secure world **should never** crash or become unusable due to receiving too
445many normal world requests (a *Denial of Service* or *DoS* attack). It should
446have a mechanism for throttling or ignoring normal world requests.
447
Paul Beesleyfd688342019-01-21 16:11:28 +0000448Performance considerations
449--------------------------
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000450
Paul Beesleyfd688342019-01-21 16:11:28 +0000451Avoid printf and use logging macros
452^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000453
Paul Beesleyfd688342019-01-21 16:11:28 +0000454``debug.h`` provides logging macros (for example, ``WARN`` and ``ERROR``)
455which wrap ``tf_log`` and which allow the logging call to be compiled-out
456depending on the ``make`` command. Use these macros to avoid print statements
457being compiled unconditionally into the binary.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000458
Paul Beesleyfd688342019-01-21 16:11:28 +0000459Each logging macro has a numerical log level:
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000460
461.. code:: c
462
Paul Beesleyfd688342019-01-21 16:11:28 +0000463 #define LOG_LEVEL_NONE 0
464 #define LOG_LEVEL_ERROR 10
465 #define LOG_LEVEL_NOTICE 20
466 #define LOG_LEVEL_WARNING 30
467 #define LOG_LEVEL_INFO 40
468 #define LOG_LEVEL_VERBOSE 50
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000469
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000470
Paul Beesleyfd688342019-01-21 16:11:28 +0000471By default, all logging statements with a log level ``<= LOG_LEVEL_INFO`` will
472be compiled into debug builds and all statements with a log level
473``<= LOG_LEVEL_NOTICE`` will be compiled into release builds. This can be
474overridden from the command line or by the platform makefile (although it may be
475necessary to clean the build directory first). For example, to enable
476``VERBOSE`` logging on FVP:
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000477
Paul Beesleyfd688342019-01-21 16:11:28 +0000478``make PLAT=fvp LOG_LEVEL=50 all``
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000479
480Use const data where possible
Paul Beesleyfd688342019-01-21 16:11:28 +0000481^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000482
483For example, the following code:
484
485.. code:: c
486
487 struct my_struct {
488 int arg1;
489 int arg2;
490 };
491
492 void init(struct my_struct *ptr);
493
494 void main(void)
495 {
496 struct my_struct x;
497 x.arg1 = 1;
498 x.arg2 = 2;
499 init(&x);
500 }
501
502is better written as:
503
504.. code:: c
505
506 struct my_struct {
507 int arg1;
508 int arg2;
509 };
510
511 void init(const struct my_struct *ptr);
512
513 void main(void)
514 {
515 const struct my_struct x = { 1, 2 };
516 init(&x);
517 }
518
519This allows the linker to put the data in a read-only data section instead of a
520writeable data section, which may result in a smaller and faster binary. Note
521that this may require dependent functions (``init()`` in the above example) to
522have ``const`` arguments, assuming they don't need to modify the data.
523
Paul Beesleyfd688342019-01-21 16:11:28 +0000524Library and driver code
525-----------------------
526
527TF library code (under ``lib/`` and ``include/lib``) is any code that provides a
528reusable interface to other code, potentially even to code outside of TF.
529
530In some systems drivers must conform to a specific driver framework to provide
531services to the rest of the system. TF has no driver framework and the
532distinction between a driver and library is somewhat subjective.
533
534A driver (under ``drivers/`` and ``include/drivers/``) is defined as code that
535interfaces with hardware via a memory mapped interface.
536
537Some drivers (for example, the Arm CCI driver in ``include/drivers/arm/cci.h``)
538provide a general purpose API to that specific hardware. Other drivers (for
539example, the Arm PL011 console driver in ``drivers/arm/pl011/pl011_console.S``)
540provide a specific hardware implementation of a more abstract library API. In
541the latter case there may potentially be multiple drivers for the same hardware
542device.
543
544Neither libraries nor drivers should depend on platform-specific code. If they
545require platform-specific data (for example, a base address) to operate then
546they should provide an initialization function that takes the platform-specific
547data as arguments.
548
549TF common code (under ``common/`` and ``include/common/``) is code that is re-used
550by other generic (non-platform-specific) TF code. It is effectively internal
551library code.
552
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000553.. _`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 +0000554.. _`Procedure Call Standard for the Arm Architecture`: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042f/IHI0042F_aapcs.pdf
555.. _`Procedure Call Standard for the Arm 64-bit Architecture`: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf