199 lines
6.4 KiB
Plaintext
199 lines
6.4 KiB
Plaintext
|
Introduction
|
||
|
============
|
||
|
|
||
|
The MSM ADSPRPC driver implements an IPC (Inter-Processor Communication)
|
||
|
mechanism that allows for clients to transparently make remote method
|
||
|
invocations across processor boundaries.
|
||
|
|
||
|
The below diagram depicts invocation of a single method where the client
|
||
|
and objects reside on different processors. An object could expose
|
||
|
multiple methods which can be grouped together and referred to as an
|
||
|
interface.
|
||
|
|
||
|
: ,--------, ,------, ,-----------, ,------, ,--------,
|
||
|
: | | method | | | | | | method | |
|
||
|
: | Client |------->| Stub |->| Transport |->| Skel |------->| Object |
|
||
|
: | | | | | | | | | |
|
||
|
: `--------` `------` `-----------` `------` `--------`
|
||
|
|
||
|
Client: Linux user mode process that initiates the remote invocation
|
||
|
Stub: Auto generated code linked in with the user mode process that
|
||
|
takes care of marshaling parameters
|
||
|
Transport: Involved in carrying an invocation from a client to an
|
||
|
object. This involves two portions: 1) MSM ADSPRPC Linux
|
||
|
kernel driver that receives the remote invocation, queues
|
||
|
them up and then waits for the response after signaling the
|
||
|
remote side. 2) Service running on the remote side that
|
||
|
dequeues the messages from the queue and dispatches them for
|
||
|
processing.
|
||
|
Skel: Auto generated code that takes care of un-marshaling
|
||
|
parameters
|
||
|
Object: Method implementation
|
||
|
|
||
|
Hardware description
|
||
|
====================
|
||
|
|
||
|
The driver interfaces with the components in the DSP subsystem and does
|
||
|
not drive or manage any hardware resources.
|
||
|
|
||
|
Software description
|
||
|
====================
|
||
|
|
||
|
The MSM ADSPRPC driver uses SMD (Shared Memory Driver) to send and
|
||
|
receive messages with the remote processor. The SMD channel used for
|
||
|
communication is opened during initialization of the driver and is
|
||
|
closed when the driver module is unloaded. The driver does not expose
|
||
|
HLOS memory to the remote processor but rather communication of
|
||
|
invocation parameters happen over ION allocated buffers.
|
||
|
|
||
|
The driver receives remote call invocations via an ioctl call. When a
|
||
|
remote call invocation is received, the driver does the following:
|
||
|
- Retrieves the invocation parameters
|
||
|
- Copies input buffers in HLOS memory to ION allocated buffers
|
||
|
- Allocates ION buffers for output buffers in HLOS memory as required
|
||
|
- Scatter-gathers list of pages for ION allocated input and output
|
||
|
buffers
|
||
|
- Coalesces information about the contiguous page buffers
|
||
|
- Builds up a message with the received information
|
||
|
- Sends the message to a remote processor through an SMD channel
|
||
|
- Waits for a response from the remote processor through the SMD channel
|
||
|
- Reads the message available from the shared memory SMD channel
|
||
|
- Copies back from ION buffers to HLOS memory for output buffers
|
||
|
- Returns the response of the remote invocation
|
||
|
|
||
|
Design
|
||
|
======
|
||
|
|
||
|
The design goals of this transport mechanism are:
|
||
|
- Fast and efficient ways to transfer huge buffers across
|
||
|
inter-processor boundaries
|
||
|
- Zero copy of ION allocated buffers passed during invocations
|
||
|
|
||
|
To achieve the zero copy approach of ION allocated user space buffers,
|
||
|
the driver scatter-gathers the list of pages of the buffers being passed
|
||
|
in. This information is then sent over to the remote processor for it
|
||
|
to map into its address space.
|
||
|
|
||
|
The invocation requests sent over the SMD channel carry context
|
||
|
information as to whom the request is originating from. The responses
|
||
|
received over the SMD channel have context information in the message
|
||
|
which is then used to wake the thread waiting for a response.
|
||
|
|
||
|
If the remote processor goes down and gets restarted, the SMD channel
|
||
|
is re-initialized when the remote processor comes back up. An
|
||
|
error code would be returned to the client for all invocations that
|
||
|
happen before the SMD channel could get completely re-initialized.
|
||
|
|
||
|
Power Management
|
||
|
================
|
||
|
|
||
|
None
|
||
|
|
||
|
SMP/multi-core
|
||
|
==============
|
||
|
|
||
|
The driver uses semaphores to wake up clients waiting for a remote
|
||
|
invocation response.
|
||
|
|
||
|
Security
|
||
|
========
|
||
|
|
||
|
Use of the zero copy approach results in a page-size granularity of
|
||
|
all buffers being passed to the remote processor. The objects that will
|
||
|
be manipulating these buffers on the remote processor will be signed
|
||
|
and trusted entities, thereby alleviating any fear of intentional
|
||
|
scribbling of these buffers.
|
||
|
|
||
|
Performance
|
||
|
===========
|
||
|
|
||
|
In order to minimize latencies across remote invocations:
|
||
|
- messages exchanged between the remote processors are kept short
|
||
|
- zero copy approach for ION allocated user space buffers
|
||
|
|
||
|
Interface
|
||
|
=========
|
||
|
|
||
|
The driver exposes a user space interface through /dev/adsprpc-smd and
|
||
|
the user space clients send commands to the driver by using the
|
||
|
following ioctl command:
|
||
|
|
||
|
- FASTRPC_IOCTL_INVOKE: Parameters passed in includes the buffers and
|
||
|
data related to remote invocation.
|
||
|
|
||
|
/*
|
||
|
* Information about the input/output buffer or an handle to the
|
||
|
* object being passed in the remote invocation
|
||
|
*
|
||
|
* @pv: Pointer to input/output buffer
|
||
|
* @len: Length of the input/output buffer
|
||
|
* @handle: Handle to the remote object
|
||
|
*/
|
||
|
typedef union {
|
||
|
struct remote_buf {
|
||
|
void *pv;
|
||
|
int len;
|
||
|
} buf;
|
||
|
unsigned int handle;
|
||
|
} remote_arg;
|
||
|
|
||
|
/*
|
||
|
* Invocation parameters passed via ioctl call by the client
|
||
|
*
|
||
|
* @handle: Handle to the object on which the method is to be
|
||
|
* invoked
|
||
|
* @sc: Scalars detailing the parameters being passed in
|
||
|
* bits 0-3: Number of output handles
|
||
|
* bits 4-7: Number of input handles
|
||
|
* bits 8-15: Number of output buffers
|
||
|
* bits 16-23: Number of input buffers
|
||
|
* bits 24-28: Method to be invoked
|
||
|
* bits 29-31: Method attributes
|
||
|
* @pra: Remote arguments to be passed for method invocation
|
||
|
*/
|
||
|
struct fastrpc_ioctl_invoke {
|
||
|
unsigned int handle;
|
||
|
unsigned int sc;
|
||
|
remote_arg *pra;
|
||
|
};
|
||
|
|
||
|
Driver parameters
|
||
|
=================
|
||
|
|
||
|
None
|
||
|
|
||
|
Config options
|
||
|
==============
|
||
|
|
||
|
None
|
||
|
|
||
|
Dependencies
|
||
|
============
|
||
|
|
||
|
The ADSPRPC driver requires that the ADSP RPC SMD channel be created and
|
||
|
the SMD subsystem be initialized. During initialization, the driver
|
||
|
opens an existing SMD edge channel between ADSP and Apps processor. On
|
||
|
success, the driver waits for the "channel opened" event from SMD,
|
||
|
acknowledging the channel availability from the remote SMD driver for
|
||
|
communication to begin.
|
||
|
|
||
|
User space utilities
|
||
|
====================
|
||
|
|
||
|
None
|
||
|
|
||
|
Other
|
||
|
=====
|
||
|
|
||
|
None
|
||
|
|
||
|
Known issues
|
||
|
============
|
||
|
|
||
|
None
|
||
|
|
||
|
To do
|
||
|
=====
|
||
|
|
||
|
None
|