blob: 97086047d02151375f2293e4d867ca9a720dccd8 [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
Sandrine Bailleux391679f2020-08-20 10:41:36 +020098necessary to clean the build directory first).
99
100For example, to enable ``VERBOSE`` logging on FVP:
101
102.. code:: shell
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000103
Sandrine Bailleux391679f2020-08-20 10:41:36 +0200104 make PLAT=fvp LOG_LEVEL=50 all
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000105
Paul Beesley07f0a312019-05-16 13:33:18 +0100106Use const data where possible
107^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000108
Paul Beesley07f0a312019-05-16 13:33:18 +0100109For example, the following code:
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000110
Paul Beesleyfd688342019-01-21 16:11:28 +0000111.. code:: c
112
Paul Beesley07f0a312019-05-16 13:33:18 +0100113 struct my_struct {
Paul Beesleyfd688342019-01-21 16:11:28 +0000114 int arg1;
115 int arg2;
Paul Beesley07f0a312019-05-16 13:33:18 +0100116 };
Paul Beesleyfd688342019-01-21 16:11:28 +0000117
Paul Beesley07f0a312019-05-16 13:33:18 +0100118 void init(struct my_struct *ptr);
119
120 void main(void)
121 {
122 struct my_struct x;
123 x.arg1 = 1;
124 x.arg2 = 2;
125 init(&x);
126 }
Paul Beesleyfd688342019-01-21 16:11:28 +0000127
128is better written as:
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000129
130.. code:: c
131
Paul Beesleyfd688342019-01-21 16:11:28 +0000132 struct my_struct {
133 int arg1;
134 int arg2;
135 };
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000136
Paul Beesley07f0a312019-05-16 13:33:18 +0100137 void init(const struct my_struct *ptr);
Paul Beesleyfd688342019-01-21 16:11:28 +0000138
Paul Beesley07f0a312019-05-16 13:33:18 +0100139 void main(void)
140 {
141 const struct my_struct x = { 1, 2 };
142 init(&x);
143 }
Paul Beesleyfd688342019-01-21 16:11:28 +0000144
Paul Beesley07f0a312019-05-16 13:33:18 +0100145This allows the linker to put the data in a read-only data section instead of a
146writeable data section, which may result in a smaller and faster binary. Note
147that this may require dependent functions (``init()`` in the above example) to
148have ``const`` arguments, assuming they don't need to modify the data.
Paul Beesleyfd688342019-01-21 16:11:28 +0000149
Soby Mathew497092d2019-06-20 12:46:11 +0100150Libc functions that are banned or to be used with caution
151---------------------------------------------------------
152
153Below is a list of functions that present security risks and either must not be
154used (Banned) or are discouraged from use and must be used with care (Caution).
155
156+------------------------+-----------+--------------------------------------+
157| libc function | Status | Comments |
158+========================+===========+======================================+
John Tsichritzis890f3f02019-07-09 18:09:03 +0100159| ``strcpy, wcscpy``, | Banned | use strlcpy instead |
Soby Mathew497092d2019-06-20 12:46:11 +0100160| ``strncpy`` | | |
161+------------------------+-----------+--------------------------------------+
John Tsichritzis890f3f02019-07-09 18:09:03 +0100162| ``strcat, wcscat``, | Banned | use strlcat instead |
Soby Mathew497092d2019-06-20 12:46:11 +0100163| ``strncat`` | | |
John Tsichritzis890f3f02019-07-09 18:09:03 +0100164+------------------------+-----------+--------------------------------------+
Soby Mathew497092d2019-06-20 12:46:11 +0100165| ``sprintf, vsprintf`` | Banned | use snprintf, vsnprintf |
166| | | instead |
John Tsichritzis890f3f02019-07-09 18:09:03 +0100167+------------------------+-----------+--------------------------------------+
Soby Mathew497092d2019-06-20 12:46:11 +0100168| ``snprintf`` | Caution | ensure result fits in buffer |
169| | | i.e : snprintf(buf,size...) < size |
170+------------------------+-----------+--------------------------------------+
171| ``vsnprintf`` | Caution | inspect va_list match types |
172| | | specified in format string |
173+------------------------+-----------+--------------------------------------+
174| ``strtok`` | Banned | use strtok_r or strsep instead |
175+------------------------+-----------+--------------------------------------+
176| ``strtok_r, strsep`` | Caution | inspect for terminated input buffer |
177+------------------------+-----------+--------------------------------------+
178| ``ato*`` | Banned | use equivalent strto* functions |
179+------------------------+-----------+--------------------------------------+
180| ``*toa`` | Banned | Use snprintf instead |
181+------------------------+-----------+--------------------------------------+
182
183The `libc` component in the codebase will not add support for the banned APIs.
184
Paul Beesleyfd688342019-01-21 16:11:28 +0000185Error handling and robustness
186-----------------------------
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000187
188Using CASSERT to check for compile time data errors
189^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
190
191Where possible, use the ``CASSERT`` macro to check the validity of data known at
192compile time instead of checking validity at runtime, to avoid unnecessary
193runtime code.
194
195For example, this can be used to check that the assembler's and compiler's views
196of the size of an array is the same.
197
198.. code:: c
199
200 #include <cassert.h>
201
202 define MY_STRUCT_SIZE 8 /* Used by assembler source files */
203
204 struct my_struct {
205 uint32_t arg1;
206 uint32_t arg2;
207 };
208
209 CASSERT(MY_STRUCT_SIZE == sizeof(struct my_struct), assert_my_struct_size_mismatch);
210
211
212If ``MY_STRUCT_SIZE`` in the above example were wrong then the compiler would
213emit an error like this:
214
Paul Beesley493e3492019-03-13 15:11:04 +0000215::
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000216
217 my_struct.h:10:1: error: size of array ‘assert_my_struct_size_mismatch’ is negative
218
219
220Using assert() to check for programming errors
221^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
222
223In general, each secure world TF image (BL1, BL2, BL31 and BL32) should be
224treated as a tightly integrated package; the image builder should be aware of
225and responsible for all functionality within the image, even if code within that
226image is provided by multiple entities. This allows us to be more aggressive in
227interpreting invalid state or bad function arguments as programming errors using
228``assert()``, including arguments passed across platform porting interfaces.
229This is in contrast to code in a Linux environment, which is less tightly
230integrated and may attempt to be more defensive by passing the error back up the
231call stack.
232
233Where possible, badly written TF code should fail early using ``assert()``. This
234helps reduce the amount of untested conditional code. By default these
235statements are not compiled into release builds, although this can be overridden
236using the ``ENABLE_ASSERTIONS`` build flag.
237
238Examples:
239
240- Bad argument supplied to library function
241- Bad argument provided by platform porting function
242- Internal secure world image state is inconsistent
243
244
245Handling integration errors
246^^^^^^^^^^^^^^^^^^^^^^^^^^^
247
248Each secure world image may be provided by a different entity (for example, a
249Trusted Boot vendor may provide the BL2 image, a TEE vendor may provide the BL32
250image and the OEM/SoC vendor may provide the other images).
251
252An image may contain bugs that are only visible when the images are integrated.
253The system integrator may not even have access to the debug variants of all the
254images in order to check if asserts are firing. For example, the release variant
255of BL1 may have already been burnt into the SoC. Therefore, TF code that detects
256an integration error should _not_ consider this a programming error, and should
257always take action, even in release builds.
258
259If an integration error is considered non-critical it should be treated as a
260recoverable error. If the error is considered critical it should be treated as
261an unexpected unrecoverable error.
262
263Handling recoverable errors
264^^^^^^^^^^^^^^^^^^^^^^^^^^^
265
266The secure world **must not** crash when supplied with bad data from an external
267source. For example, data from the normal world or a hardware device. Similarly,
268the secure world **must not** crash if it detects a non-critical problem within
269itself or the system. It must make every effort to recover from the problem by
270emitting a ``WARN`` message, performing any necessary error handling and
271continuing.
272
273Examples:
274
275- Secure world receives SMC from normal world with bad arguments.
276- Secure world receives SMC from normal world at an unexpected time.
277- BL31 receives SMC from BL32 with bad arguments.
278- BL31 receives SMC from BL32 at unexpected time.
279- Secure world receives recoverable error from hardware device. Retrying the
280 operation may help here.
281- Non-critical secure world service is not functioning correctly.
282- BL31 SPD discovers minor configuration problem with corresponding SP.
283
284Handling unrecoverable errors
285^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
286
287In some cases it may not be possible for the secure world to recover from an
288error. This situation should be handled in one of the following ways:
289
2901. If the unrecoverable error is unexpected then emit an ``ERROR`` message and
291 call ``panic()``. This will end up calling the platform-specific function
292 ``plat_panic_handler()``.
2932. If the unrecoverable error is expected to occur in certain circumstances,
294 then emit an ``ERROR`` message and call the platform-specific function
295 ``plat_error_handler()``.
296
Paul Beesley07f0a312019-05-16 13:33:18 +0100297Cases 1 and 2 are subtly different. A platform may implement
298``plat_panic_handler`` and ``plat_error_handler`` in the same way (for example,
299by waiting for a secure watchdog to time-out or by invoking an interface on the
300platform's power controller to reset the platform). However,
301``plat_error_handler`` may take additional action for some errors (for example,
302it may set a flag so the platform resets into a different mode). Also,
303``plat_panic_handler()`` may implement additional debug functionality (for
304example, invoking a hardware breakpoint).
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000305
306Examples of unexpected unrecoverable errors:
307
308- BL32 receives an unexpected SMC response from BL31 that it is unable to
309 recover from.
310- BL31 Trusted OS SPD code discovers that BL2 has not loaded the corresponding
311 Trusted OS, which is critical for platform operation.
312- Secure world discovers that a critical hardware device is an unexpected and
313 unrecoverable state.
314- Secure world receives an unexpected and unrecoverable error from a critical
315 hardware device.
316- Secure world discovers that it is running on unsupported hardware.
317
318Examples of expected unrecoverable errors:
319
320- BL1/BL2 fails to load the next image due to missing/corrupt firmware on disk.
321- BL1/BL2 fails to authenticate the next image due to an invalid certificate.
322- Secure world continuously receives recoverable errors from a hardware device
323 but is unable to proceed without a valid response.
324
325Handling critical unresponsiveness
326^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
327
328If the secure world is waiting for a response from an external source (for
329example, the normal world or a hardware device) which is critical for continued
330operation, it must not wait indefinitely. It must have a mechanism (for example,
331a secure watchdog) for resetting itself and/or the external source to prevent
332the system from executing in this state indefinitely.
333
334Examples:
335
336- BL1 is waiting for the normal world to raise an SMC to proceed to the next
337 stage of the secure firmware update process.
338- A Trusted OS is waiting for a response from a proxy in the normal world that
339 is critical for continued operation.
340- Secure world is waiting for a hardware response that is critical for continued
341 operation.
342
Paul Beesley07f0a312019-05-16 13:33:18 +0100343Use of built-in *C* and *libc* data types
344-----------------------------------------
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000345
Paul Beesley07f0a312019-05-16 13:33:18 +0100346The |TF-A| codebase should be kept as portable as possible, especially since
347both 64-bit and 32-bit platforms are supported. To help with this, the following
348data type usage guidelines should be followed:
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000349
Paul Beesley07f0a312019-05-16 13:33:18 +0100350- Where possible, use the built-in *C* data types for variable storage (for
351 example, ``char``, ``int``, ``long long``, etc) instead of the standard *C99*
352 types. Most code is typically only concerned with the minimum size of the
353 data stored, which the built-in *C* types guarantee.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000354
Paul Beesley07f0a312019-05-16 13:33:18 +0100355- Avoid using the exact-size standard *C99* types in general (for example,
356 ``uint16_t``, ``uint32_t``, ``uint64_t``, etc) since they can prevent the
357 compiler from making optimizations. There are legitimate uses for them,
358 for example to represent data of a known structure. When using them in struct
359 definitions, consider how padding in the struct will work across architectures.
360 For example, extra padding may be introduced in |AArch32| systems if a struct
361 member crosses a 32-bit boundary.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000362
Paul Beesley07f0a312019-05-16 13:33:18 +0100363- Use ``int`` as the default integer type - it's likely to be the fastest on all
364 systems. Also this can be assumed to be 32-bit as a consequence of the
365 `Procedure Call Standard for the Arm Architecture`_ and the `Procedure Call
366 Standard for the Arm 64-bit Architecture`_ .
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000367
Paul Beesley07f0a312019-05-16 13:33:18 +0100368- Avoid use of ``short`` as this may end up being slower than ``int`` in some
369 systems. If a variable must be exactly 16-bit, use ``int16_t`` or
370 ``uint16_t``.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000371
Paul Beesley07f0a312019-05-16 13:33:18 +0100372- Avoid use of ``long``. This is guaranteed to be at least 32-bit but, given
373 that `int` is 32-bit on Arm platforms, there is no use for it. For integers of
374 at least 64-bit, use ``long long``.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000375
Paul Beesley07f0a312019-05-16 13:33:18 +0100376- Use ``char`` for storing text. Use ``uint8_t`` for storing other 8-bit data.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000377
Paul Beesley07f0a312019-05-16 13:33:18 +0100378- Use ``unsigned`` for integers that can never be negative (counts,
379 indices, sizes, etc). TF intends to comply with MISRA "essential type" coding
380 rules (10.X), where signed and unsigned types are considered different
381 essential types. Choosing the correct type will aid this. MISRA static
382 analysers will pick up any implicit signed/unsigned conversions that may lead
383 to unexpected behaviour.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000384
Paul Beesley07f0a312019-05-16 13:33:18 +0100385- For pointer types:
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000386
Paul Beesley07f0a312019-05-16 13:33:18 +0100387 - If an argument in a function declaration is pointing to a known type then
388 simply use a pointer to that type (for example: ``struct my_struct *``).
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000389
Paul Beesley07f0a312019-05-16 13:33:18 +0100390 - If a variable (including an argument in a function declaration) is pointing
391 to a general, memory-mapped address, an array of pointers or another
392 structure that is likely to require pointer arithmetic then use
393 ``uintptr_t``. This will reduce the amount of casting required in the code.
394 Avoid using ``unsigned long`` or ``unsigned long long`` for this purpose; it
395 may work but is less portable.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000396
Paul Beesley07f0a312019-05-16 13:33:18 +0100397 - For other pointer arguments in a function declaration, use ``void *``. This
398 includes pointers to types that are abstracted away from the known API and
399 pointers to arbitrary data. This allows the calling function to pass a
400 pointer argument to the function without any explicit casting (the cast to
401 ``void *`` is implicit). The function implementation can then do the
402 appropriate casting to a specific type.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000403
Paul Beesley07f0a312019-05-16 13:33:18 +0100404 - Avoid pointer arithmetic generally (as this violates MISRA C 2012 rule
405 18.4) and especially on void pointers (as this is only supported via
406 language extensions and is considered non-standard). In TF-A, setting the
407 ``W`` build flag to ``W=3`` enables the *-Wpointer-arith* compiler flag and
408 this will emit warnings where pointer arithmetic is used.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000409
Paul Beesley07f0a312019-05-16 13:33:18 +0100410 - Use ``ptrdiff_t`` to compare the difference between 2 pointers.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000411
Paul Beesley07f0a312019-05-16 13:33:18 +0100412- Use ``size_t`` when storing the ``sizeof()`` something.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000413
Paul Beesley07f0a312019-05-16 13:33:18 +0100414- Use ``ssize_t`` when returning the ``sizeof()`` something from a function that
415 can also return an error code; the signed type allows for a negative return
416 code in case of error. This practice should be used sparingly.
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000417
Paul Beesley07f0a312019-05-16 13:33:18 +0100418- Use ``u_register_t`` when it's important to store the contents of a register
419 in its native size (32-bit in |AArch32| and 64-bit in |AArch64|). This is not a
420 standard *C99* type but is widely available in libc implementations,
421 including the FreeBSD version included with the TF codebase. Where possible,
422 cast the variable to a more appropriate type before interpreting the data. For
423 example, the following struct in ``ep_info.h`` could use this type to minimize
424 the storage required for the set of registers:
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000425
426.. code:: c
427
Paul Beesley07f0a312019-05-16 13:33:18 +0100428 typedef struct aapcs64_params {
429 u_register_t arg0;
430 u_register_t arg1;
431 u_register_t arg2;
432 u_register_t arg3;
433 u_register_t arg4;
434 u_register_t arg5;
435 u_register_t arg6;
436 u_register_t arg7;
437 } aapcs64_params_t;
Paul Beesleyfd688342019-01-21 16:11:28 +0000438
Paul Beesley07f0a312019-05-16 13:33:18 +0100439If some code wants to operate on ``arg0`` and knows that it represents a 32-bit
440unsigned integer on all systems, cast it to ``unsigned int``.
Paul Beesleyfd688342019-01-21 16:11:28 +0000441
Paul Beesley07f0a312019-05-16 13:33:18 +0100442These guidelines should be updated if additional types are needed.
Paul Beesleyfd688342019-01-21 16:11:28 +0000443
Paul Beesley07f0a312019-05-16 13:33:18 +0100444--------------
Paul Beesleyfd688342019-01-21 16:11:28 +0000445
Paul Beesley07f0a312019-05-16 13:33:18 +0100446*Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.*
Paul Beesleyfd688342019-01-21 16:11:28 +0000447
Paul Beesley07f0a312019-05-16 13:33:18 +0100448.. _`Linux master tree`: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/
449.. _`Procedure Call Standard for the Arm Architecture`: https://developer.arm.com/docs/ihi0042/latest/
450.. _`Procedure Call Standard for the Arm 64-bit Architecture`: https://developer.arm.com/docs/ihi0055/latest/
451.. _`EditorConfig`: http://editorconfig.org/
Paul Beesley4e2e1b22019-01-17 15:44:37 +0000452.. _`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 +0100453.. _`MISRA C:2012 Guidelines`: https://www.misra.org.uk/Activities/MISRAC/tabid/160/Default.aspx
454.. _`a spreadsheet`: https://developer.trustedfirmware.org/file/download/lamajxif3w7c4mpjeoo5/PHID-FILE-fp7c7acszn6vliqomyhn/MISRA-and-TF-Analysis-v1.3.ods