123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478 |
- Introduction
- ============
- The Shared Memory Point to Point (SMP2P) protocol facilitates communication of
- a single 32-bit value between two processors. Each value has a single writer
- (the local side) and a single reader (the remote side). Values are uniquely
- identified in the system by the directed edge (local processor ID to remote
- processor ID) and a string identifier.
- Version and feature negotiation has been included in the design to allow for
- phased upgrades of all processors.
- Software Architecture Description
- =================================
- The data and interrupt coupling between processors is shown in Fig. 1. Each
- processor is responsible for creating the outgoing SMEM items and each item is
- writable by the local processor and readable by the remote processor. By using
- two separate SMEM items that are single-reader and single-writer, SMP2P does
- not require any remote locking mechanisms.
- The client API uses the Linux GPIO and interrupt framework to expose a virtual
- GPIO and a virtual interrupt controller for each entry.
- =================
- | |
- -----write------>|SMEM item A->B |-----read------
- | | | |
- | ================= |
- | |
- | v
- GPIO API => ------------ ======= Interrupt line ======> ------------
- Processor A Processor B
- Interrupt <= ------------ <====== Interrupt line ======= ------------
- API ^ |
- | |
- | |
- | ================= |
- | | | |
- ------read-------|SMEM item A<-B |<-----write----
- | |
- =================
- Fig 1
- Design
- ======
- Each SMEM item contains a header that is used to identify and manage the edge
- along with an array of actual entries. The overall structure is captured in
- Fig 2 and the details of the header and entries are covered later in this
- section. The memory format of all shared structures is little-endian.
- -----------------------------------------------
- | SMEM item A->B |
- | |
- | ----------------------------------------- |
- | |31 24| 16| 8| 0| |
- | |----------|---------|----------|---------| |
- | | Identifier Constant(Magic Number) | |
- | |----------|---------|----------|---------| |
- | | Feature Flags |Version | |
- | | |Number | |
- | |----------|---------|----------|---------| |
- | | Remote Proc ID |Local Proc ID | |
- | |----------|---------|----------|---------| |
- | | Entries Valid | Entries Total | |
- | |-----------------------------------------| |
- | |
- | |
- | ----------------------------------------- |
- | | Entry 0 | |
- | | ---------------------------------- | |
- | | | Identifier String | | |
- | | |---------------------------------| | |
- | | | Data | | |
- | | |---------------------------------| | |
- | |---------------------------------------| |
- | ----------------------------------------- |
- | | Entry 1 | |
- | | ---------------------------------- | |
- | | | Identifier String | | |
- | | |---------------------------------| | |
- | | | Data | | |
- | | |---------------------------------| | |
- | |---------------------------------------| |
- | - |
- | - |
- | - |
- | ----------------------------------------- |
- | | Entry N | |
- | | ---------------------------------- | |
- | | | Identifier String | | |
- | | |---------------------------------| | |
- | | | Data | | |
- | | |---------------------------------| | |
- | |---------------------------------------| |
- -----------------------------------------------
- Fig 2
- The header of each SMEM item contains metadata that describes the processors
- using the edge, the version information, and the entry count. The constant
- identifier is used as a magic number to enable extraction of the items from a
- memory dump. The size of each entry depends upon the version, but the number
- of total entries (and hence the size of each SMEM item) is configurable with a
- suggested value of 16.
- The number of valid entries is used to indicate how many of the Entries Total
- are currently used and are current valid.
- ---------------------------------------------------------------------------
- |Field Size Description Valid Values |
- ---------------------------------------------------------------------------
- | Identifier 4 Bytes Value used to identify |
- | Constant structure in memory. Must be set to $SMP |
- | Useful for debugging. (0x504D5324) |
- ---------------------------------------------------------------------------
- | Local 2 Bytes Writing processor ID. Refer Processor ID Table 3|
- | Processor |
- | ID |
- ---------------------------------------------------------------------------
- | Remote 2 Bytes Reading processor ID. Refer Processor ID Table 3|
- | Processor |
- | ID |
- ---------------------------------------------------------------------------
- | Version 1 Bytes Refer to Version |
- | Number Feature Negotiation Must be set to 1. |
- | section. |
- ---------------------------------------------------------------------------
- | Feature 3 Bytes Refer to Version |
- | flags and Feature Negotiation |
- | section for details. |
- | bit 0 SSR_ACK Feature Supported when set to 1 |
- | bits 1:31 Reserved Must be set to 0. |
- ---------------------------------------------------------------------------
- | Entries 2 Bytes Total number of Must be 0 or greater. |
- | Total entries. |
- ---------------------------------------------------------------------------
- | Entries 2 Bytes Number of valid Must be between 0 |
- | Valid entries. and Entries Total. |
- ---------------------------------------------------------------------------
- | Flags 4 Bytes |
- | bit 0 RESTART_DONE Toggle for every restart |
- | bit 1 RESTART_ACK Toggle to ACK remote |
- | RESTART_DONE |
- | bits 2:31 Reserved Must be set to 0. |
- ---------------------------------------------------------------------------
- Table 1 - SMEM Item Header
- The content of each SMEM entries is described in Table 2 and consists of a
- string identifier and a 32-bit data value. The string identifier must be
- unique for each SMEM item. The data value is opaque to SMP2P giving the client
- complete flexibility as to its usage.
- ----------------------- --------------------- -----------------------------
- | Field | Size | Description | Valid Values |
- ------------|----------|---------------------|-----------------------------
- | | | | |
- | Identifier | 16 Bytes | Null Terminated | NON-NULL for |
- | String | | ASCII string. | valid entries. |
- | | | | |
- ------------|----------|---------------------|-----------------------------
- | Data | 4 Bytes | Data | Any (client defined) |
- ------------ ---------- --------------------- -----------------------------
- Table 2 - Entry Format
- The processor IDs in the system are fixed and new processors IDs will be
- added to the end of the list (Table 3).
- -------------------------------------------------
- | Processor Name | ID value |
- -------------------------------------------------
- | Application processor | 0 |
- -------------------------------------------------
- | Modem processor | 1 |
- -------------------------------------------------
- | Audio processor | 2 |
- -------------------------------------------------
- | Sensor processor | 3 |
- -------------------------------------------------
- | Wireless processor | 4 |
- -------------------------------------------------
- | CDSP processor | 5 |
- -------------------------------------------------
- | Power processor | 6 |
- -------------------------------------------------
- | TrustZone processor | 7 |
- -------------------------------------------------
- | NUM PROCESSORS | 8 |
- -------------------------------------------------
- Table 3 - Processor IDs
- SMEM Item
- ---------
- The responsibility of creating an SMEM item is with the local processor that is
- initiating outbound traffic. After creating the item, the local and remote
- processors negotiate the version and feature flags for the item to ensure
- compatibility.
- Table 4 lists the SMEM item base identifiers. To get the SMEM item ID for a
- particular edge, the remote processor ID (Table 3) is added to the base item ID
- for the local processor (Table 4). For example, the Apps ==> Modem (id 1) SMEM
- Item ID will be 427 + 1 = 428.
- ---------------------------------------------------
- | Description | SMEM ID value |
- ---------------------------------------------------
- | CDSP SMEM Item base | 94 |
- ---------------------------------------------------
- | Apps SMP2P SMEM Item base | 427 |
- ---------------------------------------------------
- | Modem SMP2P SMEM Item base | 435 |
- ---------------------------------------------------
- | Audio SMP2P SMEM Item base | 443 |
- ---------------------------------------------------
- | Sensors SMP2P SMEM Item base | 481 |
- ---------------------------------------------------
- | Wireless SMP2P SMEM Item base | 451 |
- ---------------------------------------------------
- | Power SMP2P SMEM Item base | 459 |
- ---------------------------------------------------
- | TrustZone SMP2P SMEM Item base | 489 |
- ---------------------------------------------------
- Table 4 - SMEM Items Base IDs
- Version and Feature Negotiation
- -------------------------------
- To enable upgrading without breaking the system and to enable graceful feature
- fall-back support, SMP2P supports a version number and feature flags. The
- combination of the version number and feature flags enable:
- 1) SMP2P software updates to be rolled out to each processor separately.
- 2) Individual features to be enabled or disabled per connection or edge.
- The version number represents any change in SMP2P that breaks compatibility
- between processors. Examples would be a change in the shared data structures
- or changes to fundamental behavior. Each implementation of SMP2P must be able
- to support a minimum of the current version and the previous version.
- The feature flags represent any changes in SMP2P that are optional and
- backwards compatible. Endpoints will negotiate the supported flag when the
- SMEM items are created and they cannot be changed after negotiation has been
- completed.
- Negotiation Algorithm
- ----------------------
- While creating the SMEM item the following algorithm shall be used.
- if remote endpoint's SMEM Item exists
- Read remote version number and flags
- Local version number must be lower of
- - remote version number
- - highest supported local version number
- Flags value is bitwise AND of
- - remote feature flags
- - locally supported flags
- Create SMEM item and populate negotiated number and flags
- Interrupt remote processor
- if version and flags match, negotiation is complete, else wait
- for remote interrupt below.
- Else
- Create SMEM item and populate it with highest supported version and any
- requested feature flag.
- Interrupt remote processor.
- Wait for Interrupt below.
- Upon receiving the interrupt from remote processor and negotiation is not
- complete, check the version number and feature flags:
- if equal, negotiation is complete.
- if remote number is less than local number, and remote number is
- supported:
- Set local version number to remote version number
- Bitwise AND local flags with remote flags
- Interrupt remote processor
- Negotiation is complete
- if remote number is not supported, then negotiation has failed
- Set version number to 0xFF and report failure in kernel log.
- if remote number is more than local number:
- Wait for remote endpoint to process our interrupt and negotiate down.
- Creating an SMEM Entry
- ----------------------
- Each new SMEM entry used in data transfer must be created at the end of the
- entry array in the SMEM item and cannot be deleted until the system is
- rebooted. The following sequence is be followed:
- 1) Compare Entries Valid and Entries Total to verify if there is room in the
- entry array for this request (if not, return error code to client).
- 2) Populate the Identifier of new entry and do a write memory barrier.
- 3) Update Entries Valid and Entries Total and do a write memory barrier.
- 4) Interrupt remote endpoint.
- Entry Write
- -----------
- An entry write is achieved by the following sequence of operations:
- 1) Update data field in the entry and do a write memory barrier.
- 2) Interrupt remote endpoint.
- Entry Read / Receiving Interrupts
- ---------------------------------
- An interrupt will be received from the remote system for one or more of the following events:
- 1) Initialization
- 2) Entry change
- 3) New Entry
- As long as the SMEM item initialization is complete, then each interrupt should
- trigger SMP2P to:
- 1) Compare valid entry data value to cached value and notify client if it
- has changed.
- 2) Compare Entries Valid to cached value. If changed, initialize new entries.
- Security
- ========
- Since the implementation resides in the kernel and does not expose interfaces
- to userspace, no security issues are anticipated. The usage of separate SMEM
- items allows for future security enhancements in SMEM.
- Performance
- ===========
- No performance issues are anticipated as the signaling rate is expected to be
- low and is performed in interrupt context which minimizes latency.
- Interfaces
- ================
- SMP2P is only supported in the kernel and interfaces with clients through the
- GPIO and interrupt subsystems.
- To map an entry to the client, the client must add two nodes to the Device
- Tree:
- 1) A node that matches "qcom,smp2pgpio" to create the entry
- 2) A node that matches the client driver to provide the GPIO pin mapping
- The details of the device tree entries for the GPIO interface are contained in
- the file Documentation/devicetree/bindings/gpio/gpio-smp2p.txt.
- /* SMP2P Test Driver for inbound entry. */
- smp2pgpio_smp2p_7_in: qcom,smp2pgpio-smp2p-7-in {
- compatible = "qcom,smp2pgpio";
- qcom,entry-name = "smp2p";
- qcom,remote-pid = <7>;
- qcom,is-inbound;
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
- /* SMP2P Test Client for inbound entry. */
- qcom,smp2pgpio_test_smp2p_7_in {
- compatible = "qcom,smp2pgpio_test_smp2p_7_in";
- gpios = <&smp2pgpio_smp2p_7_in 0 0>,
- <&smp2pgpio_smp2p_7_in 1 0>,
- . . .
- <&smp2pgpio_smp2p_7_in 31 0>;
- };
- /* SMP2P Test Driver for outbound entries */
- smp2pgpio_smp2p_345_out: qcom,smp2pgpio-smp2p-7-out {
- compatible = "qcom,smp2pgpio";
- qcom,entry-name = "smp2p";
- qcom,remote-pid = <7>;
- gpio-controller;
- #gpio-cells = <2>;
- interrupt-controller;
- #interrupt-cells = <2>;
- };
- /* SMP2P Test Client for outbound entry. */
- qcom,smp2pgpio_test_smp2p_7_out {
- compatible = "qcom,smp2pgpio_test_smp2p_7_out";
- gpios = <&smp2pgpio_smp2p_7_out 0 0>,
- <&smp2pgpio_smp2p_7_out 1 0>,
- . . .
- <&smp2pgpio_smp2p_7_out 31 0>;
- The client can use a match entry for "qcom,smp2pgpio_test_smp2p_7_in" to
- retrieve the Device Tree configuration node. Once that node has been
- retrieved, the client can call of_get_gpio() to get the virtual GPIO pin and
- also use gpio_to_irq() to map the GPIO pin to a virtual interrupt. After that
- point, the standard GPIO and Interrupt APIs can be used to manipulate the SMP2P
- entries and receive notifications of changes. Examples of typical function
- calls are shown below:
- of_get_gpio()
- gpio_get_value()
- gpio_set_value()
- gpio_to_irq()
- request_irq()
- free_irq()
- Please reference the unit test code for example usage.
- Subsystem Restart
- =================
- SMP2P is unaffected by SubSystem Restart (SSR) on the high-level OS side and is
- actually used as an underlying communication mechanism for SSR. On the
- peripheral system that is being restarted, SMP2P will zero out all existing
- state entries upon reboot as part of the SMP2P initialization process and if the
- SSR_ACK feature is enabled, then it waits for an acknowledgment as outlined in
- the following subsections.
- SSR_ACK Feature - Reboot Use Case (Non-HLOS Only)
- -------------------------------------------------
- If a remote system boots up after an SSR and sees that the remote and local
- version numbers and feature flags are equal, then it zeros out entry values. If
- the SSR_ACK feature is enabled, it will wait for an acknowledgment from the other
- processor that it has seen the zero entry before completing the negotiation
- sequence.
- if remote and local version numbers and feature flags are equal
- Zero out all entry values
- if SSR_ACK feature is enabled
- Set local RESTART_DONE flag to inverse of the remote RESTART_ACK
- Send interrupt to remote system
- Wait for interrupt and for remote RESTART_ACK to be equal to local
- RESTART_DONE
- Continue with normal negotiation sequence
- Interrupt Use Case
- ------------------
- For every interrupt triggered by a remote change, SMP2P will notify the client
- of a change in state. In addition, if the SSR_ACK feature is enabled, the SSR
- handshaking will also be handled.
- if SSR_ACK feature is enabled
- if remote RESTART_DONE != local RESTART_ACK
- Notify client of entry change (will be * -> 0 transition)
- Toggle local RESTART_ACK
- Send interrupt to remote system
- else
- Notify client of entry change as usual
- else
- Notify client of entry change as usual
- Debug
- =====
- The state values and names for all entries accessible by the Apps are
- accessible through debugfs nodes for general debug purposes.
- Debugfs entries for triggering unit-tests are also exported.
- Internal logging will be performed using the IPC Logging module to enable
- post-mortem analysis.
- Testing
- =======
- On-target unit testing will be done to verify internal functionality and the
- GPIO/IRQ API's.
- Driver parameters
- =================
- One module parameter will be provided to change the verbosity of internal logging.
- Config options
- ==============
- Configuration of interrupts will be done using Device Tree per the format in
- Documentation/devicetree/bindings/arm/msm/smp2p.txt. By default, the testing
- components will be enabled since it does not affect performance and has a
- minimal impact on kernel size. However, customers can disable the testing
- component for size optimization.
- CONFIG_MSM_SMP2P - enables SMP2P
- CONFIG_MSM_SMP2P_TEST - enables unit test support
- Dependencies
- ===========
- Requires SMEM for creating the SMEM items.
- User Space utilities
- ====================
- No userspace utilities are planned.
- Known issues
- ============
- None.
|