blob: d5ac978828dc1b41e8966aeb2fa191f977dba09e [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
88^^^^^^^^^^^^^^^^^^^^^^^^^
89
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
Paul Beesleyfd688342019-01-21 16:11:28 +0000128^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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
217
218 If some code wants to operate on ``arg0`` and knows that it represents a
219 32-bit unsigned integer on all systems, cast it to ``unsigned int``.
220
221These guidelines should be updated if additional types are needed.
222
Paul Beesleyfd688342019-01-21 16:11:28 +0000223Avoid anonymous typedefs of structs/enums in headers
224^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000225
Paul Beesleyfd688342019-01-21 16:11:28 +0000226For example, the following definition:
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000227
Paul Beesleyfd688342019-01-21 16:11:28 +0000228.. code:: c
229
230 typedef struct {
231 int arg1;
232 int arg2;
233 } my_struct_t;
234
235
236is better written as:
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000237
238.. code:: c
239
Paul Beesleyfd688342019-01-21 16:11:28 +0000240 struct my_struct {
241 int arg1;
242 int arg2;
243 };
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000244
Paul Beesleyfd688342019-01-21 16:11:28 +0000245This allows function declarations in other header files that depend on the
246struct/enum to forward declare the struct/enum instead of including the
247entire header:
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000248
Paul Beesleyfd688342019-01-21 16:11:28 +0000249.. code:: c
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000250
Paul Beesleyfd688342019-01-21 16:11:28 +0000251 #include <my_struct.h>
252 void my_func(my_struct_t *arg);
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000253
Paul Beesleyfd688342019-01-21 16:11:28 +0000254instead of:
255
256.. code:: c
257
258 struct my_struct;
259 void my_func(struct my_struct *arg);
260
261Some TF definitions use both a struct/enum name **and** a typedef name. This
262is discouraged for new definitions as it makes it difficult for TF to comply
263with MISRA rule 8.3, which states that "All declarations of an object or
264function shall use the same names and type qualifiers".
265
266The Linux coding standards also discourage new typedefs and checkpatch emits
267a warning for this.
268
269Existing typedefs will be retained for compatibility.
270
271Error handling and robustness
272-----------------------------
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000273
274Using CASSERT to check for compile time data errors
275^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
276
277Where possible, use the ``CASSERT`` macro to check the validity of data known at
278compile time instead of checking validity at runtime, to avoid unnecessary
279runtime code.
280
281For example, this can be used to check that the assembler's and compiler's views
282of the size of an array is the same.
283
284.. code:: c
285
286 #include <cassert.h>
287
288 define MY_STRUCT_SIZE 8 /* Used by assembler source files */
289
290 struct my_struct {
291 uint32_t arg1;
292 uint32_t arg2;
293 };
294
295 CASSERT(MY_STRUCT_SIZE == sizeof(struct my_struct), assert_my_struct_size_mismatch);
296
297
298If ``MY_STRUCT_SIZE`` in the above example were wrong then the compiler would
299emit an error like this:
300
301.. code:: c
302
303 my_struct.h:10:1: error: size of array ‘assert_my_struct_size_mismatch’ is negative
304
305
306Using assert() to check for programming errors
307^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
308
309In general, each secure world TF image (BL1, BL2, BL31 and BL32) should be
310treated as a tightly integrated package; the image builder should be aware of
311and responsible for all functionality within the image, even if code within that
312image is provided by multiple entities. This allows us to be more aggressive in
313interpreting invalid state or bad function arguments as programming errors using
314``assert()``, including arguments passed across platform porting interfaces.
315This is in contrast to code in a Linux environment, which is less tightly
316integrated and may attempt to be more defensive by passing the error back up the
317call stack.
318
319Where possible, badly written TF code should fail early using ``assert()``. This
320helps reduce the amount of untested conditional code. By default these
321statements are not compiled into release builds, although this can be overridden
322using the ``ENABLE_ASSERTIONS`` build flag.
323
324Examples:
325
326- Bad argument supplied to library function
327- Bad argument provided by platform porting function
328- Internal secure world image state is inconsistent
329
330
331Handling integration errors
332^^^^^^^^^^^^^^^^^^^^^^^^^^^
333
334Each secure world image may be provided by a different entity (for example, a
335Trusted Boot vendor may provide the BL2 image, a TEE vendor may provide the BL32
336image and the OEM/SoC vendor may provide the other images).
337
338An image may contain bugs that are only visible when the images are integrated.
339The system integrator may not even have access to the debug variants of all the
340images in order to check if asserts are firing. For example, the release variant
341of BL1 may have already been burnt into the SoC. Therefore, TF code that detects
342an integration error should _not_ consider this a programming error, and should
343always take action, even in release builds.
344
345If an integration error is considered non-critical it should be treated as a
346recoverable error. If the error is considered critical it should be treated as
347an unexpected unrecoverable error.
348
349Handling recoverable errors
350^^^^^^^^^^^^^^^^^^^^^^^^^^^
351
352The secure world **must not** crash when supplied with bad data from an external
353source. For example, data from the normal world or a hardware device. Similarly,
354the secure world **must not** crash if it detects a non-critical problem within
355itself or the system. It must make every effort to recover from the problem by
356emitting a ``WARN`` message, performing any necessary error handling and
357continuing.
358
359Examples:
360
361- Secure world receives SMC from normal world with bad arguments.
362- Secure world receives SMC from normal world at an unexpected time.
363- BL31 receives SMC from BL32 with bad arguments.
364- BL31 receives SMC from BL32 at unexpected time.
365- Secure world receives recoverable error from hardware device. Retrying the
366 operation may help here.
367- Non-critical secure world service is not functioning correctly.
368- BL31 SPD discovers minor configuration problem with corresponding SP.
369
370Handling unrecoverable errors
371^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
372
373In some cases it may not be possible for the secure world to recover from an
374error. This situation should be handled in one of the following ways:
375
3761. If the unrecoverable error is unexpected then emit an ``ERROR`` message and
377 call ``panic()``. This will end up calling the platform-specific function
378 ``plat_panic_handler()``.
3792. If the unrecoverable error is expected to occur in certain circumstances,
380 then emit an ``ERROR`` message and call the platform-specific function
381 ``plat_error_handler()``.
382
383Cases 1 and 2 are subtly different. A platform may implement ``plat_panic_handler``
384and ``plat_error_handler`` in the same way (for example, by waiting for a secure
385watchdog to time-out or by invoking an interface on the platform's power
386controller to reset the platform). However, ``plat_error_handler`` may take
387additional action for some errors (for example, it may set a flag so the
388platform resets into a different mode). Also, ``plat_panic_handler()`` may
389implement additional debug functionality (for example, invoking a hardware
390breakpoint).
391
392Examples of unexpected unrecoverable errors:
393
394- BL32 receives an unexpected SMC response from BL31 that it is unable to
395 recover from.
396- BL31 Trusted OS SPD code discovers that BL2 has not loaded the corresponding
397 Trusted OS, which is critical for platform operation.
398- Secure world discovers that a critical hardware device is an unexpected and
399 unrecoverable state.
400- Secure world receives an unexpected and unrecoverable error from a critical
401 hardware device.
402- Secure world discovers that it is running on unsupported hardware.
403
404Examples of expected unrecoverable errors:
405
406- BL1/BL2 fails to load the next image due to missing/corrupt firmware on disk.
407- BL1/BL2 fails to authenticate the next image due to an invalid certificate.
408- Secure world continuously receives recoverable errors from a hardware device
409 but is unable to proceed without a valid response.
410
411Handling critical unresponsiveness
412^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
413
414If the secure world is waiting for a response from an external source (for
415example, the normal world or a hardware device) which is critical for continued
416operation, it must not wait indefinitely. It must have a mechanism (for example,
417a secure watchdog) for resetting itself and/or the external source to prevent
418the system from executing in this state indefinitely.
419
420Examples:
421
422- BL1 is waiting for the normal world to raise an SMC to proceed to the next
423 stage of the secure firmware update process.
424- A Trusted OS is waiting for a response from a proxy in the normal world that
425 is critical for continued operation.
426- Secure world is waiting for a hardware response that is critical for continued
427 operation.
428
429Security considerations
430-----------------------
431
432Part of the security of a platform is handling errors correctly, as described in
433the previous section. There are several other security considerations covered in
434this section.
435
436Do not leak secrets to the normal world
437^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
438
439The secure world **must not** leak secrets to the normal world, for example in
440response to an SMC.
441
442Handling Denial of Service attacks
443^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
444
445The secure world **should never** crash or become unusable due to receiving too
446many normal world requests (a *Denial of Service* or *DoS* attack). It should
447have a mechanism for throttling or ignoring normal world requests.
448
Paul Beesleyfd688342019-01-21 16:11:28 +0000449Performance considerations
450--------------------------
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000451
Paul Beesleyfd688342019-01-21 16:11:28 +0000452Avoid printf and use logging macros
453^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000454
Paul Beesleyfd688342019-01-21 16:11:28 +0000455``debug.h`` provides logging macros (for example, ``WARN`` and ``ERROR``)
456which wrap ``tf_log`` and which allow the logging call to be compiled-out
457depending on the ``make`` command. Use these macros to avoid print statements
458being compiled unconditionally into the binary.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000459
Paul Beesleyfd688342019-01-21 16:11:28 +0000460Each logging macro has a numerical log level:
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000461
462.. code:: c
463
Paul Beesleyfd688342019-01-21 16:11:28 +0000464 #define LOG_LEVEL_NONE 0
465 #define LOG_LEVEL_ERROR 10
466 #define LOG_LEVEL_NOTICE 20
467 #define LOG_LEVEL_WARNING 30
468 #define LOG_LEVEL_INFO 40
469 #define LOG_LEVEL_VERBOSE 50
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000470
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000471
Paul Beesleyfd688342019-01-21 16:11:28 +0000472By default, all logging statements with a log level ``<= LOG_LEVEL_INFO`` will
473be compiled into debug builds and all statements with a log level
474``<= LOG_LEVEL_NOTICE`` will be compiled into release builds. This can be
475overridden from the command line or by the platform makefile (although it may be
476necessary to clean the build directory first). For example, to enable
477``VERBOSE`` logging on FVP:
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000478
Paul Beesleyfd688342019-01-21 16:11:28 +0000479``make PLAT=fvp LOG_LEVEL=50 all``
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000480
481Use const data where possible
Paul Beesleyfd688342019-01-21 16:11:28 +0000482^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000483
484For example, the following code:
485
486.. code:: c
487
488 struct my_struct {
489 int arg1;
490 int arg2;
491 };
492
493 void init(struct my_struct *ptr);
494
495 void main(void)
496 {
497 struct my_struct x;
498 x.arg1 = 1;
499 x.arg2 = 2;
500 init(&x);
501 }
502
503is better written as:
504
505.. code:: c
506
507 struct my_struct {
508 int arg1;
509 int arg2;
510 };
511
512 void init(const struct my_struct *ptr);
513
514 void main(void)
515 {
516 const struct my_struct x = { 1, 2 };
517 init(&x);
518 }
519
520This allows the linker to put the data in a read-only data section instead of a
521writeable data section, which may result in a smaller and faster binary. Note
522that this may require dependent functions (``init()`` in the above example) to
523have ``const`` arguments, assuming they don't need to modify the data.
524
Paul Beesleyfd688342019-01-21 16:11:28 +0000525Library and driver code
526-----------------------
527
528TF library code (under ``lib/`` and ``include/lib``) is any code that provides a
529reusable interface to other code, potentially even to code outside of TF.
530
531In some systems drivers must conform to a specific driver framework to provide
532services to the rest of the system. TF has no driver framework and the
533distinction between a driver and library is somewhat subjective.
534
535A driver (under ``drivers/`` and ``include/drivers/``) is defined as code that
536interfaces with hardware via a memory mapped interface.
537
538Some drivers (for example, the Arm CCI driver in ``include/drivers/arm/cci.h``)
539provide a general purpose API to that specific hardware. Other drivers (for
540example, the Arm PL011 console driver in ``drivers/arm/pl011/pl011_console.S``)
541provide a specific hardware implementation of a more abstract library API. In
542the latter case there may potentially be multiple drivers for the same hardware
543device.
544
545Neither libraries nor drivers should depend on platform-specific code. If they
546require platform-specific data (for example, a base address) to operate then
547they should provide an initialization function that takes the platform-specific
548data as arguments.
549
550TF common code (under ``common/`` and ``include/common/``) is code that is re-used
551by other generic (non-platform-specific) TF code. It is effectively internal
552library code.
553
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000554.. _`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 +0000555.. _`Procedure Call Standard for the Arm Architecture`: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042f/IHI0042F_aapcs.pdf
556.. _`Procedure Call Standard for the Arm 64-bit Architecture`: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf