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