> ## Documentation Index
> Fetch the complete documentation index at: https://dragonwingdocs-staging.qualcomm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Mailbox driver overview

Mailbox provides a driver interface to exchange messages between mailbox clients and RTSS. Messages are stored in designated mailbox regions. The following figure shows exchange of messages between RTSS and APSS through mailbox:<br />

<img src="https://mintlify.s3.us-west-1.amazonaws.com/qualcomm-staging/images/image-6.png" alt="Image" title="Image" className="mx-auto" style={{ width:"64%" }} />

The figure explains the mailbox driver features:

<img src="https://mintlify.s3.us-west-1.amazonaws.com/qualcomm-staging/images/image-7.png" alt="Image" title="Image" className="mx-auto" style={{ width:"88%" }} />

The following are the key components in the mailbox driver:

* [Linux HLOS mailbox server](https://docs.qualcomm.com/doc/80-70033-42/topic/mail-box.html#mailbox-server)
* [RTSS mailbox external driver](https://docs.qualcomm.com/doc/80-70033-42/topic/mail-box.html#mailbox-driver)
* [Mailbox region - DDR](https://docs.qualcomm.com/doc/80-70033-42/topic/mail-box.html#mailbox-ddr)

<img src="https://mintlify.s3.us-west-1.amazonaws.com/qualcomm-staging/images/image-8.png" alt="Image" title="Image" className="mx-auto" style={{ width:"75%" }} />

**Linux HLOS mailbox server**

The Linux HLOS mailbox server (often called the HLOS mailbox resource manager or HLOS mailbox interface) is the user‑space or kernel‑space interface that lets Linux (HLOS) applications exchange messages with RTSS over the DDR region using the mailbox IPC mechanism.

The Linux HLOS mailbox server acts as the HLOS mailbox resource manager and provides device nodes that:

* Map the mailbox hardware (configured by the RTSS mailbox driver) into `/dev/sail/*` channels.
* Offer notification APIs for HLOS applications.
* Allow full duplex, structured IPC between Linux and RTSS/NHLOS over the mailbox IPC mechanism.

Typical usage flow (HLOS side) for a simple mailbox message read/write:

1. Open channel: Application opens Tx and Rx device nodes exposed by the mailbox resource manager.
2. Send: Application writes a structured message to the Tx device node.
3. Receive:
   * Application blocks (or uses poll()/select()) on the Rx device node.
   * Reads messages when notified (async or poll based).
4. Close: Application closes the mailbox handles; resource manager cleans up context.

Source code details:

* `sources/sail-mailbox/sail-mb-umd/include/sail_mailbox.h`
* `sources/sail-mailbox/sail-mb-umd/src/sail_mbox_core.c`, `sail_mbox_lib.c`, `sail_mbox_lib.h`, and `sailmb_internal.c`

**RTSS mailbox external driver**

The mailbox external driver is the mechanism that creates and manages shared-memory channels between RTSS and APSS (HLOS).

* Carves the shared DDR mailbox region into multiple regions such as region 0, region 1, and region 2.
* Treats each region as a channel/subregion identified by a unique channel/subregion IDN.
* Provides the buffering and notification infrastructure for message passing between RTSS and APSS.

This is the RTSS side counterpart to the HLOS mailbox server. The mailbox external driver manages the low-level shared-memory regions and IPC controller, while the HLOS communicates using `/dev/sail/*` nodes.

Message flow and notifications:

1. RTSS and APSS share DDR mailbox regions managed by mailbox external driver (RTSS side) and the corresponding APSS/HLOS drivers.
2. When APSS or RTSS writes data into a region’s circular buffer, that data becomes available to the application.
3. To notify the application that new data is available or that a buffer has been consumed:
   > The mailbox external driver uses an IPCC to generate asynchronous events between APSS and RTSS.
4. On RTSS:

> * These IPC events trigger the mailbox external driver callbacks.
> * Typical RTOS IPC mechanisms are used to wake up or synchronize tasks that consume/produce messages in real time.

Source code details:

* `sail_proc/BSP/mailboxExt/public/mailboxExt_api.h`
* `sail_proc/BSP/mailboxExt/src/mailboxExt_api.c`, `mailboxExt_config.c`

**Mailbox region - DDR**

DDR is an external memory used as shared memory for the mailbox driver to store the messages by Linux HLOS and RTSS.

## **Create a new mailbox channel**

**On RTSS side**

1. Add client ID.
   > 1. Add the new client ID to `xMailboxExtclienttype` in `mailboxExt_api.h`.
   > 2. Place the entry between the QCMI start and end markers:

```text theme={null}
typedef enum
{
  MAILBOX_HLOSPMU = 0,
  MAILBOX_HLOSUSS,
  MAILBOX_HLOSTST,
  MAILBOX_CONSOLE,
  MAILBOX_OTA,
  MAILBOX_TMU,
  MAILBOX_PTP,
  MAILBOX_CAN,
  MAILBOX_POWER,
  MAILBOX_FUSE,
  MAILBOX_STZ,
  /* qcmi resource manager communication client entries goes here ..start*/
  /* qcmi resource manager communication client entries goes here ..end*/
  MAILBOX_SSM,
  MAILBOX_TSM,
  MAILBOX_EBMAX
}xMailboxExtclienttype;
```

2. Add channel IDs.

> a.  Add RTSS Receiver (Rx), Sender (Tx), or both Rx-Tx ID pairs to `mailboxEBChanType_e`          in `mailboxExt_config.h`.
>
> b.  Insert the IDs within the QCMI start and end markers:
>
> > ```text theme={null}
> > typedef enum
> > {
> >         EB_CHAN_PMU_RX_IDN,
> >         EB_CHAN_PMU_TX_IDN,
> >         EB_CHAN_ULS_RX_IDN,
> >         EB_CHAN_ULS_TX_IDN,
> >         EB_CHAN_TST_RX_IDN,
> >         EB_CHAN_TST_TX_IDN,
> >         EB_CHAN_CONSOLE_TX_IDN,
> >         EB_CHAN_OTA_RX_IDN,
> >         EB_CHAN_OTA_TX_IDN,
> >         EB_CHAN_TMU_RX_IDN,
> >         EB_CHAN_TMU_TX_IDN,
> >         EB_CHAN_PTP_RX_IDN,
> >         EB_CHAN_PTP_TX_IDN,
> >         EB_CHAN_CAN_RX_IDN,
> >         EB_CHAN_CAN_TX_IDN,
> >         EB_CHAN_POWER_TX_IDN,
> >         EB_CHAN_FUSE_RX_IDN,
> >         EB_CHAN_FUSE_TX_IDN,
> >         EB_CHAN_STZ_RX_IDN,
> >         EB_CHAN_STZ_TX_IDN,
> >         /* qcmi resource manager communication client chan entries goes here following placeholder entries always be at the end */
> >         EB_CHAN_SSM_RX_IDN,     /* SSM RX */
> >         EB_CHAN_SSM_TX_IDN,     /* SSM TX */
> >         EB_CHAN_TSM_RX_IDN,     /* TSM RX */
> >         EB_CHAN_TSM_TX_IDN,     /* TSM TX */
> >         EB_CHAN_MAX,
> > }mailboxEBChanType_e;
> > ```

3. Update subregion count.

> a. Update `mailboxEB_QCMI_NUMSUBREGION` in `mailboxExt_config.h` to reflect the new            channel:
>
> > ```text theme={null}
> > /* Number of SubRegions in the HLOS general mailbox */
> > #define mailboxEB_QCMI_NUMSUBREGION 20U
> > ```
> >
> > * For an Rx-Tx pair, the number of subregions is 2, so set `mailboxEB_QCMI_NUMSUBREGION` to 22.
> > * For Rx or Tx only, the number of subregions is 1, so set `mailboxEB_QCMI_NUMSUBREGION` to 21.

4. Define a new channel configuration entry.

> a.  Add a new channel configuration entry in the `mailboxEB_DATA` static resource table:
>
> > ```text theme={null}
> > static mbsub_rgn_config_t Mailbox_QCMISubRegionCfg[EB_CHAN_MAX]
> > ```
>
> This entry must follow the updated channel index numbering defined in the `xMailboxExtClientType` enum.
>
> Structure definition of `mbsub_rgn_config_t`:
>
> ```text theme={null}
> typedef struct __attribute__((packed))
> {
> int8    name[MB_NAME_SZ];    // mailbox sub-region name
> uint32  sender;                            // mailbox sender
> uint32  receiver;                         //  mailbox receiver
> uint32  prot;                                 // mailbox protocol
> uint32  sig;                                   // Mailbox signal Tx-Rx (Unique)
> uint32  mode;                             // Mailbox Read Mode (RD) or Write Mode (WR)                           RTSS consider RD =1; WR = 0;
> uint32  prio;                             // channel priority 0: means default Max , 1 : Max -1 , 2: Max-2 so on upto max 65
> uint32  start_addr_offset;         // offset of sub-region startaddress.
> uint32  end_addr_offset;           // offset of sub-region end address.
> uint32  item_max_num;              // Sub-region maximum item number
> uint32  item_max_size;             // Sub-region maximum item size
> } mbsub_rgn_config_t;
> ```
>
> See the `mailboxExt_config.c` file for examples of existing channel configurations.
>
> The `MAILBOX_CONSOLE` entry with index value 3 in the `xMailboxExtClientType` enum is defined as follows:
>
> ```text theme={null}
> mailboxEB_DATA static mbsub_rgn_config_t Mailbox_QCMISubRegionCfg[EB_CHAN_MAX] =
> {
>
>    * Description: sail debug log logger write channel used to send
>      data to MD(HLOS\UEFI)
>      */
>     {
>         "/dev/sail/log",
>           (uint32)IPCC_C_APPS,
>       (uint32)IPCC_C_SAIL0,
>       (uint32)IPCC_P_COMPUTEL1,
>       mailboxEB_CHAN_CONSOLE_TX_IDN_SIGID,
>           MB_CHAN_WR_MODE,
>       mailboxEB_QCMI_PRIORITY,
>       MB_DEFAULT_CHAN_OFFSET,
>       MB_DEFAULT_CHAN_OFFSET,
>       mailboxEB_CHAN_CONSOLE_TX_IDN_NUMITEM,
>       mailboxEB_CHAN_CONSOLE_TX_IDN_ITEMSIZE
>     },
> ```
>
> <Note>
>   **Note**
>
>   * The `name` field should have three characters, with suffix `0` for read and `1` for write channels.
>   * If a single Rx or Tx ID is mapped to the `xMailboxExtClientType` client entry, initialize other channel entries with default values, see `MAILBOX_CONSOLE` example
> </Note>

5. Add entry in `xMailboxClientRec` table.

   a. Update the `mailboxEB_CONST` table:

> > ```text theme={null}
> > const xMailboxEBClientRec_t xMailboxClientRec[MAILBOX_EBMAX]
> > ```
>
> Structure definition of `xMailboxEBClientRec_t`:
>
> > ```text theme={null}
> > typedef struct
> > {
> > xMailboxEBChanRec_t ChanRec[MB_CHAN_MAX_TYP;
> > }xMailboxEBClientRec_t;
> > ```
>
> Structure definition of `xMailboxEBChanRec_t`:
>
> > ```text theme={null}
> > /* chan descr type */
> > typedef struct
> > {
> > mailboxEBIDNType_e MbId;
> > mailboxEBChanType_e ChanId;
> > uint32 MbAddress;
> > uint32 *pDbgCnt;
> > xMailboxExtclienttypeClient;
> > const mbsub_rgn_config_t *pRgnCfg;
> > }xMailboxEBChanRec_t;
> > /* client chan descrtype  */
> > ```
>
> For the `/dev/sail/log` channel, the client with `MAILBOX_CONSOLE` client ID contains the following configuration entries, where only the Tx (write) channel is defined.
>
> > ```text theme={null}
> > {
> >   /* rd chan : NA default init */
> >   (mailboxEBIDNType_e)0xFF,
> >   (mailboxEBChanType_e)0xFF,
> >   0,
> >   NULL,
> >   (xMailboxExtclienttype)0xFF,
> >   NULL,
> >   /* wr chan */
> >   MAILBOX_QCMI_IDN,
> >   EB_CHAN_CONSOLE_TX_IDN,
> >   mailboxEB_QCMI_ADDR,
> >   &ulMailbox_DbgCnt[EB_CHAN_CONSOLE_TX_IDN],
> >   MAILBOX_CONSOLE,
> >   &Mailbox_QCMISubRegionCfg[EB_CHAN_CONSOLE_TX_IDN]
> > },
> > ```

Protocol and channel mapping:

> The following table lists the protocol signals, sender, receiver, and channel support for integrator reference when adding a new channel in the mailboxExt driver.
>
> | **Supported protocol** | **Signals** | **Sender** | **Receiver** | **Channel supported** |
> | :-: | :-: | :-: | :-: | :-: |
> | `IPCC_P_COMPUTEL 1` | 32 | `IPCC_C_APPS` | One of the RTSS cores, for example, `IPCC_C_SAIL0` or `IPCC_C_SAIL1` | 32 |
>
> * Select the protocol, sender, and receiver according to the table.
> * RTSS cores use logical number suffixes appended to macros, for example, IPCC\_C\_SAIL0 for core 0.
> * The sender column indicates the sender client line used by APSS to link with the RTSS domain receiver client. Each sender client provides the number of signals specified in the table based on protocol selection.
>
> Reference:
>
> The `mailbox_test` application is location at `sail_proc\BSP\tests\sailsw1\mailbox_test\src\MBtests_sailsw1.c`.

**On APPS side**

1. Add a new channel entry in the devicetree.
   > 1. Update the devicetree with the new channel configuration:
   >
   > ```text theme={null}
   > sail_mailbox: sail-mailbox@90d80000 {
   >   compatible = "qcom,sail-mailbox";
   >   reg = <0x0 0x01FFE02C 0x0 0x10>,
   >   <0x0 0x01FFD018 0x0 0x10>,
   >   <0x0 0x17C0000C 0x0 0x04>;
   >   mboxes =  <&ipcc_computeL1 IPCC_CLIENT_SAIL0 0x2>,
   >             <&ipcc_computeL1 IPCC_CLIENT_SAIL0 0x3>,
   >             <&ipcc_computeL1 IPCC_CLIENT_SAIL0 0x4>,
   >             <&ipcc_computeL1 IPCC_CLIENT_SAIL0 0x5>,
   >             <&ipcc_computeL1 IPCC_CLIENT_SAIL0 0x6>,
   >             <&ipcc_computeL1 IPCC_CLIENT_SAIL0 0X7>,
   >             <&ipcc_computeL1 IPCC_CLIENT_SAIL2 0X8>,
   >             <&ipcc_computeL1 IPCC_CLIENT_SAIL0 0X9>;
   >             +<&ipcc_computeL1 IPCC_CLIENT_SAIL0 0XA>  //Example new entry for new  channel created at RTSS side
   >   memory-region = <&sail_mailbox_mem>,
   >                   <&sail_ota_mem>;
   >                 interrupt-parent=<&ipcc_computeL1>;
   >   interrupts =  <IPCC_CLIENT_SAIL0 0x2 IRQ_TYPE_EDGE_RISING>,
   >                 <IPCC_CLIENT_SAIL0 0x3 IRQ_TYPE_EDGE_RISING>,
   >                 <IPCC_CLIENT_SAIL0 0x4 IRQ_TYPE_EDGE_RISING>,
   >                 <IPCC_CLIENT_SAIL0 0x5 IRQ_TYPE_EDGE_RISING>,
   >                 <IPCC_CLIENT_SAIL0 0x6 IRQ_TYPE_EDGE_RISING>,
   >                 <IPCC_CLIENT_SAIL0 0X7 IRQ_TYPE_EDGE_RISING>,
   >                 <IPCC_CLIENT_SAIL2 0X8 IRQ_TYPE_EDGE_RISING>,
   >                 <IPCC_CLIENT_SAIL1 0X9 IRQ_TYPE_EDGE_RISING>,
   >                 <IPCC_CLIENT_SAIL0 0XA IRQ_TYPE_EDGE_RISING>; //example entry for newly created channel at sail side
   >   sail-handshake-delay = <50000>;
   >   status = "okay";
   >          };
   > ```
   >
   > <Note>
   >   **Note**
   >
   >   <br />`&ipcc_computeL1 IPCC_CLIENT_SAIL0 0xA` indicates:
   >
   >   > * `ipcc_computeL1`: Protocol name (currently only this is supported).
   >   > * `IPCC_CLIENT_SAIL1`: RTSS core number.
   >   > * `0XA`: Channel number.
   >
   >   * Example mapping:
   >     ```text theme={null}
   >     <&ipcc_computeL1 IPCC_CLIENT_SAIL0 0x3>,
   >     <IPCC_CLIENT_SAIL0 0x3 IRQ_TYPE_EDGE_RISING>
   >     ```
   >     This corresponds to the `/dev/sail/log`, mapped to `MAILBOX_CONSOLE` with index value 3 in the `xMailboxExtClientType` enum.
   > </Note>

> References:
>
> > * `saildbg`
> >   > * Location
> >   >
> >   >   `sail-mailbox/reference_apps/sail_dbg/src/saildbg.c`
> >   > * Key APIs:
> >   >   * `open_sail_mailbox()`: Opens the mailbox channel for TX and RX.
> >   >   * `write_sail_mailbox()`: Writes a message to the TX channel.
> >   >   * `read_sail_mailbox()`: Reads a message from the RX channel.
> >   >   * `close_sail_mailbox()`: Closes the mailbox channel for TX and RX.
> >   > * Structures:
> >   >   * `struct SailClientDataType *pTxClientData`: TX structure for transmitting messages.
> >   >   * `struct SailClientDataType *pRxClientData`: RX structure for receiving messages.
> >   > * Mailbox test application:
> >   >
> >   >   [Mailbox test application: saildbg](https://docs.qualcomm.com/doc/80-70033-42/topic/test-commands.html#mailbox-test-applications-saildbg)
> > * `sail_console_chan`:
> >   > * Location:
> >   >
> >   >   `sail-mailbox/unit_test_apps/sail_console_chan_app.c`
> >   > * Mailbox test application:
> >   >
> >   >   [Mailbox test application: sail\_console\_chan\_app](https://docs.qualcomm.com/doc/80-70033-42/topic/test-commands.html#mailbox-test-applications-sail-console-chan-app)

## **RTSS mailbox demo application**

The `sailmb_demo` reference application demonstrates bidirectional mailbox communication between the APSS, which runs Linux, and RTSS, which runs Free RTOS. The application sends a message from APSS to an RTSS CPU core and receives a response from that RTSS CPU core.

A successful message exchange verifies the following:

* The RTSS firmware has initialized the shared mailbox structure in DDR.
* The Linux mailbox driver has loaded, mapped the shared memory, and completed the hardware handshake with RTSS.
* The APSS application can write a message to shared memory and trigger an interrupt to RTSS.
* RTSS can receive the interrupt, read the message, write a response, and trigger an interrupt to APSS.
* APSS can receive the interrupt, read the response, and display it on the console.

The application communicates with four RTSS CPU cores. Each core uses a dedicated transmit and receive channel pair. The mailbox channel mappings in the following table are from the APSS perspective:

| **RTSS core** | **APSS transmit channel** | **APSS receive channel** | **RTSS task** | **IPCC signal** | **Buffer capacity** | **Message size** |
| :-: | :-: | :-: | :-: | :-: | :-: | :-: |
| Core 0 | `/dev/sail/cz0` | `/dev/sail/cz1` | xCore0Task | Signal 13 | 10 messages | 64 bytes per message |
| Core 1 | `/dev/sail/co0` | `/dev/sail/co1` | xCore1Task | Signal 14 | 10 messages | 64 bytes per message |
| Core 2 | `/dev/sail/ct0` | `/dev/sail/ct1` | xCore2Task | Signal 15 | 10 messages | 64 bytes per message |
| Core 3 | `/dev/sail/cth0` | `/dev/sail/cth1` | xCore3Task | Signal 16 | 10 messages | 64 bytes per message |

To run the RTSS mailbox demo application, see [Mailbox test application: sailmb\_demo](https://docs.qualcomm.com/doc/80-70033-42/topic/test-commands.html#sailmb-demo-app).
