aboutsummaryrefslogtreecommitdiff
path: root/docs/technical_references/hardware_abstraction_layer.rst
blob: 645426f61735eef620012255448a9206e4ed9afc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
##########################
Hardware Abstraction Layer
##########################

:Organization: Arm Limited
:Contact: tf-m@lists.trustedfirmware.org

:API Version: 0.9

************
Introduction
************
:term:`TF-M` :term:`HAL` abstracts the hardware-oriented and platform specific
operations on the :term:`SPE` side and provides a set of APIs to the upper
layers such as :term:`SPM`, :term:`RoT Service`.
The :term:`HAL` aims to cover the platform different aspects whereas common
architecturally defined aspects are done generically within the common
:term:`SPE`.
In some cases, although the operations are defined architecturally,
it may not be possible to generalize implementations because lots of information
is only known to platforms.
It is more efficient to define a :term:`HAL` API for those architectural
operations as well.

.. note::
  :term:`TBSA-M` provides the hardware requirements for security purposes.
  :term:`TF-M` :term:`HAL` tries to reference :term:`TBSA-M` recommendations in
  the interfaces from the software perspective only. Please reference
  :term:`TBSA-M` for your security hardware design.

Design Goals
============
:term:`TF-M` :term:`HAL` is designed to simplify the integration efforts on
different platforms.

:term:`TF-M` :term:`HAL` is designed to make it easy to use the hardware and
develop the :term:`SPM` and :term:`RoT Service` which need to access the
devices.

:term:`TF-M` :term:`HAL` is designed to make the structure clearer and let the
:term:`TF-M` mainly focus on :term:`PSA` implementation.

********
Overview
********
This section provides an overview of the abstraction layer structure.

.. figure:: media/hal_structure.png

Here lists a minimal set of necessary functionalities:

  - **Isolation API**: Provides the necessary isolation functionalities required
    by the :term:`PSA-FF-M` and :term:`TBSA-M`, and provides APIs to :term:`SPM`
    to check the permissions of memory access.
  - **Platform API**: Provides the platform initialization, platform-specific
    memory information, system reset, etc.
  - **Log dev API**: Provides the log system functions.
  - **Interrupt API**: Provides the interrupt functions.

.. note::
  - There is a non-secure :term:`HAL` that focuses on the mailbox operation API
    for Dual-core topology. For more information about it, please refer to
    :doc:`Mailbox Design in TF-M on Dual-core System
    </docs/technical_references/dual-cpu/mailbox_design_on_dual_core_system>`.
  - The minimal set of :term:`TF-M` :term:`HAL` is sufficient for Secure
    Partitions by using customized peripheral interfaces. To provide easier
    portability for the Secure Partitions, a Secure Partition :term:`HAL` is
    provided in this design too.
  - The debug mechanisms give the external entity the corresponding right to
    access the system assets. :term:`TF-M` ensures that the external entity is
    permitted access to those assets. Currently, :term:`TF-M` only needs the
    debug authentication. The whole debug mechanism and related :term:`HAL` will
    be enhanced in the future. Please refer to the :doc:`Debug authentication
    settings section </platform/readme>` for more detail.

*****************
Design Principles
*****************
As :term:`TF-M` runs on resource-constrained devices, the :term:`HAL` tries to
avoid multiple level abstractions which cost more resources.

Part of the :term:`HAL` interfaces does not focus on exact hardware operations
such as power on/off or PIN manipulation.
Instead, the :term:`HAL` abstracts higher-level interfaces to reserve the
implementation flexibility for the platform vendors.

The :term:`TF-M` :term:`HAL` should be easy to deprecate APIs and provide
compatibilities.
Any API incompatibility should be detected during building.

:term:`TF-M` relies on the :term:`HAL` APIs to be implemented correctly and
trusts the :term:`HAL` APIs.
:term:`TFM` can provide assertions to detect common programming errors but
essentially no further extensive checks will be provided.

************
Source Files
************
This section describes the source file of the :term:`TF-M` :term:`HAL`,
including the header and c files.

tfm_hal_defs.h
==============
This header file contains the definitions of common macros and types used by all
:term:`HAL` APIs. Please refer to `Status Codes`_ for detailed definitions.

