xref: /aosp_15_r20/external/arm-trusted-firmware/docs/process/coding-guidelines.rst (revision 54fd6939e177f8ff529b10183254802c76df6d08)
1*54fd6939SJiyong ParkCoding Guidelines
2*54fd6939SJiyong Park=================
3*54fd6939SJiyong Park
4*54fd6939SJiyong ParkThis document provides some additional guidelines to consider when writing
5*54fd6939SJiyong Park|TF-A| code. These are not intended to be strictly-enforced rules like the
6*54fd6939SJiyong Parkcontents of the :ref:`Coding Style`.
7*54fd6939SJiyong Park
8*54fd6939SJiyong ParkAutomatic Editor Configuration
9*54fd6939SJiyong Park------------------------------
10*54fd6939SJiyong Park
11*54fd6939SJiyong ParkMany of the rules given below (such as indentation size, use of tabs, and
12*54fd6939SJiyong Parknewlines) can be set automatically using the `EditorConfig`_ configuration file
13*54fd6939SJiyong Parkin the root of the repository: ``.editorconfig``. With a supported editor, the
14*54fd6939SJiyong Parkrules set out in this file can be automatically applied when you are editing
15*54fd6939SJiyong Parkfiles in the |TF-A| repository.
16*54fd6939SJiyong Park
17*54fd6939SJiyong ParkSeveral editors include built-in support for EditorConfig files, and many others
18*54fd6939SJiyong Parksupport its functionality through plugins.
19*54fd6939SJiyong Park
20*54fd6939SJiyong ParkUse of the EditorConfig file is suggested but is not required.
21*54fd6939SJiyong Park
22*54fd6939SJiyong Park.. _automatic-compliance-checking:
23*54fd6939SJiyong Park
24*54fd6939SJiyong ParkAutomatic Compliance Checking
25*54fd6939SJiyong Park-----------------------------
26*54fd6939SJiyong Park
27*54fd6939SJiyong ParkTo assist with coding style compliance, the project Makefile contains two
28*54fd6939SJiyong Parktargets which both utilise the `checkpatch.pl` script that ships with the Linux
29*54fd6939SJiyong Parksource tree. The project also defines certain *checkpatch* options in the
30*54fd6939SJiyong Park``.checkpatch.conf`` file in the top-level directory.
31*54fd6939SJiyong Park
32*54fd6939SJiyong Park.. note::
33*54fd6939SJiyong Park   Checkpatch errors will gate upstream merging of pull requests.
34*54fd6939SJiyong Park   Checkpatch warnings will not gate merging but should be reviewed and fixed if
35*54fd6939SJiyong Park   possible.
36*54fd6939SJiyong Park
37*54fd6939SJiyong ParkTo check the entire source tree, you must first download copies of
38*54fd6939SJiyong Park``checkpatch.pl``, ``spelling.txt`` and ``const_structs.checkpatch`` available
39*54fd6939SJiyong Parkin the `Linux master tree`_ *scripts* directory, then set the ``CHECKPATCH``
40*54fd6939SJiyong Parkenvironment variable to point to ``checkpatch.pl`` (with the other 2 files in
41*54fd6939SJiyong Parkthe same directory) and build the `checkcodebase` target:
42*54fd6939SJiyong Park
43*54fd6939SJiyong Park.. code:: shell
44*54fd6939SJiyong Park
45*54fd6939SJiyong Park    make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkcodebase
46*54fd6939SJiyong Park
47*54fd6939SJiyong ParkTo just check the style on the files that differ between your local branch and
48*54fd6939SJiyong Parkthe remote master, use:
49*54fd6939SJiyong Park
50*54fd6939SJiyong Park.. code:: shell
51*54fd6939SJiyong Park
52*54fd6939SJiyong Park    make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkpatch
53*54fd6939SJiyong Park
54*54fd6939SJiyong ParkIf you wish to check your patch against something other than the remote master,
55*54fd6939SJiyong Parkset the ``BASE_COMMIT`` variable to your desired branch. By default,
56*54fd6939SJiyong Park``BASE_COMMIT`` is set to ``origin/master``.
57*54fd6939SJiyong Park
58*54fd6939SJiyong ParkIgnored Checkpatch Warnings
59*54fd6939SJiyong Park^^^^^^^^^^^^^^^^^^^^^^^^^^^
60*54fd6939SJiyong Park
61*54fd6939SJiyong ParkSome checkpatch warnings in the TF codebase are deliberately ignored. These
62*54fd6939SJiyong Parkinclude:
63*54fd6939SJiyong Park
64*54fd6939SJiyong Park- ``**WARNING: line over 80 characters**``: Although the codebase should
65*54fd6939SJiyong Park  generally conform to the 80 character limit this is overly restrictive in some
66*54fd6939SJiyong Park  cases.
67*54fd6939SJiyong Park
68*54fd6939SJiyong Park- ``**WARNING: Use of volatile is usually wrong``: see
69*54fd6939SJiyong Park  `Why the “volatile” type class should not be used`_ . Although this document
70*54fd6939SJiyong Park  contains some very useful information, there are several legimate uses of the
71*54fd6939SJiyong Park  volatile keyword within the TF codebase.
72*54fd6939SJiyong Park
73*54fd6939SJiyong ParkPerformance considerations
74*54fd6939SJiyong Park--------------------------
75*54fd6939SJiyong Park
76*54fd6939SJiyong ParkAvoid printf and use logging macros
77*54fd6939SJiyong Park^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
78*54fd6939SJiyong Park
79*54fd6939SJiyong Park``debug.h`` provides logging macros (for example, ``WARN`` and ``ERROR``)
80*54fd6939SJiyong Parkwhich wrap ``tf_log`` and which allow the logging call to be compiled-out
81*54fd6939SJiyong Parkdepending on the ``make`` command. Use these macros to avoid print statements
82*54fd6939SJiyong Parkbeing compiled unconditionally into the binary.
83*54fd6939SJiyong Park
84*54fd6939SJiyong ParkEach logging macro has a numerical log level:
85*54fd6939SJiyong Park
86*54fd6939SJiyong Park.. code:: c
87*54fd6939SJiyong Park
88*54fd6939SJiyong Park  #define LOG_LEVEL_NONE    0
89*54fd6939SJiyong Park  #define LOG_LEVEL_ERROR   10
90*54fd6939SJiyong Park  #define LOG_LEVEL_NOTICE  20
91*54fd6939SJiyong Park  #define LOG_LEVEL_WARNING 30
92*54fd6939SJiyong Park  #define LOG_LEVEL_INFO    40
93*54fd6939SJiyong Park  #define LOG_LEVEL_VERBOSE 50
94*54fd6939SJiyong Park
95*54fd6939SJiyong ParkBy default, all logging statements with a log level ``<= LOG_LEVEL_INFO`` will
96*54fd6939SJiyong Parkbe compiled into debug builds and all statements with a log level
97*54fd6939SJiyong Park``<= LOG_LEVEL_NOTICE`` will be compiled into release builds. This can be
98*54fd6939SJiyong Parkoverridden from the command line or by the platform makefile (although it may be
99*54fd6939SJiyong Parknecessary to clean the build directory first).
100*54fd6939SJiyong Park
101*54fd6939SJiyong ParkFor example, to enable ``VERBOSE`` logging on FVP:
102*54fd6939SJiyong Park
103*54fd6939SJiyong Park.. code:: shell
104*54fd6939SJiyong Park
105*54fd6939SJiyong Park  make PLAT=fvp LOG_LEVEL=50 all
106*54fd6939SJiyong Park
107*54fd6939SJiyong ParkUse const data where possible
108*54fd6939SJiyong Park^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
109*54fd6939SJiyong Park
110*54fd6939SJiyong ParkFor example, the following code:
111*54fd6939SJiyong Park
112*54fd6939SJiyong Park.. code:: c
113*54fd6939SJiyong Park
114*54fd6939SJiyong Park  struct my_struct {
115*54fd6939SJiyong Park          int arg1;
116*54fd6939SJiyong Park          int arg2;
117*54fd6939SJiyong Park  };
118*54fd6939SJiyong Park
119*54fd6939SJiyong Park  void init(struct my_struct *ptr);
120*54fd6939SJiyong Park
121*54fd6939SJiyong Park  void main(void)
122*54fd6939SJiyong Park  {
123*54fd6939SJiyong Park          struct my_struct x;
124*54fd6939SJiyong Park          x.arg1 = 1;
125*54fd6939SJiyong Park          x.arg2 = 2;
126*54fd6939SJiyong Park          init(&x);
127*54fd6939SJiyong Park  }
128*54fd6939SJiyong Park
129*54fd6939SJiyong Parkis better written as:
130*54fd6939SJiyong Park
131*54fd6939SJiyong Park.. code:: c
132*54fd6939SJiyong Park
133*54fd6939SJiyong Park  struct my_struct {
134*54fd6939SJiyong Park          int arg1;
135*54fd6939SJiyong Park          int arg2;
136*54fd6939SJiyong Park  };
137*54fd6939SJiyong Park
138*54fd6939SJiyong Park  void init(const struct my_struct *ptr);
139*54fd6939SJiyong Park
140*54fd6939SJiyong Park  void main(void)
141*54fd6939SJiyong Park  {
142*54fd6939SJiyong Park          const struct my_struct x = { 1, 2 };
143*54fd6939SJiyong Park          init(&x);
144*54fd6939SJiyong Park  }
145*54fd6939SJiyong Park
146*54fd6939SJiyong ParkThis allows the linker to put the data in a read-only data section instead of a
147*54fd6939SJiyong Parkwriteable data section, which may result in a smaller and faster binary. Note
148*54fd6939SJiyong Parkthat this may require dependent functions (``init()`` in the above example) to
149*54fd6939SJiyong Parkhave ``const`` arguments, assuming they don't need to modify the data.
150*54fd6939SJiyong Park
151*54fd6939SJiyong ParkLibc functions that are banned or to be used with caution
152*54fd6939SJiyong Park---------------------------------------------------------
153*54fd6939SJiyong Park
154*54fd6939SJiyong ParkBelow is a list of functions that present security risks and either must not be
155*54fd6939SJiyong Parkused (Banned) or are discouraged from use and must be used with care (Caution).
156*54fd6939SJiyong Park
157*54fd6939SJiyong Park+------------------------+-----------+--------------------------------------+
158*54fd6939SJiyong Park|    libc function       | Status    | Comments                             |
159*54fd6939SJiyong Park+========================+===========+======================================+
160*54fd6939SJiyong Park| ``strcpy, wcscpy``,    | Banned    | use strlcpy instead                  |
161*54fd6939SJiyong Park| ``strncpy``            |           |                                      |
162*54fd6939SJiyong Park+------------------------+-----------+--------------------------------------+
163*54fd6939SJiyong Park| ``strcat, wcscat``,    | Banned    | use strlcat instead                  |
164*54fd6939SJiyong Park| ``strncat``            |           |                                      |
165*54fd6939SJiyong Park+------------------------+-----------+--------------------------------------+
166*54fd6939SJiyong Park| ``sprintf, vsprintf``  | Banned    | use snprintf, vsnprintf              |
167*54fd6939SJiyong Park|                        |           | instead                              |
168*54fd6939SJiyong Park+------------------------+-----------+--------------------------------------+
169*54fd6939SJiyong Park| ``snprintf``           | Caution   | ensure result fits in buffer         |
170*54fd6939SJiyong Park|                        |           | i.e : snprintf(buf,size...) < size   |
171*54fd6939SJiyong Park+------------------------+-----------+--------------------------------------+
172*54fd6939SJiyong Park| ``vsnprintf``          | Caution   | inspect va_list match types          |
173*54fd6939SJiyong Park|                        |           | specified in format string           |
174*54fd6939SJiyong Park+------------------------+-----------+--------------------------------------+
175*54fd6939SJiyong Park| ``strtok``             | Banned    | use strtok_r or strsep instead       |
176*54fd6939SJiyong Park+------------------------+-----------+--------------------------------------+
177*54fd6939SJiyong Park| ``strtok_r, strsep``   | Caution   | inspect for terminated input buffer  |
178*54fd6939SJiyong Park+------------------------+-----------+--------------------------------------+
179*54fd6939SJiyong Park| ``ato*``               | Banned    | use equivalent strto* functions      |
180*54fd6939SJiyong Park+------------------------+-----------+--------------------------------------+
181*54fd6939SJiyong Park| ``*toa``               | Banned    | Use snprintf instead                 |
182*54fd6939SJiyong Park+------------------------+-----------+--------------------------------------+
183*54fd6939SJiyong Park
184*54fd6939SJiyong ParkThe `libc` component in the codebase will not add support for the banned APIs.
185*54fd6939SJiyong Park
186*54fd6939SJiyong ParkError handling and robustness
187*54fd6939SJiyong Park-----------------------------
188*54fd6939SJiyong Park
189*54fd6939SJiyong ParkUsing CASSERT to check for compile time data errors
190*54fd6939SJiyong Park^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
191*54fd6939SJiyong Park
192*54fd6939SJiyong ParkWhere possible, use the ``CASSERT`` macro to check the validity of data known at
193*54fd6939SJiyong Parkcompile time instead of checking validity at runtime, to avoid unnecessary
194*54fd6939SJiyong Parkruntime code.
195*54fd6939SJiyong Park
196*54fd6939SJiyong ParkFor example, this can be used to check that the assembler's and compiler's views
197*54fd6939SJiyong Parkof the size of an array is the same.
198*54fd6939SJiyong Park
199*54fd6939SJiyong Park.. code:: c
200*54fd6939SJiyong Park
201*54fd6939SJiyong Park  #include <cassert.h>
202*54fd6939SJiyong Park
203*54fd6939SJiyong Park  define MY_STRUCT_SIZE 8 /* Used by assembler source files */
204*54fd6939SJiyong Park
205*54fd6939SJiyong Park  struct my_struct {
206*54fd6939SJiyong Park      uint32_t arg1;
207*54fd6939SJiyong Park      uint32_t arg2;
208*54fd6939SJiyong Park  };
209*54fd6939SJiyong Park
210*54fd6939SJiyong Park  CASSERT(MY_STRUCT_SIZE == sizeof(struct my_struct), assert_my_struct_size_mismatch);
211*54fd6939SJiyong Park
212*54fd6939SJiyong Park
213*54fd6939SJiyong ParkIf ``MY_STRUCT_SIZE`` in the above example were wrong then the compiler would
214*54fd6939SJiyong Parkemit an error like this:
215*54fd6939SJiyong Park
216*54fd6939SJiyong Park::
217*54fd6939SJiyong Park
218*54fd6939SJiyong Park  my_struct.h:10:1: error: size of array ‘assert_my_struct_size_mismatch’ is negative
219*54fd6939SJiyong Park
220*54fd6939SJiyong Park
221*54fd6939SJiyong ParkUsing assert() to check for programming errors
222*54fd6939SJiyong Park^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
223*54fd6939SJiyong Park
224*54fd6939SJiyong ParkIn general, each secure world TF image (BL1, BL2, BL31 and BL32) should be
225*54fd6939SJiyong Parktreated as a tightly integrated package; the image builder should be aware of
226*54fd6939SJiyong Parkand responsible for all functionality within the image, even if code within that
227*54fd6939SJiyong Parkimage is provided by multiple entities. This allows us to be more aggressive in
228*54fd6939SJiyong Parkinterpreting invalid state or bad function arguments as programming errors using
229*54fd6939SJiyong Park``assert()``, including arguments passed across platform porting interfaces.
230*54fd6939SJiyong ParkThis is in contrast to code in a Linux environment, which is less tightly
231*54fd6939SJiyong Parkintegrated and may attempt to be more defensive by passing the error back up the
232*54fd6939SJiyong Parkcall stack.
233*54fd6939SJiyong Park
234*54fd6939SJiyong ParkWhere possible, badly written TF code should fail early using ``assert()``. This
235*54fd6939SJiyong Parkhelps reduce the amount of untested conditional code. By default these
236*54fd6939SJiyong Parkstatements are not compiled into release builds, although this can be overridden
237*54fd6939SJiyong Parkusing the ``ENABLE_ASSERTIONS`` build flag.
238*54fd6939SJiyong Park
239*54fd6939SJiyong ParkExamples:
240*54fd6939SJiyong Park
241*54fd6939SJiyong Park- Bad argument supplied to library function
242*54fd6939SJiyong Park- Bad argument provided by platform porting function
243*54fd6939SJiyong Park- Internal secure world image state is inconsistent
244*54fd6939SJiyong Park
245*54fd6939SJiyong Park
246*54fd6939SJiyong ParkHandling integration errors
247*54fd6939SJiyong Park^^^^^^^^^^^^^^^^^^^^^^^^^^^
248*54fd6939SJiyong Park
249*54fd6939SJiyong ParkEach secure world image may be provided by a different entity (for example, a
250*54fd6939SJiyong ParkTrusted Boot vendor may provide the BL2 image, a TEE vendor may provide the BL32
251*54fd6939SJiyong Parkimage and the OEM/SoC vendor may provide the other images).
252*54fd6939SJiyong Park
253*54fd6939SJiyong ParkAn image may contain bugs that are only visible when the images are integrated.
254*54fd6939SJiyong ParkThe system integrator may not even have access to the debug variants of all the
255*54fd6939SJiyong Parkimages in order to check if asserts are firing. For example, the release variant
256*54fd6939SJiyong Parkof BL1 may have already been burnt into the SoC. Therefore, TF code that detects
257*54fd6939SJiyong Parkan integration error should _not_ consider this a programming error, and should
258*54fd6939SJiyong Parkalways take action, even in release builds.
259*54fd6939SJiyong Park
260*54fd6939SJiyong ParkIf an integration error is considered non-critical it should be treated as a
261*54fd6939SJiyong Parkrecoverable error. If the error is considered critical it should be treated as
262*54fd6939SJiyong Parkan unexpected unrecoverable error.
263*54fd6939SJiyong Park
264*54fd6939SJiyong ParkHandling recoverable errors
265*54fd6939SJiyong Park^^^^^^^^^^^^^^^^^^^^^^^^^^^
266*54fd6939SJiyong Park
267*54fd6939SJiyong ParkThe secure world **must not** crash when supplied with bad data from an external
268*54fd6939SJiyong Parksource. For example, data from the normal world or a hardware device. Similarly,
269*54fd6939SJiyong Parkthe secure world **must not** crash if it detects a non-critical problem within
270*54fd6939SJiyong Parkitself or the system. It must make every effort to recover from the problem by
271*54fd6939SJiyong Parkemitting a ``WARN`` message, performing any necessary error handling and
272*54fd6939SJiyong Parkcontinuing.
273*54fd6939SJiyong Park
274*54fd6939SJiyong ParkExamples:
275*54fd6939SJiyong Park
276*54fd6939SJiyong Park- Secure world receives SMC from normal world with bad arguments.
277*54fd6939SJiyong Park- Secure world receives SMC from normal world at an unexpected time.
278*54fd6939SJiyong Park- BL31 receives SMC from BL32 with bad arguments.
279*54fd6939SJiyong Park- BL31 receives SMC from BL32 at unexpected time.
280*54fd6939SJiyong Park- Secure world receives recoverable error from hardware device. Retrying the
281*54fd6939SJiyong Park  operation may help here.
282*54fd6939SJiyong Park- Non-critical secure world service is not functioning correctly.
283*54fd6939SJiyong Park- BL31 SPD discovers minor configuration problem with corresponding SP.
284*54fd6939SJiyong Park
285*54fd6939SJiyong ParkHandling unrecoverable errors
286*54fd6939SJiyong Park^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
287*54fd6939SJiyong Park
288*54fd6939SJiyong ParkIn some cases it may not be possible for the secure world to recover from an
289*54fd6939SJiyong Parkerror. This situation should be handled in one of the following ways:
290*54fd6939SJiyong Park
291*54fd6939SJiyong Park1. If the unrecoverable error is unexpected then emit an ``ERROR`` message and
292*54fd6939SJiyong Park   call ``panic()``. This will end up calling the platform-specific function
293*54fd6939SJiyong Park   ``plat_panic_handler()``.
294*54fd6939SJiyong Park2. If the unrecoverable error is expected to occur in certain circumstances,
295*54fd6939SJiyong Park   then emit an ``ERROR`` message and call the platform-specific function
296*54fd6939SJiyong Park   ``plat_error_handler()``.
297*54fd6939SJiyong Park
298*54fd6939SJiyong ParkCases 1 and 2 are subtly different. A platform may implement
299*54fd6939SJiyong Park``plat_panic_handler`` and ``plat_error_handler`` in the same way (for example,
300*54fd6939SJiyong Parkby waiting for a secure watchdog to time-out or by invoking an interface on the
301*54fd6939SJiyong Parkplatform's power controller to reset the platform). However,
302*54fd6939SJiyong Park``plat_error_handler`` may take additional action for some errors (for example,
303*54fd6939SJiyong Parkit may set a flag so the platform resets into a different mode). Also,
304*54fd6939SJiyong Park``plat_panic_handler()`` may implement additional debug functionality (for
305*54fd6939SJiyong Parkexample, invoking a hardware breakpoint).
306*54fd6939SJiyong Park
307*54fd6939SJiyong ParkExamples of unexpected unrecoverable errors:
308*54fd6939SJiyong Park
309*54fd6939SJiyong Park- BL32 receives an unexpected SMC response from BL31 that it is unable to
310*54fd6939SJiyong Park  recover from.
311*54fd6939SJiyong Park- BL31 Trusted OS SPD code discovers that BL2 has not loaded the corresponding
312*54fd6939SJiyong Park  Trusted OS, which is critical for platform operation.
313*54fd6939SJiyong Park- Secure world discovers that a critical hardware device is an unexpected and
314*54fd6939SJiyong Park  unrecoverable state.
315*54fd6939SJiyong Park- Secure world receives an unexpected and unrecoverable error from a critical
316*54fd6939SJiyong Park  hardware device.
317*54fd6939SJiyong Park- Secure world discovers that it is running on unsupported hardware.
318*54fd6939SJiyong Park
319*54fd6939SJiyong ParkExamples of expected unrecoverable errors:
320*54fd6939SJiyong Park
321*54fd6939SJiyong Park- BL1/BL2 fails to load the next image due to missing/corrupt firmware on disk.
322*54fd6939SJiyong Park- BL1/BL2 fails to authenticate the next image due to an invalid certificate.
323*54fd6939SJiyong Park- Secure world continuously receives recoverable errors from a hardware device
324*54fd6939SJiyong Park  but is unable to proceed without a valid response.
325*54fd6939SJiyong Park
326*54fd6939SJiyong ParkHandling critical unresponsiveness
327*54fd6939SJiyong Park^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
328*54fd6939SJiyong Park
329*54fd6939SJiyong ParkIf the secure world is waiting for a response from an external source (for
330*54fd6939SJiyong Parkexample, the normal world or a hardware device) which is critical for continued
331*54fd6939SJiyong Parkoperation, it must not wait indefinitely. It must have a mechanism (for example,
332*54fd6939SJiyong Parka secure watchdog) for resetting itself and/or the external source to prevent
333*54fd6939SJiyong Parkthe system from executing in this state indefinitely.
334*54fd6939SJiyong Park
335*54fd6939SJiyong ParkExamples:
336*54fd6939SJiyong Park
337*54fd6939SJiyong Park- BL1 is waiting for the normal world to raise an SMC to proceed to the next
338*54fd6939SJiyong Park  stage of the secure firmware update process.
339*54fd6939SJiyong Park- A Trusted OS is waiting for a response from a proxy in the normal world that
340*54fd6939SJiyong Park  is critical for continued operation.
341*54fd6939SJiyong Park- Secure world is waiting for a hardware response that is critical for continued
342*54fd6939SJiyong Park  operation.
343*54fd6939SJiyong Park
344*54fd6939SJiyong ParkUse of built-in *C* and *libc* data types
345*54fd6939SJiyong Park-----------------------------------------
346*54fd6939SJiyong Park
347*54fd6939SJiyong ParkThe |TF-A| codebase should be kept as portable as possible, especially since
348*54fd6939SJiyong Parkboth 64-bit and 32-bit platforms are supported. To help with this, the following
349*54fd6939SJiyong Parkdata type usage guidelines should be followed:
350*54fd6939SJiyong Park
351*54fd6939SJiyong Park- Where possible, use the built-in *C* data types for variable storage (for
352*54fd6939SJiyong Park  example, ``char``, ``int``, ``long long``, etc) instead of the standard *C99*
353*54fd6939SJiyong Park  types. Most code is typically only concerned with the minimum size of the
354*54fd6939SJiyong Park  data stored, which the built-in *C* types guarantee.
355*54fd6939SJiyong Park
356*54fd6939SJiyong Park- Avoid using the exact-size standard *C99* types in general (for example,
357*54fd6939SJiyong Park  ``uint16_t``, ``uint32_t``, ``uint64_t``, etc) since they can prevent the
358*54fd6939SJiyong Park  compiler from making optimizations. There are legitimate uses for them,
359*54fd6939SJiyong Park  for example to represent data of a known structure. When using them in struct
360*54fd6939SJiyong Park  definitions, consider how padding in the struct will work across architectures.
361*54fd6939SJiyong Park  For example, extra padding may be introduced in |AArch32| systems if a struct
362*54fd6939SJiyong Park  member crosses a 32-bit boundary.
363*54fd6939SJiyong Park
364*54fd6939SJiyong Park- Use ``int`` as the default integer type - it's likely to be the fastest on all
365*54fd6939SJiyong Park  systems. Also this can be assumed to be 32-bit as a consequence of the
366*54fd6939SJiyong Park  `Procedure Call Standard for the Arm Architecture`_ and the `Procedure Call
367*54fd6939SJiyong Park  Standard for the Arm 64-bit Architecture`_ .
368*54fd6939SJiyong Park
369*54fd6939SJiyong Park- Avoid use of ``short`` as this may end up being slower than ``int`` in some
370*54fd6939SJiyong Park  systems. If a variable must be exactly 16-bit, use ``int16_t`` or
371*54fd6939SJiyong Park  ``uint16_t``.
372*54fd6939SJiyong Park
373*54fd6939SJiyong Park- Avoid use of ``long``. This is guaranteed to be at least 32-bit but, given
374*54fd6939SJiyong Park  that `int` is 32-bit on Arm platforms, there is no use for it. For integers of
375*54fd6939SJiyong Park  at least 64-bit, use ``long long``.
376*54fd6939SJiyong Park
377*54fd6939SJiyong Park- Use ``char`` for storing text. Use ``uint8_t`` for storing other 8-bit data.
378*54fd6939SJiyong Park
379*54fd6939SJiyong Park- Use ``unsigned`` for integers that can never be negative (counts,
380*54fd6939SJiyong Park  indices, sizes, etc). TF intends to comply with MISRA "essential type" coding
381*54fd6939SJiyong Park  rules (10.X), where signed and unsigned types are considered different
382*54fd6939SJiyong Park  essential types. Choosing the correct type will aid this. MISRA static
383*54fd6939SJiyong Park  analysers will pick up any implicit signed/unsigned conversions that may lead
384*54fd6939SJiyong Park  to unexpected behaviour.
385*54fd6939SJiyong Park
386*54fd6939SJiyong Park- For pointer types:
387*54fd6939SJiyong Park
388*54fd6939SJiyong Park  - If an argument in a function declaration is pointing to a known type then
389*54fd6939SJiyong Park    simply use a pointer to that type (for example: ``struct my_struct *``).
390*54fd6939SJiyong Park
391*54fd6939SJiyong Park  - If a variable (including an argument in a function declaration) is pointing
392*54fd6939SJiyong Park    to a general, memory-mapped address, an array of pointers or another
393*54fd6939SJiyong Park    structure that is likely to require pointer arithmetic then use
394*54fd6939SJiyong Park    ``uintptr_t``. This will reduce the amount of casting required in the code.
395*54fd6939SJiyong Park    Avoid using ``unsigned long`` or ``unsigned long long`` for this purpose; it
396*54fd6939SJiyong Park    may work but is less portable.
397*54fd6939SJiyong Park
398*54fd6939SJiyong Park  - For other pointer arguments in a function declaration, use ``void *``. This
399*54fd6939SJiyong Park    includes pointers to types that are abstracted away from the known API and
400*54fd6939SJiyong Park    pointers to arbitrary data. This allows the calling function to pass a
401*54fd6939SJiyong Park    pointer argument to the function without any explicit casting (the cast to
402*54fd6939SJiyong Park    ``void *`` is implicit). The function implementation can then do the
403*54fd6939SJiyong Park    appropriate casting to a specific type.
404*54fd6939SJiyong Park
405*54fd6939SJiyong Park  - Avoid pointer arithmetic generally (as this violates MISRA C 2012 rule
406*54fd6939SJiyong Park    18.4) and especially on void pointers (as this is only supported via
407*54fd6939SJiyong Park    language extensions and is considered non-standard). In TF-A, setting the
408*54fd6939SJiyong Park    ``W`` build flag to ``W=3`` enables the *-Wpointer-arith* compiler flag and
409*54fd6939SJiyong Park    this will emit warnings where pointer arithmetic is used.
410*54fd6939SJiyong Park
411*54fd6939SJiyong Park  - Use ``ptrdiff_t`` to compare the difference between 2 pointers.
412*54fd6939SJiyong Park
413*54fd6939SJiyong Park- Use ``size_t`` when storing the ``sizeof()`` something.
414*54fd6939SJiyong Park
415*54fd6939SJiyong Park- Use ``ssize_t`` when returning the ``sizeof()`` something from a function that
416*54fd6939SJiyong Park  can also return an error code; the signed type allows for a negative return
417*54fd6939SJiyong Park  code in case of error. This practice should be used sparingly.
418*54fd6939SJiyong Park
419*54fd6939SJiyong Park- Use ``u_register_t`` when it's important to store the contents of a register
420*54fd6939SJiyong Park  in its native size (32-bit in |AArch32| and 64-bit in |AArch64|). This is not a
421*54fd6939SJiyong Park  standard *C99* type but is widely available in libc implementations,
422*54fd6939SJiyong Park  including the FreeBSD version included with the TF codebase. Where possible,
423*54fd6939SJiyong Park  cast the variable to a more appropriate type before interpreting the data. For
424*54fd6939SJiyong Park  example, the following struct in ``ep_info.h`` could use this type to minimize
425*54fd6939SJiyong Park  the storage required for the set of registers:
426*54fd6939SJiyong Park
427*54fd6939SJiyong Park.. code:: c
428*54fd6939SJiyong Park
429*54fd6939SJiyong Park    typedef struct aapcs64_params {
430*54fd6939SJiyong Park            u_register_t arg0;
431*54fd6939SJiyong Park            u_register_t arg1;
432*54fd6939SJiyong Park            u_register_t arg2;
433*54fd6939SJiyong Park            u_register_t arg3;
434*54fd6939SJiyong Park            u_register_t arg4;
435*54fd6939SJiyong Park            u_register_t arg5;
436*54fd6939SJiyong Park            u_register_t arg6;
437*54fd6939SJiyong Park            u_register_t arg7;
438*54fd6939SJiyong Park    } aapcs64_params_t;
439*54fd6939SJiyong Park
440*54fd6939SJiyong ParkIf some code wants to operate on ``arg0`` and knows that it represents a 32-bit
441*54fd6939SJiyong Parkunsigned integer on all systems, cast it to ``unsigned int``.
442*54fd6939SJiyong Park
443*54fd6939SJiyong ParkThese guidelines should be updated if additional types are needed.
444*54fd6939SJiyong Park
445*54fd6939SJiyong ParkFavor C language over assembly language
446*54fd6939SJiyong Park---------------------------------------
447*54fd6939SJiyong Park
448*54fd6939SJiyong ParkGenerally, prefer code written in C over assembly. Assembly code is less
449*54fd6939SJiyong Parkportable, harder to understand, maintain and audit security wise. Also, static
450*54fd6939SJiyong Parkanalysis tools generally don't analyze assembly code.
451*54fd6939SJiyong Park
452*54fd6939SJiyong ParkThere are, however, legitimate uses of assembly language. These include:
453*54fd6939SJiyong Park
454*54fd6939SJiyong Park  - Early boot code executed before the C runtime environment is setup.
455*54fd6939SJiyong Park
456*54fd6939SJiyong Park  - Exception handling code.
457*54fd6939SJiyong Park
458*54fd6939SJiyong Park  - Low-level code where the exact sequence of instructions executed on the CPU
459*54fd6939SJiyong Park    matters, such as CPU reset sequences.
460*54fd6939SJiyong Park
461*54fd6939SJiyong Park  - Low-level code where specific system-level instructions must be used, such
462*54fd6939SJiyong Park    as cache maintenance operations.
463*54fd6939SJiyong Park
464*54fd6939SJiyong Park--------------
465*54fd6939SJiyong Park
466*54fd6939SJiyong Park*Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.*
467*54fd6939SJiyong Park
468*54fd6939SJiyong Park.. _`Linux master tree`: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/
469*54fd6939SJiyong Park.. _`Procedure Call Standard for the Arm Architecture`: https://developer.arm.com/docs/ihi0042/latest/
470*54fd6939SJiyong Park.. _`Procedure Call Standard for the Arm 64-bit Architecture`: https://developer.arm.com/docs/ihi0055/latest/
471*54fd6939SJiyong Park.. _`EditorConfig`: http://editorconfig.org/
472*54fd6939SJiyong Park.. _`Why the “volatile” type class should not be used`: https://www.kernel.org/doc/html/latest/process/volatile-considered-harmful.html
473*54fd6939SJiyong Park.. _`MISRA C:2012 Guidelines`: https://www.misra.org.uk/Activities/MISRAC/tabid/160/Default.aspx
474*54fd6939SJiyong Park.. _`a spreadsheet`: https://developer.trustedfirmware.org/file/download/lamajxif3w7c4mpjeoo5/PHID-FILE-fp7c7acszn6vliqomyhn/MISRA-and-TF-Analysis-v1.3.ods
475