blob: f7d53a97ebf6b786831e2a73fd1ba6296d559e36 [file] [log] [blame]
Paul Beesley07f0a312019-05-16 13:33:18 +01001Coding Guidelines
2=================
Paul Beesley4e2e1b22019-01-17 15:44:37 +00003
Paul Beesley07f0a312019-05-16 13:33:18 +01004This document provides some additional guidelines to consider when writing
5|TF-A| code. These are not intended to be strictly-enforced rules like the
6contents of the :ref:`Coding Style`.
Paul Beesley4e2e1b22019-01-17 15:44:37 +00007
Paul Beesley07f0a312019-05-16 13:33:18 +01008Automatic Editor Configuration
9------------------------------
Paul Beesley4e2e1b22019-01-17 15:44:37 +000010
Paul Beesley07f0a312019-05-16 13:33:18 +010011Many of the rules given below (such as indentation size, use of tabs, and
12newlines) can be set automatically using the `EditorConfig`_ configuration file
13in the root of the repository: ``.editorconfig``. With a supported editor, the
14rules set out in this file can be automatically applied when you are editing
15files in the |TF-A| repository.
Paul Beesleyfd688342019-01-21 16:11:28 +000016
Paul Beesley07f0a312019-05-16 13:33:18 +010017Several editors include built-in support for EditorConfig files, and many others
18support its functionality through plugins.
Paul Beesleyfd688342019-01-21 16:11:28 +000019
Paul Beesley07f0a312019-05-16 13:33:18 +010020Use of the EditorConfig file is suggested but is not required.
Paul Beesleyfd688342019-01-21 16:11:28 +000021
Paul Beesleyfd688342019-01-21 16:11:28 +000022
Paul Beesley07f0a312019-05-16 13:33:18 +010023Automatic Compliance Checking
24-----------------------------
Paul Beesleyfd688342019-01-21 16:11:28 +000025
Paul Beesley07f0a312019-05-16 13:33:18 +010026To assist with coding style compliance, the project Makefile contains two
27targets which both utilise the `checkpatch.pl` script that ships with the Linux
28source tree. The project also defines certain *checkpatch* options in the
29``.checkpatch.conf`` file in the top-level directory.
Paul Beesleyfd688342019-01-21 16:11:28 +000030
Paul Beesley07f0a312019-05-16 13:33:18 +010031.. note::
32 Checkpatch errors will gate upstream merging of pull requests.
33 Checkpatch warnings will not gate merging but should be reviewed and fixed if
34 possible.
Paul Beesley4e2e1b22019-01-17 15:44:37 +000035
Paul Beesley07f0a312019-05-16 13:33:18 +010036To check the entire source tree, you must first download copies of
37``checkpatch.pl``, ``spelling.txt`` and ``const_structs.checkpatch`` available
38in the `Linux master tree`_ *scripts* directory, then set the ``CHECKPATCH``
39environment variable to point to ``checkpatch.pl`` (with the other 2 files in
40the same directory) and build the `checkcodebase` target:
Paul Beesley4e2e1b22019-01-17 15:44:37 +000041
Paul Beesley07f0a312019-05-16 13:33:18 +010042.. code:: shell
Paul Beesley4e2e1b22019-01-17 15:44:37 +000043
Paul Beesley07f0a312019-05-16 13:33:18 +010044 make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkcodebase
Paul Beesley4e2e1b22019-01-17 15:44:37 +000045
Paul Beesley07f0a312019-05-16 13:33:18 +010046To just check the style on the files that differ between your local branch and
47the remote master, use:
Paul Beesley4e2e1b22019-01-17 15:44:37 +000048
Paul Beesley07f0a312019-05-16 13:33:18 +010049.. code:: shell
Paul Beesley4e2e1b22019-01-17 15:44:37 +000050
Paul Beesley07f0a312019-05-16 13:33:18 +010051 make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkpatch
Paul Beesley4e2e1b22019-01-17 15:44:37 +000052
Paul Beesley07f0a312019-05-16 13:33:18 +010053If you wish to check your patch against something other than the remote master,
54set the ``BASE_COMMIT`` variable to your desired branch. By default,
55``BASE_COMMIT`` is set to ``origin/master``.
Paul Beesley4e2e1b22019-01-17 15:44:37 +000056
Paul Beesley07f0a312019-05-16 13:33:18 +010057Ignored Checkpatch Warnings
58^^^^^^^^^^^^^^^^^^^^^^^^^^^
Paul Beesley4e2e1b22019-01-17 15:44:37 +000059
Paul Beesley07f0a312019-05-16 13:33:18 +010060Some checkpatch warnings in the TF codebase are deliberately ignored. These
61include:
Paul Beesley4e2e1b22019-01-17 15:44:37 +000062
Paul Beesley07f0a312019-05-16 13:33:18 +010063- ``**WARNING: line over 80 characters**``: Although the codebase should
64 generally conform to the 80 character limit this is overly restrictive in some
65 cases.
Paul Beesley4e2e1b22019-01-17 15:44:37 +000066
Paul Beesley07f0a312019-05-16 13:33:18 +010067- ``**WARNING: Use of volatile is usually wrong``: see
68 `Why the “volatile” type class should not be used`_ . Although this document
69 contains some very useful information, there are several legimate uses of the
70 volatile keyword within the TF codebase.
Paul Beesley4e2e1b22019-01-17 15:44:37 +000071
Paul Beesley07f0a312019-05-16 13:33:18 +010072Performance considerations
73--------------------------
Paul Beesley4e2e1b22019-01-17 15:44:37 +000074
Paul Beesley07f0a312019-05-16 13:33:18 +010075Avoid printf and use logging macros
76^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Paul Beesley4e2e1b22019-01-17 15:44:37 +000077
Paul Beesley07f0a312019-05-16 13:33:18 +010078``debug.h`` provides logging macros (for example, ``WARN`` and ``ERROR``)
79which wrap ``tf_log`` and which allow the logging call to be compiled-out
80depending on the ``make`` command. Use these macros to avoid print statements
81being compiled unconditionally into the binary.
Paul Beesley4e2e1b22019-01-17 15:44:37 +000082
Paul Beesley07f0a312019-05-16 13:33:18 +010083Each logging macro has a numerical log level:
Paul Beesley4e2e1b22019-01-17 15:44:37 +000084
85.. code:: c
86
Paul Beesley07f0a312019-05-16 13:33:18 +010087 #define LOG_LEVEL_NONE 0
88 #define LOG_LEVEL_ERROR 10
89 #define LOG_LEVEL_NOTICE 20
90 #define LOG_LEVEL_WARNING 30
91 #define LOG_LEVEL_INFO 40
92 #define LOG_LEVEL_VERBOSE 50
Paul Beesley4e2e1b22019-01-17 15:44:37 +000093
Paul Beesley07f0a312019-05-16 13:33:18 +010094By default, all logging statements with a log level ``<= LOG_LEVEL_INFO`` will
95be compiled into debug builds and all statements with a log level
96``<= LOG_LEVEL_NOTICE`` will be compiled into release builds. This can be
97overridden from the command line or by the platform makefile (although it may be
98necessary to clean the build directory first). For example, to enable
99``VERBOSE`` logging on FVP:
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000100
Paul Beesley07f0a312019-05-16 13:33:18 +0100101``make PLAT=fvp LOG_LEVEL=50 all``
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000102
Paul Beesley07f0a312019-05-16 13:33:18 +0100103Use const data where possible
104^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000105
Paul Beesley07f0a312019-05-16 13:33:18 +0100106For example, the following code:
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000107
Paul Beesleyfd688342019-01-21 16:11:28 +0000108.. code:: c
109
Paul Beesley07f0a312019-05-16 13:33:18 +0100110 struct my_struct {
Paul Beesleyfd688342019-01-21 16:11:28 +0000111 int arg1;
112 int arg2;
Paul Beesley07f0a312019-05-16 13:33:18 +0100113 };
Paul Beesleyfd688342019-01-21 16:11:28 +0000114
Paul Beesley07f0a312019-05-16 13:33:18 +0100115 void init(struct my_struct *ptr);
116
117 void main(void)
118 {
119 struct my_struct x;
120 x.arg1 = 1;
121 x.arg2 = 2;
122 init(&x);
123 }
Paul Beesleyfd688342019-01-21 16:11:28 +0000124
125is better written as:
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000126
127.. code:: c
128
Paul Beesleyfd688342019-01-21 16:11:28 +0000129 struct my_struct {
130 int arg1;
131 int arg2;
132 };
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000133
Paul Beesley07f0a312019-05-16 13:33:18 +0100134 void init(const struct my_struct *ptr);
Paul Beesleyfd688342019-01-21 16:11:28 +0000135
Paul Beesley07f0a312019-05-16 13:33:18 +0100136 void main(void)
137 {
138 const struct my_struct x = { 1, 2 };
139 init(&x);
140 }
Paul Beesleyfd688342019-01-21 16:11:28 +0000141
Paul Beesley07f0a312019-05-16 13:33:18 +0100142This allows the linker to put the data in a read-only data section instead of a
143writeable data section, which may result in a smaller and faster binary. Note
144that this may require dependent functions (``init()`` in the above example) to
145have ``const`` arguments, assuming they don't need to modify the data.
Paul Beesleyfd688342019-01-21 16:11:28 +0000146
Soby Mathew497092d2019-06-20 12:46:11 +0100147Libc functions that are banned or to be used with caution
148---------------------------------------------------------
149
150Below is a list of functions that present security risks and either must not be
151used (Banned) or are discouraged from use and must be used with care (Caution).
152
153+------------------------+-----------+--------------------------------------+
154| libc function | Status | Comments |
155+========================+===========+======================================+
John Tsichritzis890f3f02019-07-09 18:09:03 +0100156| ``strcpy, wcscpy``, | Banned | use strlcpy instead |
Soby Mathew497092d2019-06-20 12:46:11 +0100157| ``strncpy`` | | |
158+------------------------+-----------+--------------------------------------+
John Tsichritzis890f3f02019-07-09 18:09:03 +0100159| ``strcat, wcscat``, | Banned | use strlcat instead |
Soby Mathew497092d2019-06-20 12:46:11 +0100160| ``strncat`` | | |
John Tsichritzis890f3f02019-07-09 18:09:03 +0100161+------------------------+-----------+--------------------------------------+
Soby Mathew497092d2019-06-20 12:46:11 +0100162| ``sprintf, vsprintf`` | Banned | use snprintf, vsnprintf |
163| | | instead |
John Tsichritzis890f3f02019-07-09 18:09:03 +0100164+------------------------+-----------+--------------------------------------+
Soby Mathew497092d2019-06-20 12:46:11 +0100165| ``snprintf`` | Caution | ensure result fits in buffer |
166| | | i.e : snprintf(buf,size...) < size |
167+------------------------+-----------+--------------------------------------+
168| ``vsnprintf`` | Caution | inspect va_list match types |
169| | | specified in format string |
170+------------------------+-----------+--------------------------------------+
171| ``strtok`` | Banned | use strtok_r or strsep instead |
172+------------------------+-----------+--------------------------------------+
173| ``strtok_r, strsep`` | Caution | inspect for terminated input buffer |
174+------------------------+-----------+--------------------------------------+
175| ``ato*`` | Banned | use equivalent strto* functions |
176+------------------------+-----------+--------------------------------------+
177| ``*toa`` | Banned | Use snprintf instead |
178+------------------------+-----------+--------------------------------------+
179
180The `libc` component in the codebase will not add support for the banned APIs.
181
Paul Beesleyfd688342019-01-21 16:11:28 +0000182Error handling and robustness
183-----------------------------
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000184
185Using CASSERT to check for compile time data errors
186^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
187
188Where possible, use the ``CASSERT`` macro to check the validity of data known at
189compile time instead of checking validity at runtime, to avoid unnecessary
190runtime code.
191
192For example, this can be used to check that the assembler's and compiler's views
193of the size of an array is the same.
194
195.. code:: c
196
197 #include <cassert.h>
198
199 define MY_STRUCT_SIZE 8 /* Used by assembler source files */
200
201 struct my_struct {
202 uint32_t arg1;
203 uint32_t arg2;
204 };
205
206 CASSERT(MY_STRUCT_SIZE == sizeof(struct my_struct), assert_my_struct_size_mismatch);
207
208
209If ``MY_STRUCT_SIZE`` in the above example were wrong then the compiler would
210emit an error like this:
211
Paul Beesley493e3492019-03-13 15:11:04 +0000212::
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000213
214 my_struct.h:10:1: error: size of array ‘assert_my_struct_size_mismatch’ is negative
215
216
217Using assert() to check for programming errors
218^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
219
220In general, each secure world TF image (BL1, BL2, BL31 and BL32) should be
221treated as a tightly integrated package; the image builder should be aware of
222and responsible for all functionality within the image, even if code within that
223image is provided by multiple entities. This allows us to be more aggressive in
224interpreting invalid state or bad function arguments as programming errors using
225``assert()``, including arguments passed across platform porting interfaces.
226This is in contrast to code in a Linux environment, which is less tightly
227integrated and may attempt to be more defensive by passing the error back up the
228call stack.
229
230Where possible, badly written TF code should fail early using ``assert()``. This
231helps reduce the amount of untested conditional code. By default these
232statements are not compiled into release builds, although this can be overridden
233using the ``ENABLE_ASSERTIONS`` build flag.
234
235Examples:
236
237- Bad argument supplied to library function
238- Bad argument provided by platform porting function
239- Internal secure world image state is inconsistent
240
241
242Handling integration errors
243^^^^^^^^^^^^^^^^^^^^^^^^^^^
244
245Each secure world image may be provided by a different entity (for example, a
246Trusted Boot vendor may provide the BL2 image, a TEE vendor may provide the BL32
247image and the OEM/SoC vendor may provide the other images).
248
249An image may contain bugs that are only visible when the images are integrated.
250The system integrator may not even have access to the debug variants of all the
251images in order to check if asserts are firing. For example, the release variant
252of BL1 may have already been burnt into the SoC. Therefore, TF code that detects
253an integration error should _not_ consider this a programming error, and should
254always take action, even in release builds.
255
256If an integration error is considered non-critical it should be treated as a
257recoverable error. If the error is considered critical it should be treated as
258an unexpected unrecoverable error.
259
260Handling recoverable errors
261^^^^^^^^^^^^^^^^^^^^^^^^^^^
262
263The secure world **must not** crash when supplied with bad data from an external
264source. For example, data from the normal world or a hardware device. Similarly,
265the secure world **must not** crash if it detects a non-critical problem within
266itself or the system. It must make every effort to recover from the problem by
267emitting a ``WARN`` message, performing any necessary error handling and
268continuing.
269
270Examples:
271
272- Secure world receives SMC from normal world with bad arguments.
273- Secure world receives SMC from normal world at an unexpected time.
274- BL31 receives SMC from BL32 with bad arguments.
275- BL31 receives SMC from BL32 at unexpected time.
276- Secure world receives recoverable error from hardware device. Retrying the
277 operation may help here.
278- Non-critical secure world service is not functioning correctly.
279- BL31 SPD discovers minor configuration problem with corresponding SP.
280
281Handling unrecoverable errors
282^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
283
284In some cases it may not be possible for the secure world to recover from an
285error. This situation should be handled in one of the following ways:
286
2871. If the unrecoverable error is unexpected then emit an ``ERROR`` message and
288 call ``panic()``. This will end up calling the platform-specific function
289 ``plat_panic_handler()``.
2902. If the unrecoverable error is expected to occur in certain circumstances,
291 then emit an ``ERROR`` message and call the platform-specific function
292 ``plat_error_handler()``.
293
Paul Beesley07f0a312019-05-16 13:33:18 +0100294Cases 1 and 2 are subtly different. A platform may implement
295``plat_panic_handler`` and ``plat_error_handler`` in the same way (for example,
296by waiting for a secure watchdog to time-out or by invoking an interface on the
297platform's power controller to reset the platform). However,
298``plat_error_handler`` may take additional action for some errors (for example,
299it may set a flag so the platform resets into a different mode). Also,
300``plat_panic_handler()`` may implement additional debug functionality (for
301example, invoking a hardware breakpoint).
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000302
303Examples of unexpected unrecoverable errors:
304
305- BL32 receives an unexpected SMC response from BL31 that it is unable to
306 recover from.
307- BL31 Trusted OS SPD code discovers that BL2 has not loaded the corresponding
308 Trusted OS, which is critical for platform operation.
309- Secure world discovers that a critical hardware device is an unexpected and
310 unrecoverable state.
311- Secure world receives an unexpected and unrecoverable error from a critical
312 hardware device.
313- Secure world discovers that it is running on unsupported hardware.
314
315Examples of expected unrecoverable errors:
316
317- BL1/BL2 fails to load the next image due to missing/corrupt firmware on disk.
318- BL1/BL2 fails to authenticate the next image due to an invalid certificate.
319- Secure world continuously receives recoverable errors from a hardware device
320 but is unable to proceed without a valid response.
321
322Handling critical unresponsiveness
323^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
324
325If the secure world is waiting for a response from an external source (for
326example, the normal world or a hardware device) which is critical for continued
327operation, it must not wait indefinitely. It must have a mechanism (for example,
328a secure watchdog) for resetting itself and/or the external source to prevent
329the system from executing in this state indefinitely.
330
331Examples:
332
333- BL1 is waiting for the normal world to raise an SMC to proceed to the next
334 stage of the secure firmware update process.
335- A Trusted OS is waiting for a response from a proxy in the normal world that
336 is critical for continued operation.
337- Secure world is waiting for a hardware response that is critical for continued
338 operation.
339
Paul Beesley07f0a312019-05-16 13:33:18 +0100340Use of built-in *C* and *libc* data types
341-----------------------------------------
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000342
Paul Beesley07f0a312019-05-16 13:33:18 +0100343The |TF-A| codebase should be kept as portable as possible, especially since
344both 64-bit and 32-bit platforms are supported. To help with this, the following
345data type usage guidelines should be followed:
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000346
Paul Beesley07f0a312019-05-16 13:33:18 +0100347- Where possible, use the built-in *C* data types for variable storage (for
348 example, ``char``, ``int``, ``long long``, etc) instead of the standard *C99*
349 types. Most code is typically only concerned with the minimum size of the
350 data stored, which the built-in *C* types guarantee.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000351
Paul Beesley07f0a312019-05-16 13:33:18 +0100352- Avoid using the exact-size standard *C99* types in general (for example,
353 ``uint16_t``, ``uint32_t``, ``uint64_t``, etc) since they can prevent the
354 compiler from making optimizations. There are legitimate uses for them,
355 for example to represent data of a known structure. When using them in struct
356 definitions, consider how padding in the struct will work across architectures.
357 For example, extra padding may be introduced in |AArch32| systems if a struct
358 member crosses a 32-bit boundary.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000359
Paul Beesley07f0a312019-05-16 13:33:18 +0100360- Use ``int`` as the default integer type - it's likely to be the fastest on all
361 systems. Also this can be assumed to be 32-bit as a consequence of the
362 `Procedure Call Standard for the Arm Architecture`_ and the `Procedure Call
363 Standard for the Arm 64-bit Architecture`_ .
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000364
Paul Beesley07f0a312019-05-16 13:33:18 +0100365- Avoid use of ``short`` as this may end up being slower than ``int`` in some
366 systems. If a variable must be exactly 16-bit, use ``int16_t`` or
367 ``uint16_t``.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000368
Paul Beesley07f0a312019-05-16 13:33:18 +0100369- Avoid use of ``long``. This is guaranteed to be at least 32-bit but, given
370 that `int` is 32-bit on Arm platforms, there is no use for it. For integers of
371 at least 64-bit, use ``long long``.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000372
Paul Beesley07f0a312019-05-16 13:33:18 +0100373- Use ``char`` for storing text. Use ``uint8_t`` for storing other 8-bit data.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000374
Paul Beesley07f0a312019-05-16 13:33:18 +0100375- Use ``unsigned`` for integers that can never be negative (counts,
376 indices, sizes, etc). TF intends to comply with MISRA "essential type" coding
377 rules (10.X), where signed and unsigned types are considered different
378 essential types. Choosing the correct type will aid this. MISRA static
379 analysers will pick up any implicit signed/unsigned conversions that may lead
380 to unexpected behaviour.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000381
Paul Beesley07f0a312019-05-16 13:33:18 +0100382- For pointer types:
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000383
Paul Beesley07f0a312019-05-16 13:33:18 +0100384 - If an argument in a function declaration is pointing to a known type then
385 simply use a pointer to that type (for example: ``struct my_struct *``).
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000386
Paul Beesley07f0a312019-05-16 13:33:18 +0100387 - If a variable (including an argument in a function declaration) is pointing
388 to a general, memory-mapped address, an array of pointers or another
389 structure that is likely to require pointer arithmetic then use
390 ``uintptr_t``. This will reduce the amount of casting required in the code.
391 Avoid using ``unsigned long`` or ``unsigned long long`` for this purpose; it
392 may work but is less portable.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000393
Paul Beesley07f0a312019-05-16 13:33:18 +0100394 - For other pointer arguments in a function declaration, use ``void *``. This
395 includes pointers to types that are abstracted away from the known API and
396 pointers to arbitrary data. This allows the calling function to pass a
397 pointer argument to the function without any explicit casting (the cast to
398 ``void *`` is implicit). The function implementation can then do the
399 appropriate casting to a specific type.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000400
Paul Beesley07f0a312019-05-16 13:33:18 +0100401 - Avoid pointer arithmetic generally (as this violates MISRA C 2012 rule
402 18.4) and especially on void pointers (as this is only supported via
403 language extensions and is considered non-standard). In TF-A, setting the
404 ``W`` build flag to ``W=3`` enables the *-Wpointer-arith* compiler flag and
405 this will emit warnings where pointer arithmetic is used.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000406
Paul Beesley07f0a312019-05-16 13:33:18 +0100407 - Use ``ptrdiff_t`` to compare the difference between 2 pointers.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000408
Paul Beesley07f0a312019-05-16 13:33:18 +0100409- Use ``size_t`` when storing the ``sizeof()`` something.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000410
Paul Beesley07f0a312019-05-16 13:33:18 +0100411- Use ``ssize_t`` when returning the ``sizeof()`` something from a function that
412 can also return an error code; the signed type allows for a negative return
413 code in case of error. This practice should be used sparingly.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000414
Paul Beesley07f0a312019-05-16 13:33:18 +0100415- Use ``u_register_t`` when it's important to store the contents of a register
416 in its native size (32-bit in |AArch32| and 64-bit in |AArch64|). This is not a
417 standard *C99* type but is widely available in libc implementations,
418 including the FreeBSD version included with the TF codebase. Where possible,
419 cast the variable to a more appropriate type before interpreting the data. For
420 example, the following struct in ``ep_info.h`` could use this type to minimize
421 the storage required for the set of registers:
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000422
423.. code:: c
424
Paul Beesley07f0a312019-05-16 13:33:18 +0100425 typedef struct aapcs64_params {
426 u_register_t arg0;
427 u_register_t arg1;
428 u_register_t arg2;
429 u_register_t arg3;
430 u_register_t arg4;
431 u_register_t arg5;
432 u_register_t arg6;
433 u_register_t arg7;
434 } aapcs64_params_t;
Paul Beesleyfd688342019-01-21 16:11:28 +0000435
Paul Beesley07f0a312019-05-16 13:33:18 +0100436If some code wants to operate on ``arg0`` and knows that it represents a 32-bit
437unsigned integer on all systems, cast it to ``unsigned int``.
Paul Beesleyfd688342019-01-21 16:11:28 +0000438
Paul Beesley07f0a312019-05-16 13:33:18 +0100439These guidelines should be updated if additional types are needed.
Paul Beesleyfd688342019-01-21 16:11:28 +0000440
Paul Beesley07f0a312019-05-16 13:33:18 +0100441--------------
Paul Beesleyfd688342019-01-21 16:11:28 +0000442
Paul Beesley07f0a312019-05-16 13:33:18 +0100443*Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.*
Paul Beesleyfd688342019-01-21 16:11:28 +0000444
Paul Beesley07f0a312019-05-16 13:33:18 +0100445.. _`Linux master tree`: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/
446.. _`Procedure Call Standard for the Arm Architecture`: https://developer.arm.com/docs/ihi0042/latest/
447.. _`Procedure Call Standard for the Arm 64-bit Architecture`: https://developer.arm.com/docs/ihi0055/latest/
448.. _`EditorConfig`: http://editorconfig.org/
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000449.. _`Why the “volatile” type class should not be used`: https://www.kernel.org/doc/html/latest/process/volatile-considered-harmful.html
Paul Beesley07f0a312019-05-16 13:33:18 +0100450.. _`MISRA C:2012 Guidelines`: https://www.misra.org.uk/Activities/MISRAC/tabid/160/Default.aspx
451.. _`a spreadsheet`: https://developer.trustedfirmware.org/file/download/lamajxif3w7c4mpjeoo5/PHID-FILE-fp7c7acszn6vliqomyhn/MISRA-and-TF-Analysis-v1.3.ods