tfm_hal_[module].[h/c]
======================
All other headers and c files are classified by the modules, such as isolation,
platform, interrupt, devices, etc.

.. note::
  There are common files in the platform folder include the implemented
  :term:`HAL` APIs. The platform vendors can use them directly but need to
  implement all the sub APIs.

************
Status Codes
************
These are common status and error codes for all :term:`HAL` APIs.

Types
=====
tfm_hal_status_t
----------------
This is a status code to be used as the return type of :term:`HAL` APIs.

.. code-block:: c

  enum tfm_hal_status_t {
      TFM_HAL_ERROR_MEM_FAULT = SCHAR_MIN,
      TFM_HAL_ERROR_MAX_VALUE,
      TFM_HAL_ERROR_BAD_STATE,
      TFM_HAL_ERROR_NOT_SUPPORTED,
      TFM_HAL_ERROR_INVALID_INPUT,
      TFM_HAL_ERROR_NOT_INIT,
      TFM_HAL_ERROR_GENERIC,
      TFM_HAL_SUCCESS = 0
  };

Error Codes
===========
Negative values indicate an error. Zero and positive values indicate success.

Here is the general list. The detailed usages for each error code are described
in the API introduction sections.

TFM_HAL_SUCCESS
---------------
Status code to indicate general success.

TFM_HAL_ERROR_GENERIC
---------------------
Status code to indicate an error that does not correspond to any defined failure
cause.

TFM_HAL_ERROR_NOT_INIT
----------------------
Status code to indicate that the module is not initialed.

TFM_HAL_ERROR_INVALID_INPUT
---------------------------
Status code to indicate that the input is invalid.

TFM_HAL_ERROR_NOT_SUPPORTED
---------------------------
Status code to indicate that the requested operation or a parameter is not
supported.

TFM_HAL_ERROR_BAD_STATE
-----------------------
Status code to indicate that the requested action cannot be performed in the
current state.

TFM_HAL_ERROR_MAX_VALUE
-----------------------
Status code to indicate that the current number has got the max value.

TFM_HAL_ERROR_MEM_FAULT
-----------------------
Status code to indicate that the memory check failed.

***************************
API Definition for TF-M SPM
***************************
This section describes the APIs defined for :term:`TF-M` :term:`SPM`.

Platform API
============
The platform API is a higher-level abstraction layer of the platform, other than
a dedicated API set for the special hardware devices.

APIs
----
tfm_hal_platform_init()
^^^^^^^^^^^^^^^^^^^^^^^
**Prototype**

.. code-block:: c

  enum tfm_hal_status_t tfm_hal_platform_init(void)

**Description**

This API performs the platform-specific initialization.

This API is called after architecture and platform common initialization has
finished during system early startup.

**Parameter**

- ``void`` - None.

**Return Values**

- ``TFM_HAL_SUCCESS`` - Init success.
- ``TFM_HAL_ERROR_GENERIC`` - Generic errors.

tfm_hal_system_reset()
^^^^^^^^^^^^^^^^^^^^^^
**Prototype**

.. code-block:: c

  void tfm_hal_system_reset(void)

**Description**

This API performs a system reset.

The platform can uninitialize some resources before reset.

**Parameter**

- ``void`` - None

**Return Values**

- ``void`` - None

**Note**

This API should not return.

Isolation API
=============
The :term:`PSA-FF-M` defines three isolation levels and a memory access rule to
provide diverse levels of securitiy. The isolation API provides the functions to
implement these requirements.

Memory Access Attributes
------------------------
The memory access attributes are encoded as bit fields, you can logic OR them to
have a combination of the atrributes, for example
``TFM_HAL_MEM_ATTR_UNPRIVILEGED | TFM_HAL_MEM_ATTR_READABLE`` is unprivileged
readable. The data type is `uint32_t`.

TFM_HAL_MEM_ATTR_EXECUTABLE
^^^^^^^^^^^^^^^^^^^^^^^^^^^
The memory is executable.

.. code-block:: c

  #define TFM_HAL_MEM_ATTR_EXECUTABLE (1UL << 0)

TFM_HAL_MEM_ATTR_READABLE
^^^^^^^^^^^^^^^^^^^^^^^^^
The memory is readable.

