1#######################
2Adding Secure Partition
3#######################
4
5***********************
6Terms and abbreviations
7***********************
8This document uses the following terms and abbreviations.
9
10.. table:: term table
11   :widths: auto
12
13   ================== ==================================
14    **Term**          **Meaning**
15   ================== ==================================
16   FF-M               Firmware Framework for M
17   ID                 Identifier
18   IPC                Interprocess communication
19   IPC model          The secure IPC framework
20   irqs               Interrupt requests
21   MMIO               Memory Mapped I/O
22   PSA                Platform Security Architecture
23   RoT                Root of Trust
24   SFN                Secure Function
25   SFN model          Secure Function model
26   SID                RoT Service ID
27   SP                 Secure Partition
28   SPM                Secure Partition Manager
29   TF-M               Trusted firmware M
30   ================== ==================================
31
32************
33Introduction
34************
35Secure Partition is an execution environment that provides the following
36functions to Root of Trust (RoT) Services:
37
38- Access to resources, protection of its own code and data.
39- Mechanisms to interact with other components in the system.
40
41Each Secure Partition is a single thread of execution and the smallest unit of
42isolation.
43
44This document mainly describes how to add a secure partition in TF-M and
45focuses on the configuration, manifest, implement rules. The actual
46source-level implementation is not included in this document.
47
48.. Note::
49   If not otherwise specified, the steps are identical for IPC and SFN model.
50
51   The IPC and SFN model conforms to the *PSA Firmware Framework for M (FF-M) v
52   1.1* changes. Refer to `PSA Firmware Framework specification`_ and
53   `Firmware Framework for M 1.1 Extensions`_ for details.
54
55*******
56Process
57*******
58The main steps to add a secure partition are as follows:
59
60- `Add source folder`_
61- `Add manifest`_
62- `Update the Build System`_
63- `Implement the RoT services`_
64
65Add source folder
66=================
67Add a source folder under ``<TF-M base folder>/secure_fw/partitions`` for the
68new secure partition (Let's take ``example`` as the folder name):
69
70This folder should include those parts:
71
72- Manifest file
73- CMake configuration files
74- Source code files
75
76Add manifest
77============
78Each Secure Partition must have resource requirements declared in a manifest
79file. The Secure Partition Manager (SPM) uses the manifest file to assemble and
80allocate resources within the SPE. The manifest includes the following:
81
82- A Secure Partition name.
83- A list of implemented RoT Services.
84- Access to other RoT Services.
85- Memory requirements.
86- Scheduling hints.
87- Peripheral memory-mapped I/O regions and interrupts.
88
89.. Note::
90   The current manifest format in TF-M is "yaml" which is different from the
91   requirement of PSA FF.
92
93.. Note::
94   The users can set LOW, NORMAL or HIGH in ``priority`` attribute in a Secure
95   Partition manifest.
96
97   The manifest tool ``tools/tfm_parse_manifest_list.py`` calculates the load
98   priority of Secure Partitions based on their ``priority`` values and their
99   dependencies.
100   SPM determines the loading and initialization order of Secure Partitions
101   based on their load priority values during TF-M initialization.
102
103   - A Secure Partition with a higher ``priority`` is loaded and initialized
104     before Secure Partitions with lower ``priority``.
105   - A Secure Partition is loaded and initialized after its dependencies are.
106
107Here is a manifest reference example for the IPC model:
108
109.. Note::
110    To use SFN model, the user needs to replace ``"model": "IPC"`` to
111    ``"model": "SFN"``. The user also needs to remove the attribute
112    ``"entry_point"``, and optionally replace it with ``"entry_init"``.
113
114.. code-block:: yaml
115
116  {
117    "psa_framework_version": 1.1,
118    "name": "TFM_SP_EXAMPLE",
119    "type": "APPLICATION-ROT",
120    "priority": "NORMAL",
121    "model": "IPC",
122    "entry_point": "tfm_example_main",
123    "stack_size": "0x0200",
124    "services" : [
125      {
126        "name": "ROT_A",
127        "sid": "0x000000E0",
128        "non_secure_clients": true,
129        "connection_based": true,
130        "version": 1,
131        "version_policy": "STRICT"
132        "mm_iovec": "disable"
133      }
134    ],
135    "mmio_regions": [
136      {
137        "name": "TFM_PERIPHERAL_A",
138        "permission": "READ-WRITE"
139      }
140    ],
141    "irqs": [
142      {
143        "source": "TFM_A_IRQ",
144        "name": "A_IRQ",
145        "handling": "SLIH"
146      }
147    ]
148    "dependencies": [
149      "TFM_CRYPTO",
150      "TFM_INTERNAL_TRUSTED_STORAGE_SERVICE"
151    ]
152  }
153
154Update manifest list
155--------------------
156The ``<TF-M base folder>/tools/tfm_manifest_list.yaml`` is used to collect
157necessary information of secure partition.
158The manifest tool ``tools/tfm_parse_manifest_list.py`` processes it and
159generates necessary files while building.
160
161Please refer to the :ref:`tfm_manifest_list` for the format of manifest lists.
162
163Reference configuration example:
164
165.. code-block:: yaml
166
167    {
168      "description": "TFM Example Partition",
169      "manifest": "secure_fw/partitions/example/tfm_example_partition.yaml",
170      "conditional": "@TFM_PARTITION_EXAMPLE@",
171      "output_path": "partitions/example",
172      "version_major": 0,
173      "version_minor": 1,
174      "pid": 290,
175      "linker_pattern": {
176        "library_list": [
177          "*tfm_*partition_example*"
178         ]
179      }
180    }
181
182TF-M also supports out-of-tree Secure Partition build where you can have your
183own manifest lists.
184Please refer to `Out-of-tree Secure Partition build`_ for details.
185
186Secure Partition ID Distribution
187--------------------------------
188Every Secure Partition has an identifier (ID). TF-M will generate a header file
189that includes definitions of the Secure Partition IDs. The header file is
190``<TF-M build folder>generated/interface/include/psa_manifest/pid.h``. Each
191definition uses the ``name`` attribute in the manifest as its name and the
192value is allocated by SPM.
193
194The Partition ID can be set to a fixed value or omitted to be auto allocated.
195
196.. code-block:: c
197
198   #define name id-value
199
200.. table:: PID table
201   :widths: auto
202
203   ==================================== ======================
204   **Secure Partitions**                **PID Range**
205   ==================================== ======================
206   TF-M Internal Partitions             0 - 255
207   PSA and user Partitions              256 - 2999
208   TF-M test Partitions                 3000 - 4999
209   Firmware Framework test Partitions   5000 - 5999
210   Reserved                             6000 -
211   ==================================== ======================
212
213Please refer to ``<TF-M base folder>/tools/tfm_manifest_list.yaml``,
214''<TF-M extras repo>/partitions/\*/\*_manifest_list.yaml'',
215``<TF-M test repo>/tests_reg/test/secure_fw/tfm_test_manifest_list.yaml`` and
216``<TF-M test repo>/tests_psa_arch/spe/tfm_psa_ff_test_manifest_list.yaml`` for the detailed
217PID allocations.
218
219About where to add the definition, please refer to the chapter `Update manifest list`_.
220
221RoT Service ID (SID) Distribution
222---------------------------------
223An RoT Service is identified by its RoT Service ID (SID). A SID is a 32-bit
224number that is associated with a symbolic name in the Secure Partition
225manifest. The bits [31:12] uniquely identify the vendor of the RoT Service.
226The remaining bits [11:0] can be used at the discretion of the vendor.
227
228Here is the RoT Service ID table used in TF-M.
229
230.. table:: SID table
231   :widths: auto
232
233   =========================== ====================== ========================
234   **Partitions**              **Vendor ID(20 bits)** **Function ID(12 bits)**
235   =========================== ====================== ========================
236   initial_attestation         0x00000                0x020-0x03F
237   platform                    0x00000                0x040-0x05F
238   protected_storage           0x00000                0x060-0x06F
239   internal_trusted_storage    0x00000                0x070-0x07F
240   crypto                      0x00000                0x080-0x09F
241   firmware_update             0x00000                0x0A0-0x0BF
242   tfm_secure_client           0x0000F                0x000-0x01F
243   tfm_ipc_client              0x0000F                0x060-0x07F
244   tfm_ipc_service             0x0000F                0x080-0x09F
245   tfm_slih_test_service       0x0000F                0x0A0-0x0AF
246   tfm_flih_test_service       0x0000F                0x0B0-0x0BF
247   tfm_ps_test_service         0x0000F                0x0C0-0x0DF
248   tfm_secure_client_2         0x0000F                0x0E0-0x0FF
249   tfm_sfn_test_service_1      0x0000F                0x100-0x11F
250   tfm_sfn_test_service_2      0x0000F                0x120-0x13F
251   tfm_attest_test_service     0x0000F                0x140-0x15F
252   =========================== ====================== ========================
253
254RoT Service Stateless Handle Distribution
255-----------------------------------------
256A Secure partition may include stateless services. They are distinguished and
257referenced by stateless handles. In manifest, a ``stateless_handle`` attribute
258is set for indexing stateless services. It must be either ``"auto"`` or a
259number in the range [1, 32] in current implementation and may extend. Also the
260``connection-based`` attribute must be set to ``false`` for stateless services.
261
262The indexes of stateless handles are divided into two ranges for different
263usages.
264Indexes [1, 16] are assigned to TF-M Secure Partitions.
265The rest indexes [17, 32] are reserved for any other Secure Partitions, for
266example Secure Partitions in ``tf-m-tests`` and ``tf-m-extras``.
267
268The following table summaries the stateless handle allocation for the TF-M
269Secure Partitions.
270
271.. table:: Stateless Handle table
272   :widths: auto
273
274   =============================== =======================
275    **Partition name**              **Stateless Handle**
276   =============================== =======================
277   TFM_SP_CRYPTO                   1
278   TFM_SP_PS                       2
279   TFM_SP_ITS                      3
280   TFM_SP_INITIAL_ATTESTATION      4
281   TFM_SP_FWU                      5
282   TFM_SP_PLATFORM                 6
283   =============================== =======================
284
285For the indexes of other Secure Partitions, please refer to their manifests or
286documentations.
287
288stack_size
289----------
290The ``stack_size`` is required to indicate the stack memory usage of the Secure
291Partition.
292The value of this attribute must be a decimal or hexadecimal value in bytes.
293It can also be a build configurable with default value defined in
294``config_base.cmake``.
295The value of the configuration can be overridden to fit different use cases.
296
297heap_size
298---------
299This attribute is optional. The default value is 0.
300It indicates the heap memory usage of the Secure Partition.
301The allowed values are the same as the ``stack_size``.
302
303mmio_regions
304------------
305This attribute is a list of MMIO region objects which the Secure Partition
306needs access to. TF-M only supports the ``named_region`` current. Please refer
307to PSA FF for more details about it. The user needs to provide a name macro to
308indicate the variable of the memory region.
309
310TF-M uses the below structure to indicate a peripheral memory.
311
312.. code-block:: c
313
314  struct platform_data_t {
315    uint32_t periph_start;
316    uint32_t periph_limit;
317    int16_t periph_ppc_bank;
318    int16_t periph_ppc_loc;
319  };
320
321.. Note::
322   This structure is not expected by TF-M, it's only that the current
323   implementations are using. Other peripherals that need different information
324   to create isolation need to define a different structure with the same name.
325
326Here is an example for it:
327
328.. code-block:: c
329
330   struct platform_data_t tfm_peripheral_A;
331   #define TFM_PERIPHERAL_A                 (&tfm_peripheral_A)
332
333mm_iovec
334--------
335Memory-mapped iovecs (MM-IOVEC) provides direct mapping of client input and output vectors into the
336Secure Partition.
337When this attribute is set to ``enable``, it enables Secure Partitions to use the MM-IOVEC APIs if
338the framework supports MM-IOVEC.
339
340Using MM-IOVEC provides a memory and runtime optimization for larger buffers, but reduces mitigation
341for common security vulnerabilities.
342Please refer to `Firmware Framework for M 1.1 Extensions`_ for more details.
343Whether to use MM-IOVEC depends on the requirements of memory and runtime optimization and security.
344
345Update the Build System
346=======================
347The following changes to the build system are required for the newly added secure partition.
348
349Add a CMakeLists.txt file
350-------------------------
351Each Secure Partition must have a corresponding ``CMakeLists.txt``, in this case,
352``<TF-M base folder>/secure_fw/partitions/example/CMakeLists.txt``, which is the compilation
353configuration for this Secure Partition.
354
355Here is a reference example for `CMakeLists.txt`_
356
357.. _CMakeLists.txt: https://git.trustedfirmware.org/plugins/gitiles/TF-M/tf-m-extras/+/refs/heads/main/examples/example_partition/CMakeLists.txt
358
359The CMake file should include the following contents
360
361- Add library ``tfm_app_rot_partition_example`` and associated source files.
362
363  .. code-block:: cmake
364
365      add_library(tfm_app_rot_partition_example STATIC)
366
367      target_sources(tfm_app_rot_partition_example
368          PRIVATE
369              tfm_example_partition.c
370      )
371
372  .. Note::
373    The secure partition must be built as a standalone static library, and the
374    name of the library must follow this pattern, as it affects how the linker
375    script will lay the partition in memory:
376
377    - ``tfm_psa_rot_partition*`` in case of a PSA RoT partition
378    - ``tfm_app_rot_partition*`` in case of an Application RoT partition
379
380- Add source files generated by the manifest tool.
381
382  .. code-block:: cmake
383
384    # The intermedia file defines the partition stack.
385    target_sources(tfm_app_rot_partition_example
386        PRIVATE
387            ${CMAKE_BINARY_DIR}/generated/example_partition/auto_generated/intermedia_tfm_example_partition.c
388    )
389
390    # The load info file includes the static data of the partition.
391    target_sources(tfm_partitions
392        INTERFACE
393            ${CMAKE_BINARY_DIR}/generated/example_partition/auto_generated/load_info_tfm_example_partition.c
394    )
395
396- Add dependency with manifest tool.
397
398  To make sure the above generated files are up-to-date when the Secure Partition library is built,
399  dependencies between the library and the manifest tool target should be set up.
400
401  .. code-block:: cmake
402
403    add_dependencies(tfm_app_rot_partition_example manifest_tool)
404
405- Link ``tfm_sprt`` for the PSA API interfaces.
406
407  .. code-block:: cmake
408
409    target_link_libraries(tfm_app_rot_partition_example
410        PRIVATE
411            tfm_sprt
412    )
413
414- Link the Secure Partition library to ``tfm_partitions`` so that it can be included in the final
415  image.
416
417  .. code-block:: cmake
418
419    target_link_libraries(tfm_partitions
420        INTERFACE
421            tfm_app_rot_partition_example
422    )
423
424Finally, the build of this Secure Partition should be added to
425``<TF-M base folder>/secure_fw/partitions/CMakeLists.txt``.
426
427  .. code-block:: cmake
428
429    add_subdirectory(example)
430
431Update the Config System
432------------------------
433If the Secure Partition has the build config to enable or disable it, the config option should be
434added to config systems.
435
436CMake Config
437^^^^^^^^^^^^
438The default value of the config option should be added to the
439``<TF-M base folder>/config/config_base.cmake``.
440
441  .. code-block:: cmake
442
443    set(TFM_PARTITION_EXAMPLE  OFF  CACHE BOOL  "Enable the example partition")
444
445Kconfig
446^^^^^^^
447A ``menuconfig`` should be added to ``<TF-M base folder>/secure_fw/partitions/example/Kconfig``.
448
449  .. code-block:: kconfig
450
451    menuconfig TFM_PARTITION_EXAMPLE
452        bool "Enable the Example Partition"
453        default n
454
455And add it to ``<TF-M base folder>/secure_fw/partitions/Kconfig``
456
457  .. code-block:: kconfig
458
459    rsource ``example/Kconfig``
460
461.. Note::
462
463  The Secure Partition building should be skipped if it is not enabled.
464  This should be done by adding the following code at the beginning of its ``CMakeLists.txt``
465
466  .. code-block:: cmake
467
468    if (NOT TFM_PARTITION_EXAMPLE)
469        return()
470    endif()
471
472Implement the RoT services
473==========================
474To implement RoT services, the partition needs a source file which contains the
475implementations of the services, as well as the partition entry point. The user
476can create this source file under
477``<TF-M base folder>/secure_fw/partitions/example/tfm_example_partition.c``.
478
479As an example, the RoT service with SID **ROT_A** will be implemented.
480
481Entry point for IPC Model Partitions
482------------------------------------
483This function must have a loop that repeatedly waits for input signals and
484then processes them, following the Secure Partition initialization.
485
486.. code-block:: c
487
488    #include "psa_manifest/tfm_example.h"
489    #include "psa/service.h"
490
491    void tfm_example_main(void)
492    {
493        psa_signal_t signals = 0;
494
495        /* Secure Partition initialization */
496        example_init();
497
498        /*
499         * Continually wait for one or more of the partition's RoT Service or
500         * interrupt signals to be asserted and then handle the asserted
501         * signal(s).
502         */
503        while (1) {
504            signals = psa_wait(PSA_WAIT_ANY, PSA_BLOCK);
505            if (signals & ROT_A_SIGNAL) {
506                rot_A();
507            } else {
508                /* Should not come here */
509                psa_panic();
510            }
511        }
512    }
513
514Entry init for SFN Model Partitions
515-----------------------------------
516In the SFN model, the Secure Partition consists of one optional initialization
517function, which is declared as the ``entry_init`` symbol as mentioned in
518section `Add manifest`_. After initialization, the entry_init function
519returns the following values:
520
521    - Return ``PSA_SUCCESS`` if initialization succeeds.
522
523    - Return ``PSA_SUCCESS`` if initialization is partially successful,
524      and you want some SFNs to receive messages. RoT Services that are
525      non-operational must respond to connection requests with
526      ``PSA_ERROR_CONNECTION_REFUSED``.
527
528    - Return an error status if the initialization failed, and no SFNs
529      within the Secure Partition must be called.
530
531Service implementation for IPC Model
532------------------------------------
533The service is implemented by the ``rot_A()`` function, which is called upon an
534incoming signal. This implementation is up to the user, however an example
535service has been included for reference. The following example sends a message
536"Hello World" when called.
537
538.. code-block:: c
539
540    #include "psa_manifest/tfm_example.h"
541    #include "psa/service.h"
542
543    /* Some other type of services. */
544    #define SOME_ROT_A_SERVICE_TYPE                (1)
545
546    static void rot_A(void)
547    {
548        const int BUFFER_LEN = 32;
549        psa_msg_t msg;
550        int i;
551        uint8_t rec_buf[BUFFER_LEN];
552        uint8_t send_buf[BUFFER_LEN] = "Hello World";
553
554        psa_get(ROT_A_SIGNAL, &msg);
555        switch (msg.type) {
556        case PSA_IPC_CONNECT:
557        case PSA_IPC_DISCONNECT:
558            /*
559             * This service does not require any setup or teardown on connect
560             * or disconnect, so just reply with success.
561             */
562            psa_reply(msg.handle, PSA_SUCCESS);
563            break;
564        default:
565            /* Handling services requested by psa_call. */
566            if (msg.type == PSA_IPC_CALL) {
567                for (i = 0; i < PSA_MAX_IOVEC; i++) {
568                    if (msg.in_size[i] != 0) {
569                        psa_read(msg.handle, i, rec_buf, BUFFER_LEN);
570                    }
571                    if (msg.out_size[i] != 0) {
572                        psa_write(msg.handle, i, send_buf, BUFFER_LEN);
573                    }
574                }
575                psa_reply(msg.handle, PSA_SUCCESS);
576            } else if (msg.type == SOME_ROT_A_SERVICE_TYPE) {
577                /* Operations for SOME_ROT_A_SERVICE_TYPE */
578            } else {
579                /* Invalid type for this Secure Partition. */
580                return PSA_ERROR_PROGRAMMER_ERROR;
581            }
582        }
583    }
584
585Service implementation for SFN Model
586------------------------------------
587SFN model consists of a set of Secure Functions (SFN), one for each RoT
588Service. The connection, disconnection and request messages do not cause a
589Secure Partition signal to be asserted for SFN Secure Partitions. Instead,
590the Secure Function (SFN) for the RoT Service is invoked by the framework,
591with the message details provided as a parameter to the SFN. To add a secure
592function (SFN) to process messages for each RoT Service, each SFN will have
593following prototype.
594
595.. code-block:: c
596
597  psa_status_t <<name>>_sfn(const psa_msg_t *msg);
598
599A connection-based example service has been included for reference which
600sends a message "Hello World" when called.
601
602.. code-block:: c
603
604    #include "psa_manifest/tfm_example.h"
605    #include "psa/service.h"
606
607    /* Some other type of services. */
608    #define SOME_ROT_A_SERVICE_TYPE                (1)
609
610    psa_status_t rot_a_sfn(const psa_msg_t *msg)
611    {
612        const int BUFFER_LEN = 32;
613        int i;
614        uint8_t rec_buf[BUFFER_LEN];
615        uint8_t send_buf[BUFFER_LEN] = "Hello World";
616
617        switch (msg->type) {
618        case PSA_IPC_CONNECT:
619        case PSA_IPC_DISCONNECT:
620            /*
621             * This service does not require any setup or teardown on connect
622             * or disconnect, so just reply with success.
623             */
624            return PSA_SUCCESS;
625        default:
626            /* Handling services requested by psa_call. */
627            if (msg->type == PSA_IPC_CALL) {
628                for (i = 0; i < PSA_MAX_IOVEC; i++) {
629                    if (msg->in_size[i] != 0) {
630                        psa_read(msg->handle, i, rec_buf, BUFFER_LEN);
631                    }
632                    if (msg.->out_size[i] != 0) {
633                        psa_write(msg->handle, i, send_buf, BUFFER_LEN);
634                    }
635                }
636                return PSA_SUCCESS;
637            } else if (msg->type == SOME_ROT_A_SERVICE_TYPE) {
638                /* Operations for SOME_ROT_A_SERVICE_TYPE */
639            } else {
640                /* Invalid type for this Secure Partition. */
641                return PSA_ERROR_PROGRAMMER_ERROR;
642            }
643        }
644    }
645
646Test suites and test partitions
647-------------------------------
648
649A regression test suite can be added to verify whether the new secure partition
650works as expected. Refer to
651`Adding TF-M Regression Test Suite <https://trustedfirmware-m.readthedocs.io/projects/tf-m-tests/en/latest/tfm_test_suites_addition.html#adding-a-new-test-suite>`_
652for the details of adding a regression test suite.
653
654Some regression tests require a dedicated RoT service. The implementations of
655the RoT service for test are similar to secure partition addition. Refer to
656`Adding partitions for regression tests <https://trustedfirmware-m.readthedocs.io/projects/tf-m-tests/en/latest/tfm_test_partitions_addition.html>`_
657to get more information.
658
659Out-of-tree Secure Partition build
660----------------------------------
661
662TF-M supports out-of-tree Secure Partition build, whose source code folders
663are maintained outside TF-M repo. Developers can configure
664``TFM_EXTRA_MANIFEST_LIST_FILES`` and ``TFM_EXTRA_PARTITION_PATHS`` in build
665command line to include out-of-tree Secure Partitions.
666
667- ``TFM_EXTRA_MANIFEST_LIST_FILES``
668
669  A list of the absolute path(s) of the manifest list(s) provided by out-of-tree
670  Secure Partition(s).
671  Use semicolons ``;`` to separate multiple manifest lists. Wrap the multiple
672  manifest lists with double quotes.
673
674- ``TFM_EXTRA_PARTITION_PATHS``
675
676  A list of the absolute directories of the out-of-tree Secure Partition source
677  code folder(s). TF-M build system searches ``CMakeLists.txt`` of partitions in
678  the source code folder(s).
679  Use semicolons ``;`` to separate multiple out-of-tree Secure Partition
680  directories. Wrap the multiple directories with double quotes.
681
682A single out-of-tree Secure Partition folder can be organized as the figure
683below.
684
685::
686
687  secure partition folder
688        ├── CMakeLists.txt
689        ├── manifest_list.yaml
690        ├── out_of_tree_partition_manifest.yaml
691        └── source code
692
693In the example above, ``TFM_EXTRA_MANIFEST_LIST_FILES`` and
694``TFM_EXTRA_PARTITION_PATHS`` in the build command can be configured as listed
695below.
696
697.. code-block:: bash
698
699  -DTFM_EXTRA_MANIFEST_LIST_FILES=<Absolute-path-sp-folder/manifest_list.yaml>
700  -DTFM_EXTRA_PARTITION_PATHS=<Absolute-path-sp-folder>
701
702Multiple out-of-tree Secure Partitions can be organized in diverse structures.
703For example, multiple Secure Partitions can be maintained under the same
704directory as shown below.
705
706::
707
708  top-level folder
709        ├── Partition 1
710        │       ├── CMakeLists.txt
711        │       ├── partition_1_manifest.yaml
712        │       └── source code
713        ├── Partition 2
714        │       └── ...
715        ├── Partition 3
716        │       └── ...
717        ├── manifest_list.yaml
718        └── Root CMakeLists.txt
719
720In the example above, a root CMakeLists.txt includes all the partitions'
721CMakLists.txt, for example via ``add_subdirectory()``. The manifest_list.yaml
722lists all partitions' manifest files.
723``TFM_EXTRA_MANIFEST_LIST_FILES`` and ``TFM_EXTRA_PARTITION_PATHS`` in build
724command line can be configured as listed below.
725
726.. code-block:: bash
727
728  -DTFM_EXTRA_MANIFEST_LIST_FILES=<Absolute-path-top-level-folder/manifest_list.yaml>
729  -DTFM_EXTRA_PARTITION_PATHS=<Absolute-path-top-level-folder>
730
731Alternatively, out-of-tree Secure Partitions can be separated in different
732folders.
733
734::
735
736    partition 1 folder                    partition 2 folder
737        ├── CMakeLists.txt                    ├── CMakeLists.txt
738        ├── manifest_list.yaml                ├── manifest_list.yaml
739        ├── partition_1_manifest.yaml         ├── partition_2_manifest.yaml
740        └── source code                       └── source code
741
742In the example above, each Secure Partition manages its own manifest files and
743CMakeLists.txt. ``TFM_EXTRA_MANIFEST_LIST_FILES`` and
744``TFM_EXTRA_PARTITION_PATHS`` in build command line can be configured as listed
745below. Please note those input shall be wrapped with double quotes.
746
747.. code-block:: bash
748
749  -DTFM_EXTRA_MANIFEST_LIST_FILES="<Absolute-path-part-1-folder/manifest_list.yaml>;<Absolute-path-part-2-folder/manifest_list.yaml>"
750  -DTFM_EXTRA_PARTITION_PATHS="<Absolute-path-part-1-folder>;<Absolute-path-part-2-folder>"
751
752.. Note::
753
754   Manifest list paths in ``TFM_EXTRA_MANIFEST_LIST_FILES`` do NOT have to be
755   one-to-one mapping to Secure Partition directories in
756   ``TFM_EXTRA_PARTITION_PATHS``. The orders don't matter either.
757
758   ``TFM_EXTRA_MANIFEST_LIST_FILES`` and ``TFM_EXTRA_PARTITION_PATHS`` can be
759   configured in multiple extra sources. It is recommended to use CMake list
760   ``APPEND`` method to avoid unexpected override.
761
762Further Notes
763-------------
764
765- In the IPC model, Use PSA FF proposed memory accessing mechanism. SPM
766  provides APIs and checking between isolation boundaries, a free accessing
767  of memory can cause program panic.
768- In the IPC model, the memory checking inside partition runtime is
769  unnecessary. SPM handles the checking while memory accessing APIs are
770  called.
771- In the IPC model, the client ID had been included in the message structure
772  and secure partition can get it when calling psa_get() function. The secure
773  partition does not need to call ``tfm_core_get_caller_client_id()`` to get
774  the caller client ID anymore.
775- In the IPC model, SPM will check the security policy and partition
776  dependence between client and service. So the service does not need to
777  validate the secure caller anymore.
778
779*********
780Reference
781*********
782
783| `PSA Firmware Framework specification`_
784| `Firmware Framework for M 1.1 Extensions`_
785
786.. _PSA Firmware Framework specification:
787  https://www.arm.com/architecture/security-features/platform-security
788
789.. _Firmware Framework for M 1.1 Extensions: https://developer.arm.com/
790  documentation/aes0039/latest
791
792--------------
793
794*SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributor*
795