1##########################################
2Mailbox Design in TF-M on Dual-core System
3##########################################
4
5:Author: David Hu
6:Organization: Arm Limited
7:Contact: david.hu@arm.com
8
9************
10Introduction
11************
12
13This document proposes a generic design of the mailbox communication for Trusted
14Firmware-M (TF-M) on a dual-core system. The mailbox functionalities transfer
15PSA Client requests and results between Non-secure Processing Environment (NSPE)
16and Secure Processing Environment (SPE).
17
18The dual-core system should satisfy the following requirements
19
20- NSPE and SPE are properly isolated and protected following PSA specifications.
21- An Arm M-profile core locates in SPE and acts as the Secure core.
22- TF-M runs on the Secure core with platform specific drivers support.
23- Inter-Processor Communication hardware module in system for communication
24  between Secure core and Non-secure core. Mailbox communication calls the
25  Inter-Processor Communication to transfer notifications.
26- Non-secure memory shared by NSPE and SPE.
27
28Scope
29=====
30
31This design document focuses on the mailbox functionalities in NSPE and SPE on a
32dual-core system. The mailbox functionalities include the initialization of
33mailbox in NSPE and SPE, and the transfer of PSA Client requests and replies
34between NSPE and SPE.
35
36.. note::
37  This document is partially complete since the introduction of the Hybrid
38  Platform Scheduling support, which extends the operation of the mailbox
39  communication between local and remote NSPEs with SPE described here.
40  For more details see :doc:`/design_docs/dual-cpu/hybrid_platform_solution`.
41
42
43Data types and mailbox APIs are defined in this document.
44
45Some details of interactions between mailbox and other modules are specified in
46other documents.
47Communication prototype design [1]_ defines a general communication prototype
48between NSPE and SPE on a dual-core system. It describes how TF-M interacts with
49mailbox functionalities and the general requirements on mailbox.
50Dual-core booting sequence [2]_ describes a synchronization step of mailbox
51between NSPE and SPE during system booting.
52
53Organization of the document
54============================
55
56- `Mailbox architecture`_ provides an overview on the mailbox architecture.
57- `Mailbox communication for PSA Client calls`_ discusses about the mailbox
58  communication for PSA Client calls.
59- `Mailbox initialization`_ introduces the initialization of mailbox.
60- `Mailbox APIs and data structures`_ lists mailbox data types and APIs.
61
62********************
63Mailbox architecture
64********************
65
66The mailbox consists of two parts sitting in NSPE and SPE respectively.
67NSPE mailbox provides mailbox functionalities in NSPE and SPE mailbox provides
68mailbox functionalities in TF-M in SPE.
69
70PSA Client APIs called in NSPE are implemented by NSPE mailbox functions on
71dual-core systems, to send PSA Client request and receive the result. The
72implementation can vary in diverse NSPE OSs or use cases.
73
74TF-M provides a reference implementation of NSPE mailbox. The NSPE mailbox
75delivers the PSA Client requests to SPE mailbox. After the PSA Client result is
76replied from SPE, NSPE mailbox fetches the result and returns it to PSA Client
77APIs.
78
79NSPE mailbox objects are managed by NSPE mailbox in non-secure memory to hold
80PSA Client call parameters, return result and other mailbox data.
81NSPE mailbox relies on platform specific Inter-Process Communication to process
82notifications between NSPE and SPE.
83
84The SPE mailbox in TF-M receives PSA Client requests from NSPE mailbox. It
85parses the requests and invokes TF-M Remote Procedure Call (RPC) layer.
86RPC layer delivers the requests to TF-M core/Secure Partition Manager (SPM).
87After the PSA Client call is completed, TF-M core/SPM invokes RPC layer to
88return results to NSPE, via SPE mailbox.
89SPE mailbox objects are managed by SPE mailbox in secure memory.
90SPE mailbox relies on platform specific Inter-Process Communication to process
91notifications between SPE and NSPE.
92
93The architecture is showed in following figure.
94
95.. figure:: dual_core_mailbox_arch.png
96
97******************************************
98Mailbox communication for PSA Client calls
99******************************************
100
101This section describes the transfer of PSA Client request and reply between NSPE
102and SPE via mailbox.
103
104Mailbox objects
105===============
106
107This section lists the mailbox objects required in NSPE and SPE.
108
109NSPE mailbox objects are managed by NSPE mailbox in non-secure memory. But NSPE
110mailbox objects can be accessed by both NSPE mailbox and SPE mailbox.
111
112SPE mailbox objects are managed by SPE mailbox in secure memory. SPE mailbox
113objects should be protected from NSPE accesses by system specific isolation.
114
115NSPE Mailbox queue
116------------------
117
118NSPE mailbox maintains a mailbox queue in non-secure memory. Please refer to the
119structure definition in `NSPE mailbox queue structure`_.
120
121NSPE mailbox queue contains one or more slots. The number of slots should be
122aligned with that in SPE mailbox queue.
123
124Each slot in NSPE mailbox queue consists of a pair of a mailbox message
125structure and a mailbox reply structure. Each slot might contain additional
126fields, such as identification of non-secure task which initiates the PSA Client
127request. Each slot serves a PSA Client call from non-secure task.
128
129The parameters of PSA Client request are hosted in the mailbox message inside
130the slot. `Mailbox messages`_ describes the details of mailbox message.
131
132The mailbox reply structure is used to receive the PSA Client result from SPE.
133`Mailbox replies`_ describes the details of mailbox reply.
134
135Mailbox messages
136----------------
137
138A mailbox message contains the parameters of a PSA Client request from a
139non-secure task. Please refer to the structure definition in
140`Mailbox message structure`_.
141
142Inside PSA Client API implementation, NSPE mailbox selects an empty mailbox
143queue slot for the PSA Client request. The parameters of that PSA Client request
144are organized into the mailbox message belonging to the selected slot.
145SPE mailbox will parse those parameters from the mailbox message.
146
147More fields can be defined in mailbox message to transfer additional information
148from NSPE to SPE for processing in TF-M.
149
150Mailbox replies
151---------------
152
153A mailbox reply structure in non-secure memory receives the PSA Client result
154replied from SPE mailbox. Please refer to the structure definition in
155`Mailbox reply structure`_.
156
157SPE Mailbox queue
158-----------------
159
160SPE mailbox maintains a mailbox queue to store SPE mailbox objects.
161Please refer to the structure definition in `SPE mailbox queue structure`_.
162
163SPE mailbox queue contains one or more slots. The number of slots should be
164aligned with that in NSPE mailbox queue. After SPE is notified that a PSA Client
165request is pending, SPE mailbox can assign an empty slot, copy the corresponding
166PSA Client call parameters from non-secure memory to that slot and parse the
167parameters.
168
169Each slot in SPE mailbox queue can contain the following fields
170
171- An optional field to hold mailbox message content copied from non-secure
172  memory.
173- Index of NSPE mailbox queue slot containing the mailbox message.
174- A handle to the mailbox message. Optional. Identify the owner slot of PSA
175  Client result when multiple mailbox messages are under processing.
176
177More fields can be defined in the slot structure to support mailbox processing
178in SPE.
179
180Overall workflow
181================
182
183The overall workflow of transferring PSA Client requests and results between
184NSPE and SPE via mailbox is shown below.
185
186#. Non-secure task initiates a service request by calling PSA Developer APIs,
187   which eventually invoke PSA Client APIs.
188   PSA Client APIs call NSPE mailbox functions to transmit PSA Client call to
189   SPE.
190
191#. NSPE mailbox assigns an empty slot from NSPE mailbox queue for that PSA
192   client call.
193
194#. NSPE mailbox prepares the parameters of PSA Client call in the dedicated
195   mailbox message inside the assigned slot.
196
197#. After the mailbox message is ready, NSPE mailbox invokes platform specific
198   Inter-Processor Communication driver to notify SPE.
199   The notification mechanism of Inter-Processor Communication is platform
200   specific.
201
202#. After the notification is completed, non-secure task waits for the reply from
203   SPE.
204
205#. Platform specific Inter-Processor Communication interrupt for mailbox is
206   asserted in SPE. The interrupt handler activates SPE mailbox to process the
207   request(s).
208
209#. During mailbox processing in TF-M, the handling routine can include the
210   following steps:
211
212    #. SPE mailbox checks and validates NSPE mailbox queue status.
213    #. SPE mailbox fetches PSA Client call parameters from NSPE mailbox queue.
214    #. SPE mailbox parses the parameters.
215    #. SPE mailbox invokes the TF-M RPC APIs to deliver the PSA Client
216       request to TF-M SPM.
217    #. The PSA Client call is handled in TF-M SPM and target Secure Partition if
218       necessary.
219
220   If multiple ongoing mailbox messages are pending in the SPE, SPE mailbox can
221   process mailbox messages one by one.
222
223#. After the PSA Client call is completed, TF-M RPC layer notifies SPE mailbox
224   to reply PSA Client result to NSPE.
225
226#. SPE mailbox writes the PSA Client result to the dedicated mailbox reply
227   structure in non-secure memory. The related SPE mailbox objects should be
228   invalidated or cleaned.
229
230#. SPE mailbox notifies NSPE by invoking Inter-Processor Communication driver to
231   send a notification to NSPE.
232   The notification mechanism of Inter-Processor Communication is platform
233   specific.
234
235#. NSPE mailbox is activated to handle the PSA Client result in the mailbox
236   reply structure. Related mailbox objects should be invalidated or cleaned by
237   NSPE mailbox after the return results is extracted out.
238
239#. NSPE mailbox returns the result to PSA Client API implementation.
240   The result is eventually returned to the non-secure task.
241
242The following sections discuss more details of key steps in above sequence.
243
244Mailbox notifications between NSPE and SPE
245==========================================
246
247As shown in `Overall workflow`_, NSPE mailbox asserts mailbox notification to
248trigger SPE to handle PSA Client request. SPE mailbox asserts mailbox
249notification to notify NSPE that PSA Client result is written. The notification
250implementation is based on platform specific Inter-Processor Communication.
251
252It is recommended to assign one independent set of Inter-Processor Communication
253channel to each notification routine respectively, to implement a *full-duplex*
254notification mechanism between NSPE and SPE.
255If both notification routines share the same Inter-Processor Communication
256channel, proper synchronization should be implemented to prevent conflicts
257between two notification routines.
258
259In SPE, the Inter-Processor Communication interrupt handler should deal with the
260incoming notification from NSPE and activate the subsequent mailbox handling in
261SPE. Communication prototype design [1]_ defines the behavior of Inter-Processor
262Communication interrupt handler.
263
264NSPE can implement an interrupt handler or a polling of notification status to
265handle Inter-Processor Communication notification from SPE.
266
267Implement PSA Client API with NSPE Mailbox
268==========================================
269
270PSA Client APIs are implemented with NSPE mailbox API
271``tfm_ns_mailbox_client_call()``.
272
273The pseudo code below shows a reference implementation of
274``psa_framework_version()``.
275
276.. code-block:: c
277
278  uint32_t psa_framework_version(void)
279  {
280      ...
281      int32_t ret;
282
283      ret = tfm_ns_mailbox_client_call(...);
284      if (ret != MAILBOX_SUCCESS) {
285          version = PSA_VERSION_NONE;
286      }
287
288      ...
289  }
290
291``tfm_ns_mailbox_client_call()`` implementation can vary according to usage
292scenario. TF-M reference implementation provides implementations for NS OS and
293NS bare metal environment respectively. Refer to
294`TF-M reference implementation of NSPE mailbox`_ for details.
295
296As PSA Firmware Framework-M (FF-M) requests, a PSA Client API function should be
297blocked until the result is returned. To comply with FF-M, NSPE mailbox requires
298proper mechanism(s) to keep current caller waiting for PSA Client result or an
299empty mailbox queue slot.
300
301.. note::
302
303  ``tfm_ns_mailbox_client_call()`` may trap the current exception in sleep and
304  therefore it must not be called in interrupt service routine.
305
306Refer to `Mailbox APIs and data structures`_ for details of
307``tfm_ns_mailbox_client_call()``.
308
309TF-M reference implementation of NSPE mailbox
310=============================================
311
312TF-M NS interface provides a reference implementation of NS mailbox.
313
314This reference implementation defines several NS mailbox HAL APIs. Please refer
315to `NSPE mailbox HAL APIs`_ for details.
316
317Integration with NSPE
318---------------------
319
320TF-M reference implementation provides several mailbox build flags to control
321the integration with NS software.
322
323  .. _mailbox_os_flag:
324
325  - ``TFM_MULTI_CORE_NS_OS``
326
327    When integrating NS mailbox with NS OS, such as NS RTOS, that flag can be
328    selected to enable NS OS support in NS mailbox, such as thread management
329    to fulfill thread wait and wake-up.
330    Please refer to `NSPE mailbox RTOS abstraction APIs`_ for NS OS support
331    details.
332
333    With NS OS support, multiple outstanding PSA Client calls can be supported
334    in NS mailbox when number of mailbox queue slots configured in
335    ``NUM_MAILBOX_QUEUE_SLOT`` is greater than 1.
336
337   If ``TFM_MULTI_CORE_NS_OS`` is enabled, when a NS client starts a PSA Client
338   call:
339
340    - ``tfm_ns_mailbox_client_call()`` selects an empty NSPE mailbox queue slot
341      to organize received PSA client call parameters into a mailbox message.
342
343    - Then it sends those parameters to SPE mailbox and waits for results from
344      SPE. During waiting for the result, the NS client thread may be switched
345      out by NS OS scheduler.
346
347    - When the result arrives, the NS client thread will be woken up inside
348      NS mailbox interrupt handler.
349
350    - The result is then written back to NS client finally.
351
352    When that flag is disabled, NS mailbox runs as being integrated with NS bare
353    metal environment. NS mailbox simply loops mailbox message status while
354    waiting for results.
355
356  .. _mailbox_os_thread_flag:
357
358  - ``TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD``
359
360    When ``TFM_MULTI_CORE_NS_OS`` is enabled, this flag can be selected to
361    enable another NS mailbox thread model which relies on a NS mailbox
362    dedicated thread.
363
364    - It requires NS OS to create a dedicated thread to perform NS mailbox
365      functionalities. This dedicated thread invokes
366      ``tfm_ns_mailbox_thread_runner()`` to handle PSA Client calls.
367      ``tfm_ns_mailbox_thread_runner()`` constructs mailbox messages and sends
368      them to SPE mailbox.
369
370    - ``tfm_ns_mailbox_client_call()`` sends PSA Client calls to the dedicated
371      mailbox thread. It doesn't directly deal with mailbox messages.
372
373    - It also relies on NS OS to provide thread management and inter-thread
374      communication. Please refer to `NSPE mailbox RTOS abstraction APIs`_ for
375      details.
376
377    - It also requires dual-cpu platform to implement NS Inter-Processor
378      Communication interrupts. The interrupt handler invokes
379      ``tfm_ns_mailbox_wake_reply_owner_isr()`` to deal with PSA Client call
380      replies and notify the waiting threads.
381
382Multiple outstanding PSA Client call feature
383--------------------------------------------
384
385Multiple outstanding PSA Client call feature can enable dual-cpu platform to
386issue multiple PSA Client calls in NS OS and those PSA Client calls can be
387served simultaneously.
388
389Without this feature, only a single PSA Client call can be issued and served.
390A new PSA Client call cannot be started until the previous one is completed.
391
392When multiple outstanding PSA Client call feature is enabled, while a NS
393application is waiting for its PSA Client result, another NS application can be
394switched in by NS OS to prepare another PSA Client call or deal with its PSA
395client result. It can decrease the CPU idle time of waiting for PSA Client call
396completion.
397
398If multiple NS applications request secure services in NS OS, it is recommended
399to enable this feature.
400
401To implement this feature in NS OS:
402
403  - Platform should set the number of mailbox queue slots in
404    ``NUM_MAILBOX_QUEUE_SLOT`` in platform's ``config.cmake``.
405    It will use more data area with multiple mailbox queue slots.
406
407    NSPE and SPE share the same ``NUM_MAILBOX_QUEUE_SLOT`` value.
408
409  - Enable ``TFM_MULTI_CORE_NS_OS``
410
411    For more details, refer to
412    :ref:`TFM_MULTI_CORE_NS_OS<mailbox_os_flag>`.
413
414    ``TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD`` can be enabled to select another NS
415    mailbox working model.
416    See :ref:`TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD<mailbox_os_thread_flag>` for
417    details.
418
419Critical section protection between cores
420=========================================
421
422Proper protection should be implemented to protect the critical accesses to
423shared mailbox resources. The critical sections can include atomic reading and
424modifying NSPE mailbox queue status, slot status and other critical operations.
425
426The implementation should protect a critical access to those shared mailbox
427resource from corruptions caused by accesses from the peer core. SPE mailbox
428also accesses NSPE mailbox queue. Therefore, it is essential to implement
429synchronization or protection on NSPE mailbox queue between Secure core and
430Non-secure core. NSPE mailbox and SPE mailbox define corresponding critical
431section protection APIs respectively. The implementation of those APIs can be
432platform specific. Please see more details in `NSPE mailbox APIs`_ and
433`SPE mailbox APIs`_.
434
435It is recommended to rely on both hardware and software to implement the
436synchronization and protection.
437
438Protection of local mailbox objects can be implemented as static functions
439inside NSPE mailbox and SPE mailbox.
440
441Mailbox handling in TF-M
442========================
443
444According to communication prototype design [1]_, mailbox implementation should
445invoke ``tfm_rpc_register_ops()`` to hook its operations to TF-M RPC module
446callbacks during initialization. Mailbox message handling should call TF-M RPC
447PSA Client call handlers to deliver PSA Client request to TF-M SPM.
448
449If multiple outstanding NS PSA Client calls should be supported, TF-M SPM can
450store the mailbox message handle in a specific field in PSA message structure to
451identify the mailbox message, while creating a PSA message. While replying the
452PSA Client result, TF-M SPM can extract the mailbox message handle from PSA
453message and pass it back to mailbox reply function. SPE mailbox can identify
454which mailbox message is completed according to the handle and write the result
455to corresponding NSPE mailbox queue slot.
456
457Platform specific Inter-Processor Communication interrupt handler in SPE should
458call ``spm_handle_interrupt()`` to notify SPM of the interrupt. SPM will then
459send the ``MAILBOX_INTERRUPT_SIGNAL`` signal to the ``ns_agent_mailbox`` partition, which
460will call ``tfm_rpc_client_call_handler()``.
461
462**********************
463Mailbox initialization
464**********************
465
466It should be guaranteed that NSPE mailbox should not initiate PSA Client request
467until SPE mailbox initialization completes.
468Refer to dual-core booting sequence [2]_ for more details on the synchronization
469between NSPE and SPE during booting.
470
471In current design, the base address of NSPE mailbox queue should be pre-defined
472and shared between NSPE mailbox and SPE mailbox.
473
474SPE mailbox initialization
475==========================
476
477The SPE mailbox queue memory should be allocated before calling
478``tfm_mailbox_init()``. ``tfm_mailbox_init()`` initializes the memory and
479variables.
480``tfm_mailbox_init()`` calls ``tfm_mailbox_hal_init()`` to perform platform
481specific initialization. The base address of NSPE mailbox queue can be
482received via ``tfm_mailbox_hal_init()``.
483
484SPE mailbox dedicated Inter-Processor Communication initialization can also be
485enabled during SPE mailbox initialization.
486
487After SPE mailbox initialization completes, SPE notifies NSPE that SPE mailbox
488functionalities are ready.
489
490NSPE mailbox initialization
491===========================
492
493The NSPE mailbox queue memory should be allocated before calling
494``tfm_ns_mailbox_init()``. ``tfm_ns_mailbox_init()`` initializes the memory and
495variables.
496``tfm_ns_mailbox_init()`` calls ``tfm_ns_mailbox_hal_init()`` to perform
497platform specific initialization. The base address of NSPE mailbox queue can be
498passed to SPE mailbox via ``tfm_ns_mailbox_hal_init()``.
499
500NSPE mailbox dedicated Inter-Processor Communication initialization can also be
501enabled during NSPE mailbox initialization.
502
503********************************
504Mailbox APIs and data structures
505********************************
506
507Data types
508==========
509
510Constants
511---------
512
513``MAILBOX_SUCCESS``
514^^^^^^^^^^^^^^^^^^^
515
516``MAILBOX_SUCCESS`` is a generic return value to indicate success of mailbox
517operation.
518
519.. code-block:: c
520
521  #define MAILBOX_SUCCESS        (0)
522
523``MAILBOX_QUEUE_FULL``
524^^^^^^^^^^^^^^^^^^^^^^
525
526``MAILBOX_QUEUE_FULL`` is a return value from mailbox function if mailbox queue
527is full.
528
529.. code-block:: c
530
531  #define MAILBOX_QUEUE_FULL     (INT32_MIN + 1)
532
533``MAILBOX_INVAL_PARAMS``
534^^^^^^^^^^^^^^^^^^^^^^^^
535
536``MAILBOX_INVAL_PARAMS`` is a return value from mailbox function if any
537parameter is invalid.
538
539.. code-block:: c
540
541  #define MAILBOX_INVAL_PARAMS   (INT32_MIN + 2)
542
543``MAILBOX_NO_PERMS``
544^^^^^^^^^^^^^^^^^^^^
545
546``MAILBOX_NO_PERMS`` is a return value from mailbox function if the caller
547doesn't own a proper permission to execute the operation.
548
549.. code-block:: c
550
551  #define MAILBOX_NO_PERMS       (INT32_MIN + 3)
552
553``MAILBOX_NO_PEND_EVENT``
554^^^^^^^^^^^^^^^^^^^^^^^^^
555
556``MAILBOX_NO_PEND_EVENT`` is a return value from mailbox function if the
557expected event doesn't occur yet.
558
559.. code-block:: c
560
561  #define MAILBOX_NO_PEND_EVENT  (INT32_MIN + 4)
562
563``MAILBOX_CHAN_BUSY``
564^^^^^^^^^^^^^^^^^^^^^
565
566``MAILBOX_CHAN_BUSY`` is a return value from mailbox function if the underlying
567Inter-Processor Communication resource is busy.
568
569.. code-block:: c
570
571  #define MAILBOX_CHAN_BUSY      (INT32_MIN + 5)
572
573``MAILBOX_CALLBACK_REG_ERROR``
574^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
575
576``MAILBOX_CALLBACK_REG_ERROR`` is a return value from mailbox function if the
577registration of mailbox callback functions failed.
578
579.. code-block:: c
580
581  #define MAILBOX_CALLBACK_REG_ERROR     (INT32_MIN + 6)
582
583``MAILBOX_INIT_ERROR``
584^^^^^^^^^^^^^^^^^^^^^^
585
586``MAILBOX_INIT_ERROR`` is a return value from mailbox function if the mailbox
587initialization failed.
588
589.. code-block:: c
590
591  #define MAILBOX_INIT_ERROR     (INT32_MIN + 7)
592
593``MAILBOX_GENERIC_ERROR``
594^^^^^^^^^^^^^^^^^^^^^^^^^
595
596``MAILBOX_GENERIC_ERROR`` indicates mailbox generic errors which cannot be
597indicated by the codes above.
598
599.. code-block:: c
600
601  #define MAILBOX_GENERIC_ERROR    (INT32_MIN + 8)
602
603PSA Client API types
604^^^^^^^^^^^^^^^^^^^^
605
606The following constants define the PSA Client API type values shared between
607NSPE and SPE
608
609.. code-block:: c
610
611  #define MAILBOX_PSA_FRAMEWORK_VERSION       (0x1)
612  #define MAILBOX_PSA_VERSION                 (0x2)
613  #define MAILBOX_PSA_CONNECT                 (0x3)
614  #define MAILBOX_PSA_CALL                    (0x4)
615  #define MAILBOX_PSA_CLOSE                   (0x5)
616
617Mailbox message structure
618-------------------------
619
620``psa_client_params_t`` lists the parameters passed from NSPE to SPE required by
621a PSA Client call.
622
623.. code-block:: c
624
625  struct psa_client_params_t {
626      union {
627          struct {
628              uint32_t        sid;
629          } psa_version_params;
630
631          struct {
632              uint32_t        sid;
633              uint32_t        minor_version;
634          } psa_connect_params;
635
636          struct {
637              psa_handle_t    handle;
638              int32_t         type;
639              const psa_invec *in_vec;
640              size_t          in_len;
641              psa_outvec      *out_vec;
642              size_t          out_len;
643          } psa_call_params;
644
645          struct {
646              psa_handle_t    handle;
647          } psa_close_params;
648      };
649  };
650
651The following structure describe a mailbox message and its members.
652
653- ``call_type`` indicates the PSA Client API type.
654- ``params`` stores the PSA Client call parameters.
655- ``client_id`` records the client ID of the non-secure client. Optional.
656  It is used to identify the non-secure tasks in TF-M when NSPE OS enforces
657  non-secure task isolation.
658
659.. code-block:: c
660
661  struct mailbox_msg_t {
662      uint32_t                     call_type;
663      struct psa_client_params_t   params;
664
665      int32_t                      client_id;
666  };
667
668Mailbox reply structure
669-----------------------
670
671This structure describes a mailbox reply structure, which is managed by NSPE
672mailbox in non-secure memory.
673
674.. code-block:: c
675
676  struct mailbox_reply_t {
677      int32_t    return_val;
678      const void *owner;
679      int32_t    *reply;
680      uint8_t    *woken_flag;
681  };
682
683Mailbox queue status bitmask
684----------------------------
685
686``mailbox_queue_status_t`` defines a bitmask to indicate a status of slots in
687mailbox queues.
688
689.. code-block:: c
690
691  typedef uint32_t   mailbox_queue_status_t;
692
693NSPE mailbox queue structure
694----------------------------
695
696``ns_mailbox_slot_t`` defines a non-secure mailbox queue slot.
697
698.. code-block:: c
699
700  /* A single slot structure in NSPE mailbox queue */
701  struct ns_mailbox_slot_t {
702      struct mailbox_msg_t   msg;
703      struct mailbox_reply_t reply;
704  };
705
706``ns_mailbox_queue_t`` describes the NSPE mailbox queue and its members in
707non-secure memory.
708
709- ``empty_slots`` is the bitmask of empty slots.
710- ``pend_slots`` is the bitmask of slots whose PSA Client call is not replied
711  yet.
712- ``replied_slots`` is the bitmask of slots whose PSA Client result is returned
713  but not extracted yet.
714- ``queue`` is the NSPE mailbox queue of slots.
715- ``is_full`` indicates whether NS mailbox queue is full.
716
717.. code-block:: c
718
719  struct ns_mailbox_queue_t {
720      mailbox_queue_status_t   empty_slots;
721      mailbox_queue_status_t   pend_slots;
722      mailbox_queue_status_t   replied_slots;
723
724      struct ns_mailbox_slot_t queue[NUM_MAILBOX_QUEUE_SLOT];
725
726      bool                     is_full;
727  };
728
729SPE mailbox queue structure
730---------------------------
731
732``secure_mailbox_slot_t`` defines a single slot structure in SPE mailbox queue.
733
734- ``ns_slot_idx`` records the index of NSPE mailbox slot containing the mailbox
735  message under processing. SPE mailbox determines the reply structure address
736  according to this index.
737- ``msg_handle`` contains the handle to the mailbox message under processing.
738  The handle can be delivered to TF-M SPM while creating PSA message to identify
739  the mailbox message.
740
741.. code-block:: c
742
743  /* A handle to a mailbox message in use */
744  typedef int32_t    mailbox_msg_handle_t;
745
746  struct secure_mailbox_slot_t {
747      uint8_t              ns_slot_idx;
748      mailbox_msg_handle_t msg_handle;
749  };
750
751``secure_mailbox_queue_t`` describes the SPE mailbox queue in secure memory.
752
753- ``empty_slots`` is the bitmask of empty slots.
754- ``queue`` is the SPE mailbox queue of slots.
755- ``ns_queue`` stores the address of NSPE mailbox queue structure.
756
757.. code-block:: c
758
759  struct secure_mailbox_queue_t {
760      mailbox_queue_status_t       empty_slots;
761
762      struct secure_mailbox_slot_t queue[NUM_MAILBOX_QUEUE_SLOT];
763      /* Base address of NSPE mailbox queue in non-secure memory */
764      struct ns_mailbox_queue_t    *ns_queue;
765  };
766
767NSPE mailbox APIs
768=================
769
770NSPE mailbox interface APIs
771---------------------------
772
773APIs defined in this section are called by NS software and PSA Client APIs
774implementations.
775
776``tfm_ns_mailbox_init()``
777^^^^^^^^^^^^^^^^^^^^^^^^^
778
779This function initializes NSPE mailbox.
780
781.. code-block:: c
782
783  int32_t tfm_ns_mailbox_init(struct ns_mailbox_queue_t *queue);
784
785**Parameters**
786
787+-----------+-----------------------------------------+
788| ``queue`` | The base address of NSPE mailbox queue. |
789+-----------+-----------------------------------------+
790
791**Return**
792
793+---------------------+------------------------------------------+
794| ``MAILBOX_SUCCESS`` | Initialization succeeds.                 |
795+---------------------+------------------------------------------+
796| Other return codes  | Initialization fails with an error code. |
797+---------------------+------------------------------------------+
798
799**Usage**
800
801``tfm_ns_mailbox_init()`` invokes ``tfm_ns_mailbox_hal_init()`` to complete
802platform specific mailbox and Inter-Processor Communication initialization.
803The non-secure memory area for NSPE mailbox queue structure should be statically
804or dynamically pre-allocated before calling ``tfm_ns_mailbox_init()``.
805
806``tfm_ns_mailbox_client_call()``
807^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
808
809This function sends the PSA Client request to SPE, waits and fetches PSA Client
810result.
811
812.. code-block:: c
813
814  int32_t tfm_ns_mailbox_client_call(uint32_t call_type,
815                                     const struct psa_client_params_t *params,
816                                     int32_t client_id,
817                                     int32_t *reply);
818
819**Parameters**
820
821+---------------+--------------------------------------------------+
822| ``call_type`` | Type of PSA Client call                          |
823+---------------+--------------------------------------------------+
824| ``params``    | Address of PSA Client call parameters structure. |
825+---------------+--------------------------------------------------+
826| ``client_id`` | ID of non-secure task.                           |
827+---------------+--------------------------------------------------+
828| ``reply``     | The NS client task private buffer written with   |
829|               | PSA Client result                                |
830+---------------+--------------------------------------------------+
831
832**Return**
833
834+---------------------+--------------------------------------------+
835| ``MAILBOX_SUCCESS`` | PSA Client call is completed successfully. |
836+---------------------+--------------------------------------------+
837| Other return code   | Operation failed with an error code.       |
838+---------------------+--------------------------------------------+
839
840**Usage**
841
842If ``TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD`` is enabled,
843``tfm_ns_mailbox_client_call()`` will forward PSA Client calls to the dedicated
844mailbox thread via NS OS message queue.
845Otherwise, ``tfm_ns_mailbox_client_call()`` directly deals with PSA Client calls
846and perform NS mailbox functionalities.
847
848``tfm_ns_mailbox_thread_runner()``
849^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
850
851This function handles PSA Client call inside a dedicated NS mailbox thread.
852It constructs mailbox messages and transmits them to SPE mailbox.
853
854.. code-block:: c
855
856  void tfm_ns_mailbox_thread_runner(void *args);
857
858**Parameters**
859
860+----------+-------------------------------------------------------------+
861| ``args`` | The pointer to the structure of PSA Client call parameters. |
862+----------+-------------------------------------------------------------+
863
864**Usage**
865
866``tfm_ns_mailbox_thread_runner()`` should be executed inside the dedicated
867mailbox thread.
868
869.. note::
870
871  ``tfm_ns_mailbox_thread_runner()`` is implemented as an empty function when
872  ``TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD`` is disabled.
873
874``tfm_ns_mailbox_wake_reply_owner_isr()``
875^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
876
877This function wakes up the owner task(s) of the returned PSA Client result(s).
878
879.. code-block:: c
880
881  int32_t tfm_ns_mailbox_wake_reply_owner_isr(void);
882
883**Return**
884
885+---------------------------+--------------------------------------------+
886| ``MAILBOX_SUCCESS``       | The tasks of replied mailbox messages were |
887|                           | found and wake-up signals were sent.       |
888+---------------------------+--------------------------------------------+
889| ``MAILBOX_NO_PEND_EVENT`` | No replied mailbox message is found.       |
890+---------------------------+--------------------------------------------+
891| Other return codes        | Operation failed with an error code        |
892+---------------------------+--------------------------------------------+
893
894**Usage**
895
896``tfm_ns_mailbox_wake_reply_owner_isr()`` should be called from platform
897specific Inter-Processor Communication interrupt handler.
898
899.. note::
900
901  ``tfm_ns_mailbox_wake_reply_owner_isr()`` is implemented as a dummy function
902  when ``TFM_MULTI_CORE_NS_OS`` is disabled.
903
904NSPE mailbox HAL APIs
905---------------------
906
907The HAL APIs defined in this section should be implemented by platform-specific
908implementation.
909
910This section describes a *reference design* of NSPE mailbox HAL APIs. Developers
911can define and implement different APIs.
912
913``tfm_ns_mailbox_hal_init()``
914^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
915
916This function executes platform-specific NSPE mailbox initialization.
917
918.. code-block:: c
919
920  int32_t tfm_ns_mailbox_hal_init(struct ns_mailbox_queue_t *queue);
921
922**Parameters**
923
924+-----------+-----------------------------------------+
925| ``queue`` | The base address of NSPE mailbox queue. |
926+-----------+-----------------------------------------+
927
928**Return**
929
930+---------------------+------------------------------------------+
931| ``MAILBOX_SUCCESS`` | Initialization succeeds.                 |
932+---------------------+------------------------------------------+
933| Other return codes  | Initialization fails with an error code. |
934+---------------------+------------------------------------------+
935
936**Usage**
937
938``tfm_ns_mailbox_hal_init()`` performs platform specific mailbox and
939Inter-Processor Communication initialization. ``tfm_ns_mailbox_hal_init()`` can
940also share the address of NSPE mailbox queue with SPE mailbox via platform
941specific implementation.
942
943``tfm_ns_mailbox_hal_notify_peer()``
944^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
945
946This function invokes platform specific Inter-Processor Communication drivers to
947send notification to SPE.
948
949.. code-block:: c
950
951  int32_t tfm_ns_mailbox_hal_notify_peer(void);
952
953**Return**
954
955+---------------------+---------------------------------------+
956| ``MAILBOX_SUCCESS`` | The operation completes successfully. |
957+---------------------+---------------------------------------+
958| Other return codes  | Operation fails with an error code.   |
959+---------------------+---------------------------------------+
960
961**Usage**
962
963``tfm_ns_mailbox_hal_notify_peer()`` should be implemented by platform specific
964Inter-Processor Communication drivers.
965
966``tfm_ns_mailbox_hal_notify_peer()`` should not be exported outside NSPE
967mailbox.
968
969``tfm_ns_mailbox_hal_enter_critical()``
970^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
971
972This function enters the critical section of NSPE mailbox queue access.
973
974.. code-block:: c
975
976  void tfm_ns_mailbox_hal_enter_critical(void);
977
978**Usage**
979
980NSPE mailbox invokes ``tfm_ns_mailbox_hal_enter_critical()`` before entering
981critical section of NSPE mailbox queue.
982``tfm_ns_mailbox_hal_enter_critical()`` implementation is platform specific.
983
984``tfm_ns_mailbox_hal_enter_critical()`` should not be called in any interrupt
985service routine. Use only to lock data that are shared with secure side.
986
987``tfm_ns_mailbox_hal_exit_critical()``
988^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
989
990This function exits the critical section of NSPE mailbox queue access.
991
992.. code-block:: c
993
994  void tfm_ns_mailbox_hal_exit_critical(void);
995
996**Usage**
997
998NSPE mailbox invokes ``tfm_ns_mailbox_hal_exit_critical()`` after exiting
999critical section of NSPE mailbox queue.
1000``tfm_ns_mailbox_hal_exit_critical()`` implementation is platform specific.
1001
1002``tfm_ns_mailbox_hal_exit_critical()`` should not be called in any interrupt
1003service routine.
1004
1005``tfm_ns_mailbox_hal_enter_critical_isr()``
1006^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1007
1008This function enters the critical section of NSPE mailbox queue access in an
1009IRQ handler.
1010
1011.. code-block:: c
1012
1013  void tfm_ns_mailbox_hal_enter_critical(void);
1014
1015**Usage**
1016
1017NSPE mailbox invokes ``tfm_ns_mailbox_hal_enter_critical_isr()`` before entering
1018critical section of NSPE mailbox queue in an IRQ handler.
1019``tfm_ns_mailbox_hal_enter_critical_isr()`` implementation is platform specific.
1020Use only to lock data that are shared with secure side.
1021
1022``tfm_ns_mailbox_hal_exit_critical_isr()``
1023^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1024
1025This function exits the critical section of NSPE mailbox queue access in an IRQ
1026handler
1027
1028.. code-block:: c
1029
1030  void tfm_ns_mailbox_hal_exit_critical_isr(void);
1031
1032**Usage**
1033
1034NSPE mailbox invokes ``tfm_ns_mailbox_hal_exit_critical_isr()`` after exiting
1035critical section of NSPE mailbox queue in an IRQ handler.
1036``tfm_ns_mailbox_hal_exit_critical_isr()`` implementation is platform specific.
1037
1038NSPE mailbox RTOS abstraction APIs
1039----------------------------------
1040
1041The APIs defined in this section should be implemented by RTOS-specific
1042implementation when ``TFM_MULTI_CORE_NS_OS`` is enabled.
1043
1044.. note::
1045
1046  If ``TFM_MULTI_CORE_NS_OS`` is set to ``OFF``, the following APIs are defined
1047  as dummy functions or empty functions.
1048
1049``tfm_ns_mailbox_os_lock_init()``
1050^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1051
1052This function initializes the multi-core lock for synchronizing PSA client
1053call(s). The actual implementation depends on the non-secure use scenario.
1054
1055.. code-block:: c
1056
1057  int32_t tfm_ns_mailbox_os_lock_init(void);
1058
1059**Return**
1060
1061+---------------------------+---------------------------+
1062| ``MAILBOX_SUCCESS``       | Initialization succeeded. |
1063+---------------------------+---------------------------+
1064| ``MAILBOX_GENERIC_ERROR`` | Initialization failed.    |
1065+---------------------------+---------------------------+
1066
1067**Usage**
1068
1069``tfm_ns_mailbox_init()`` invokes this function to initialize the lock.
1070If ``TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD`` is enabled,
1071``tfm_ns_mailbox_os_lock_init()`` is defined as a dummy one.
1072
1073``tfm_ns_mailbox_os_lock_acquire()``
1074^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1075
1076This function acquires the multi-core lock for synchronizing PSA client call(s).
1077The actual implementation depends on the non-secure use scenario.
1078
1079.. code-block:: c
1080
1081  int32_t tfm_ns_mailbox_os_lock_acquire(void);
1082
1083**Return**
1084
1085+---------------------------+--------------------------------+
1086| ``MAILBOX_SUCCESS``       | Succeeded to acquire the lock. |
1087+---------------------------+--------------------------------+
1088| ``MAILBOX_GENERIC_ERROR`` | Failed to acquire the lock.    |
1089+---------------------------+--------------------------------+
1090
1091**Usage**
1092
1093``tfm_ns_mailbox_client_call()`` invokes this function to acquire the lock when
1094``TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD`` is disabled
1095If ``TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD`` is enabled,
1096``tfm_ns_mailbox_os_lock_acquire()`` is defined as a dummy one.
1097
1098``tfm_ns_mailbox_os_lock_release()``
1099^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1100
1101This function releases the multi-core lock for synchronizing PSA client call(s).
1102The actual implementation depends on the non-secure use scenario.
1103
1104.. code-block:: c
1105
1106  int32_t tfm_ns_mailbox_os_lock_release(void);
1107
1108**Return**
1109
1110+---------------------------+--------------------------------+
1111| ``MAILBOX_SUCCESS``       | Succeeded to release the lock. |
1112+---------------------------+--------------------------------+
1113| ``MAILBOX_GENERIC_ERROR`` | Failed to release the lock.    |
1114+---------------------------+--------------------------------+
1115
1116**Usage**
1117
1118``tfm_ns_mailbox_client_call()`` invokes this function to release the lock when
1119``TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD`` is disabled
1120If ``TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD`` is enabled,
1121``tfm_ns_mailbox_os_lock_release()`` is defined as a dummy one.
1122
1123``tfm_ns_mailbox_os_get_task_handle()``
1124^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1125
1126This function gets the handle of the current non-secure task executing mailbox
1127functionalities.
1128
1129.. code-block:: c
1130
1131  void *tfm_ns_mailbox_os_get_task_handle(void);
1132
1133**Return**
1134
1135+-------------+-----------------------------------------------------------+
1136| Task handle | The non-secure task handle waiting for PSA Client result. |
1137+-------------+-----------------------------------------------------------+
1138
1139``tfm_ns_mailbox_os_wait_reply()``
1140^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1141
1142This function performs use scenario and NS OS specific waiting mechanism to wait
1143for the reply of the specified mailbox message to be returned from SPE.
1144
1145.. code-block:: c
1146
1147  void tfm_ns_mailbox_os_wait_reply(void);
1148
1149**Usage**
1150
1151The PSA Client API implementations call ``tfm_ns_mailbox_os_wait_reply()`` to
1152fall into sleep to wait for PSA Client result.
1153
1154``tfm_ns_mailbox_os_wake_task_isr()``
1155^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1156
1157This function wakes up the dedicated task which is waiting for PSA Client
1158result, via RTOS-specific wake-up mechanism.
1159
1160.. code-block:: c
1161
1162  void tfm_ns_mailbox_hal_wait_reply(const void *task_handle);
1163
1164**Parameters**
1165
1166+-----------------+----------------------------------------+
1167| ``task_handle`` | The handle to the task to be woken up. |
1168+-----------------+----------------------------------------+
1169
1170``tfm_ns_mailbox_os_mq_create()``
1171^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1172
1173This function creates and initializes a NS OS message queue.
1174
1175.. code-block:: c
1176
1177  void *tfm_ns_mailbox_os_mq_create(ize_t msg_size, uint8_t msg_count);
1178
1179**Parameters**
1180
1181+---------------+------------------------------------------+
1182| ``msg_size``  | The maximum message size in bytes.       |
1183+---------------+------------------------------------------+
1184| ``msg_count`` | The maximum number of messages in queue. |
1185+---------------+------------------------------------------+
1186
1187**Return**
1188
1189+----------------------+-----------------------------------------------------+
1190| message queue handle | The handle of the message queue created, or NULL in |
1191|                      | case of error.                                      |
1192+----------------------+-----------------------------------------------------+
1193
1194**Usage**
1195
1196If ``TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD`` is disabled,
1197``tfm_ns_mailbox_os_mq_create()`` is defined as a dummy one.
1198
1199``tfm_ns_mailbox_os_mq_send()``
1200^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1201
1202This function sends PSA Client call request via NS OS message queue.
1203
1204.. code-block:: c
1205
1206  int32_t tfm_ns_mailbox_os_mq_send(void *mq_handle,
1207                                    const void *msg_ptr);
1208
1209**Parameters**
1210
1211+---------------+----------------------------------------+
1212| ``mq_handle`` | The handle of message queue.           |
1213+---------------+----------------------------------------+
1214| ``msg_ptr``   | The pointer to the message to be sent. |
1215+---------------+----------------------------------------+
1216
1217**Return**
1218
1219+---------------------+-------------------------------------+
1220| ``MAILBOX_SUCCESS`` | The message is successfully sent.   |
1221+---------------------+-------------------------------------+
1222| Other return code   | Operation fails with an error code. |
1223+---------------------+-------------------------------------+
1224
1225**Usage**
1226
1227If ``TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD`` is disabled,
1228``tfm_ns_mailbox_os_mq_send()`` is defined as a dummy one.
1229
1230``tfm_ns_mailbox_os_mq_receive()``
1231^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1232
1233This function receives PSA Client call requests via NS OS message queue.
1234
1235.. code-block:: c
1236
1237  int32_t tfm_ns_mailbox_os_mq_receive(void *mq_handle,
1238                                       void *msg_ptr);
1239
1240**Parameters**
1241
1242+---------------+---------------------------------------------------+
1243| ``mq_handle`` | The handle of message queue.                      |
1244+---------------+---------------------------------------------------+
1245| ``msg_ptr``   | The pointer to buffer for message to be received. |
1246+---------------+---------------------------------------------------+
1247
1248**Return**
1249
1250+---------------------+-------------------------------------+
1251| ``MAILBOX_SUCCESS`` | A message is successfully received. |
1252+---------------------+-------------------------------------+
1253| Other return code   | Operation fails with an error code. |
1254+---------------------+-------------------------------------+
1255
1256**Usage**
1257
1258The buffer size must be large enough to contain the request whose size is set
1259in ``msg_size `` in ``tfm_ns_mailbox_os_mq_create()``.
1260
1261If ``TFM_MULTI_CORE_NS_OS_MAILBOX_THREAD`` is disabled,
1262``tfm_ns_mailbox_os_mq_receive()`` is defined as a dummy one.
1263
1264.. note::
1265
1266  The function caller should be blocked until a PSA Client call request is
1267  received from message queue, unless a fatal error occurs.
1268
1269SPE mailbox APIs
1270================
1271
1272SPE mailbox interface APIs
1273--------------------------
1274
1275The APIs defined in this section are called in TF-M routines and platform
1276specific secure interrupt handler.
1277
1278``tfm_mailbox_handle_msg()``
1279^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1280
1281This function completes the handling of mailbox messages from NSPE.
1282
1283.. code-block:: c
1284
1285  int32_t tfm_mailbox_handle_msg(void);
1286
1287**Return**
1288
1289+---------------------+---------------------------------------+
1290| ``MAILBOX_SUCCESS`` | The operation completes successfully. |
1291+---------------------+---------------------------------------+
1292| Other return codes  | Operation fails with an error code.   |
1293+---------------------+---------------------------------------+
1294
1295**Usage**
1296
1297``tfm_mailbox_handle_msg()`` is registered to RPC callback function
1298``handle_req``.
1299
1300``tfm_mailbox_handle_msg()`` executes the following tasks:
1301
1302- Check NSPE mailbox queue status.
1303- Copy mailbox message(s) from NSPE. Optional.
1304- Checks and validations if necessary
1305- Parse mailbox message
1306- Call TF-M RPC APIs to pass PSA Client request to TF-M SPM.
1307
1308``tfm_mailbox_reply_msg()``
1309^^^^^^^^^^^^^^^^^^^^^^^^^^^
1310
1311This function replies the PSA Client result to NSPE.
1312
1313.. code-block:: c
1314
1315  int32_t tfm_mailbox_reply_msg(mailbox_msg_handle_t handle, int32_t reply);
1316
1317**Parameters**
1318
1319+------------+-----------------------------------------------------------------+
1320| ``handle`` | The handle to mailbox message related to the PSA Client result. |
1321+------------+-----------------------------------------------------------------+
1322| ``reply``  | The PSA Client result value to be replied.                      |
1323+------------+-----------------------------------------------------------------+
1324
1325**Return**
1326
1327+---------------------+---------------------------------------+
1328| ``MAILBOX_SUCCESS`` | The operation completes successfully. |
1329+---------------------+---------------------------------------+
1330| Other return codes  | Operation fails with an error code.   |
1331+---------------------+---------------------------------------+
1332
1333**Usage**
1334
1335``tfm_mailbox_reply_msg()`` is registered to RPC callback ``reply``.
1336It is invoked inside handler of ``psa_reply()`` to return the PSA Client result
1337to NSPE.
1338
1339``handle`` determines which mailbox message in SPE mailbox queue contains the
1340PSA Client call. If ``handle`` is set as ``MAILBOX_MSG_NULL_HANDLE``, the return
1341result is replied to the mailbox message in the first SPE mailbox queue slot.
1342
1343``tfm_mailbox_init()``
1344^^^^^^^^^^^^^^^^^^^^^^
1345
1346This function initializes SPE mailbox.
1347
1348.. code-block:: c
1349
1350  int32_t tfm_mailbox_init(void);
1351
1352**Return**
1353
1354+---------------------+-------------------------------------------+
1355| ``MAILBOX_SUCCESS`` | Initialization succeeds.                  |
1356+---------------------+-------------------------------------------+
1357| Other return codes  | Initialization failed with an error code. |
1358+---------------------+-------------------------------------------+
1359
1360**Usage**
1361
1362``tfm_mailbox_init()`` invokes ``tfm_mailbox_hal_init()`` to execute platform
1363specific initialization.
1364
1365SPE mailbox HAL APIs
1366--------------------
1367
1368``tfm_mailbox_hal_notify_peer()``
1369^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1370
1371This function invokes platform specific Inter-Processor Communication drivers to
1372send notification to NSPE.
1373
1374.. code-block:: c
1375
1376  int32_t tfm_mailbox_hal_notify_peer(void);
1377
1378**Return**
1379
1380+---------------------+---------------------------------------+
1381| ``MAILBOX_SUCCESS`` | The operation completes successfully. |
1382+---------------------+---------------------------------------+
1383| Other return codes  | Operation fails with an error code.   |
1384+---------------------+---------------------------------------+
1385
1386**Usage**
1387
1388``tfm_mailbox_hal_notify_peer()`` should be implemented by platform specific
1389Inter-Processor Communication drivers.
1390
1391``tfm_mailbox_hal_notify_peer()`` should not be exported outside SPE mailbox.
1392
1393
1394``tfm_mailbox_hal_init()``
1395^^^^^^^^^^^^^^^^^^^^^^^^^^
1396
1397This function is implemented by platform support in TF-M. It completes platform
1398specific mailbox initialization, including receiving the the address of NSPE
1399mailbox queue and Inter-Processor Communication initialization.
1400
1401.. code-block:: c
1402
1403  int32_t tfm_mailbox_hal_init(struct secure_mailbox_queue_t *s_queue);
1404
1405**Parameters**
1406
1407+-------------+----------------------------------------+
1408| ``s_queue`` | The base address of SPE mailbox queue. |
1409+-------------+----------------------------------------+
1410
1411**Return**
1412
1413+---------------------+-------------------------------------------+
1414| ``MAILBOX_SUCCESS`` | Initialization succeeds.                  |
1415+---------------------+-------------------------------------------+
1416| Other return codes  | Initialization failed with an error code. |
1417+---------------------+-------------------------------------------+
1418
1419``tfm_mailbox_hal_enter_critical()``
1420^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1421
1422This function enters the critical section of NSPE mailbox queue access in SPE.
1423
1424.. code-block:: c
1425
1426  void tfm_mailbox_hal_enter_critical(void);
1427
1428**Usage**
1429
1430SPE mailbox invokes ``tfm_mailbox_hal_enter_critical()`` before entering
1431critical section of NSPE mailbox queue.
1432``tfm_mailbox_hal_enter_critical()`` implementation is platform specific.
1433
1434``tfm_mailbox_hal_enter_critical()`` can be called in an interrupt service
1435routine.
1436
1437``tfm_mailbox_hal_exit_critical()``
1438^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1439
1440This function exits from the critical section of NSPE mailbox queue access in
1441SPE.
1442
1443.. code-block:: c
1444
1445  void tfm_mailbox_hal_exit_critical(void);
1446
1447**Usage**
1448
1449SPE mailbox invokes ``tfm_mailbox_hal_exit_critical()`` when exiting from
1450critical section of NSPE mailbox queue.
1451``tfm_mailbox_hal_exit_critical()`` implementation is platform specific.
1452
1453``tfm_mailbox_hal_exit_critical()`` can be called in an interrupt service
1454routine.
1455
1456*********
1457Reference
1458*********
1459
1460.. [1] :doc:`Communication prototype between NSPE and SPE in Dual-core systems <./communication_prototype_between_nspe_and_spe_in_dual_core_systems>`
1461
1462.. [2] :doc:`Booting a Dual-core system <booting_a_dual_core_system>`
1463
1464--------------------
1465
1466*Copyright (c) 2019-2024 Arm Limited. All Rights Reserved.*
1467*Copyright (c) 2022 Cypress Semiconductor Corporation. All rights reserved.*
1468