.. code-block:: c

  #define TFM_HAL_MEM_ATTR_READABLE (1UL << 1)

TFM_HAL_MEM_ATTR_WRITABLE
^^^^^^^^^^^^^^^^^^^^^^^^^
The memory is writable.

.. code-block:: c

  #define TFM_HAL_MEM_ATTR_WRITABLE (1UL << 2)

TFM_HAL_MEM_ATTR_UNPRIVILEGED
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The memory is unprivileged mode accessible.

.. code-block:: c

  #define TFM_HAL_MEM_ATTR_UNPRIVILEGED (1UL << 3)

TFM_HAL_MEM_ATTR_DEVICE
^^^^^^^^^^^^^^^^^^^^^^^
The memory is a MMIO device.

.. code-block:: c

  #define TFM_HAL_MEM_ATTR_DEVICE (1UL << 4)

TFM_HAL_MEM_ATTR_NS
^^^^^^^^^^^^^^^^^^^
The memory is accessible from :term:`NSPE`

.. code-block:: c

  #define TFM_HAL_MEM_ATTR_NS (1UL << 5)

APIs
----
tfm_hal_set_up_static_boundaries()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
**Prototype**

.. code-block:: c

  tfm_hal_status_t tfm_hal_set_up_static_boundaries(void)

**Description**

This API sets up the static isolation boundaries which are constant throughout
the runtime of the system.

The boundaries include:

- The SPE boundary between the :term:`SPE` and the :term:`NSPE`
- The PSA RoT isolation boundary between the PSA Root of Trust and the
  Application Root of Trust which is for isolation level 2 and 3 only.

Please refer to the :term:`PSA-FF-M` for the definitions of the isolation
boundaries.

**Return Values**

- ``TFM_HAL_SUCCESS`` - the isolation boundaries have been set up.
- ``TFM_HAL_ERROR_GENERIC`` - failed to set up the isolation boundaries.

tfm_hal_mpu_update_partition_boundary
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
**Prototype**

.. code-block:: c

  enum tfm_hal_status_t tfm_hal_mpu_update_partition_boundary(uintptr_t start,
                                                              uintptr_t end);

**Description**

This API updates the partition isolation boundary for isolation level 3.
Inside the partition isolation boundary is the private data of the running
Secure Partition.
This boundary is updated dynamically when :term:`SPM` switches Partitions in
isolation level 3.

The access permissions of the boundary is all privileged mode read-write.

Platforms decide which :term:`MPU` region the paritition boundary uses.

**Parameter**

- ``start`` - start address of the partition boundary.
- ``end`` - end address of the partition boundary.

**Return Values**

- ``TFM_HAL_SUCCESS`` - the isolation boundary has been set up.
- ``TFM_HAL_ERROR_GENERIC`` - failed to set upthe isolation boundary.

**Note**

This API is only for platforms using :term:`MPU` as isolation hardwares.
A generic API for all platforms will be introduced in future versions.

tfm_hal_memory_has_access()
^^^^^^^^^^^^^^^^^^^^^^^^^^^
**Prototype**

.. code-block:: c

  tfm_hal_status_t tfm_hal_memory_has_access(const uintptr_t base,
                                             size_t size,
                                             uint32_t attr)

**Description**

This API checks if the memory region defined by ``base`` and ``size`` has the
given access atrributes - ``attr``.

The Attributes include :term:`NSPE` access, privileged mode, and read-write
permissions.

**Parameter**

- ``base`` - The base address of the region.
- ``size`` - The size of the region.
- ``attr`` - The `Memory Access Attributes`_.

**Return Values**

- ``TFM_HAL_SUCCESS`` - The memory region has the access permissions.
- ``TFM_HAL_ERROR_MEM_FAULT`` - The memory region does not have the access
  permissions.
- ``TFM_HAL_ERROR_INVALID_INPUT`` - Invalid inputs.
- ``TFM_HAL_ERROR_GENERIC`` - An error occurred.

Log API
=======
The log API is used by the :term:`TF-M` :doc:`log system <tfm_log_system_design_document>`.
The log device could be uart, memory, usb, etc.

APIs
----
tfm_hal_output_partition_log()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
**Prototype**

.. code-block:: c

  int32_t tfm_hal_output_partition_log(const unsigned char *str, uint32_t len)

**Description**

This API is called by Secure Partition to output logs.

**Parameter**

- ``str`` - The string to output.
- ``len`` - Length of the string in bytes.

**Return Values**

- Positive values - Number of bytes output.
- ``TFM_HAL_ERROR_NOT_INIT`` - The log device has not been initialized.
- ``TFM_HAL_ERROR_INVALID_INPUT`` - Invalid inputs when ``str`` is ``NULL`` or
  ``len`` is zero.

**Note**

None.

tfm_hal_output_spm_log()
^^^^^^^^^^^^^^^^^^^^^^^^
**Prototype**

.. code-block:: c

  int32_t tfm_hal_output_spm_log(const unsigned char *str, uint32_t len)

**Description**

This API is called by :term:`SPM` to output logs.

**Parameter**

- ``str`` - The string to output.
- ``len`` - Length of the string in bytes.

**Return Values**

- Positive numbers - Number of bytes output.
- ``TFM_HAL_ERROR_NOT_INIT`` - The log device has not been initialized.
- ``TFM_HAL_ERROR_INVALID_INPUT`` - Invalid inputs when ``str`` is ``NULL``
  or ``len`` is zero.

**Note**

Please check :doc:`TF-M log system <tfm_log_system_design_document>` for more
information.

************************************
API Definition for Secure Partitions
************************************
The Secure Partition (SP) :term:`HAL` mainly focuses on two parts:

  - Peripheral devices. The peripherals accessed by the :term:`TF-M` default
    Secure Partitions.
  - Secure Partition abstraction support. The Secure Partition data that must be
    provided by the platform.

The Secure Partition abstraction support will be introduced in the peripheral
API definition.

ITS and PS flash API
====================
There are two kinds of flash:

  - Internal flash. Accessed by the PSA Internal Trusted Storage (ITS) service.
  - External flash. Accessed by the PSA Protected Storage (PS) service.

The ITS HAL for the internal flash device is defined in the ``tfm_hal_its.h``
header and the PS HAL in the ``tfm_hal_ps.h`` header.

Macros
------
Internal Trusted Storage
^^^^^^^^^^^^^^^^^^^^^^^^
TFM_HAL_ITS_FLASH_DRIVER
~~~~~~~~~~~~~~~~~~~~~~~~
Defines the identifier of the CMSIS Flash ARM_DRIVER_FLASH object to use for
ITS. It must have been allocated by the platform and will be declared extern in
the HAL header.

TFM_HAL_ITS_PROGRAM_UNIT
~~~~~~~~~~~~~~~~~~~~~~~~
Defines the size of the ITS flash device's physical program unit (the smallest
unit of data that can be individually programmed to flash). It must be equal to
TFM_HAL_ITS_FLASH_DRIVER.GetInfo()->program_unit, but made available at compile
time so that filesystem structures can be statically sized.

TFM_HAL_ITS_FLASH_AREA_ADDR
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Defines the base address of the dedicated flash area for ITS.

TFM_HAL_ITS_FLASH_AREA_SIZE
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Defines the size of the dedicated flash area for ITS in bytes.

TFM_HAL_ITS_SECTORS_PER_BLOCK
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Defines the number of contiguous physical flash erase sectors that form a
logical filesystem erase block.

Protected Storage
^^^^^^^^^^^^^^^^^
TFM_HAL_PS_FLASH_DRIVER
~~~~~~~~~~~~~~~~~~~~~~~
Defines the identifier of the CMSIS Flash ARM_DRIVER_FLASH object to use for
PS. It must have been allocated by the platform and will be declared extern in
the HAL header.

TFM_HAL_PS_PROGRAM_UNIT
~~~~~~~~~~~~~~~~~~~~~~~~
Defines the size of the PS flash device's physical program unit (the smallest
unit of data that can be individually programmed to flash). It must be equal to
TFM_HAL_PS_FLASH_DRIVER.GetInfo()->program_unit, but made available at compile
time so that filesystem structures can be statically sized.

TFM_HAL_PS_FLASH_AREA_ADDR
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Defines the base address of the dedicated flash area for PS.

TFM_HAL_PS_FLASH_AREA_SIZE
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Defines the size of the dedicated flash area for PS in bytes.

TFM_HAL_PS_SECTORS_PER_BLOCK
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Defines the number of contiguous physical flash erase sectors that form a
logical filesystem erase block.

Optional definitions
--------------------
The ``TFM_HAL_ITS_FLASH_AREA_ADDR``, ``TFM_HAL_ITS_FLASH_AREA_SIZE`` and
``TFM_HAL_ITS_SECTORS_PER_BLOCK`` definitions are optional. If not defined, the
platform must implement ``tfm_hal_its_fs_info()`` instead.

Equivalently, ``tfm_hal_its_ps_info()`` must be implemented by the platform if
``TFM_HAL_ITS_FLASH_AREA_ADDR``, ``TFM_HAL_ITS_FLASH_AREA_SIZE`` or
``TFM_HAL_ITS_SECTORS_PER_BLOCK`` is not defined.

Objects
-------
ARM_DRIVER_FLASH
^^^^^^^^^^^^^^^^
The ITS and PS HAL headers each expose a CMSIS Flash Driver instance.

.. code-block:: c

    extern ARM_DRIVER_FLASH TFM_HAL_ITS_FLASH_DRIVER

    extern ARM_DRIVER_FLASH TFM_HAL_PS_FLASH_DRIVER

The CMSIS Flash Driver provides the flash primitives ReadData(), ProgramData()
and EraseSector() as well as GetInfo() to access flash device properties such
as the sector size.

Types
-----
tfm_hal_its_fs_info_t
^^^^^^^^^^^^^^^^^^^^^
Struct containing information required from the platform at runtime to configure
the ITS filesystem.

.. code-block:: c

    struct tfm_hal_its_fs_info_t {
        uint32_t flash_area_addr;
        size_t flash_area_size;
        uint8_t sectors_per_block;
    };

Each attribute is described below:

  - ``flash_area_addr`` - Location of the block of flash to use for ITS
  - ``flash_area_size`` - Number of bytes of flash to use for ITS
  - ``sectors_per_block`` - Number of erase sectors per logical FS block

tfm_hal_ps_fs_info_t
^^^^^^^^^^^^^^^^^^^^^
Struct containing information required from the platform at runtime to configure
the PS filesystem.

.. code-block:: c

    struct tfm_hal_ps_fs_info_t {
        uint32_t flash_area_addr;
        size_t flash_area_size;
        uint8_t sectors_per_block;
    };

Each attribute is described below:

  - ``flash_area_addr`` - Location of the block of flash to use for PS
  - ``flash_area_size`` - Number of bytes of flash to use for PS
  - ``sectors_per_block`` - Number of erase sectors per logical FS block

Functions
---------
tfm_hal_its_fs_info()
^^^^^^^^^^^^^^^^^^^^^
**Prototype**

.. code-block:: c

    enum tfm_hal_status_t tfm_hal_its_fs_info(struct tfm_hal_its_fs_info_t *fs_info);

**Description**

Retrieves the filesystem configuration parameters for ITS.

**Parameter**

- ``fs_info`` - Filesystem config information

**Return values**

- ``TFM_HAL_SUCCESS`` - The operation completed successfully
- ``TFM_HAL_ERROR_INVALID_INPUT`` - Invalid parameter

**Note**

This function should ensure that the values returned do not result in a security
compromise. The block of flash supplied must meet the security requirements of
Internal Trusted Storage.

tfm_hal_ps_fs_info()
^^^^^^^^^^^^^^^^^^^^
**Prototype**

.. code-block:: c

    enum tfm_hal_status_t tfm_hal_ps_fs_info(struct tfm_hal_ps_fs_info_t *fs_info);

**Description**

Retrieves the filesystem configuration parameters for PS.

**Parameter**

- ``fs_info`` - Filesystem config information

**Return values**

- ``TFM_HAL_SUCCESS`` - The operation completed successfully
- ``TFM_HAL_ERROR_INVALID_INPUT`` - Invalid parameter

**Note**

This function should ensure that the values returned do not result in a security
compromise.

--------------

*Copyright (c) 2020-2021, Arm Limited. All rights reserved.*