aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/remoteproc.h
diff options
context:
space:
mode:
authorOhad Ben-Cohen <ohad@wizery.com>2011-10-20 10:52:46 -0400
committerOhad Ben-Cohen <ohad@wizery.com>2012-02-08 15:52:56 -0500
commit400e64df6b237eb36b127efd72000a2794f9eec1 (patch)
treecdc007e406c3305d4ac2356e5b402b9c1ca82a6a /include/linux/remoteproc.h
parentdcd6c92267155e70a94b3927bce681ce74b80d1f (diff)
remoteproc: add framework for controlling remote processors
Modern SoCs typically employ a central symmetric multiprocessing (SMP) application processor running Linux, with several other asymmetric multiprocessing (AMP) heterogeneous processors running different instances of operating system, whether Linux or any other flavor of real-time OS. Booting a remote processor in an AMP configuration typically involves: - Loading a firmware which contains the OS image - Allocating and providing it required system resources (e.g. memory) - Programming an IOMMU (when relevant) - Powering on the device This patch introduces a generic framework that allows drivers to do that. In the future, this framework will also include runtime power management and error recovery. Based on (but now quite far from) work done by Fernando Guzman Lugo <fernando.lugo@ti.com>. ELF loader was written by Mark Grosen <mgrosen@ti.com>, based on msm's Peripheral Image Loader (PIL) by Stephen Boyd <sboyd@codeaurora.org>. Designed with Brian Swetland <swetland@google.com>. Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com> Acked-by: Grant Likely <grant.likely@secretlab.ca> Cc: Brian Swetland <swetland@google.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Tony Lindgren <tony@atomide.com> Cc: Russell King <linux@arm.linux.org.uk> Cc: Rusty Russell <rusty@rustcorp.com.au> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Greg KH <greg@kroah.com> Cc: Stephen Boyd <sboyd@codeaurora.org>
Diffstat (limited to 'include/linux/remoteproc.h')
-rw-r--r--include/linux/remoteproc.h265
1 files changed, 265 insertions, 0 deletions
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
new file mode 100644
index 000000000000..1edbfde4593c
--- /dev/null
+++ b/include/linux/remoteproc.h
@@ -0,0 +1,265 @@
1/*
2 * Remote Processor Framework
3 *
4 * Copyright(c) 2011 Texas Instruments, Inc.
5 * Copyright(c) 2011 Google, Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 * * Neither the name Texas Instruments nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35#ifndef REMOTEPROC_H
36#define REMOTEPROC_H
37
38#include <linux/types.h>
39#include <linux/kref.h>
40#include <linux/klist.h>
41#include <linux/mutex.h>
42#include <linux/virtio.h>
43#include <linux/completion.h>
44
45/*
46 * The alignment between the consumer and producer parts of the vring.
47 * Note: this is part of the "wire" protocol. If you change this, you need
48 * to update your peers too.
49 */
50#define AMP_VRING_ALIGN (4096)
51
52/**
53 * struct fw_resource - describes an entry from the resource section
54 * @type: resource type
55 * @id: index number of the resource
56 * @da: device address of the resource
57 * @pa: physical address of the resource
58 * @len: size, in bytes, of the resource
59 * @flags: properties of the resource, e.g. iommu protection required
60 * @reserved: must be 0 atm
61 * @name: name of resource
62 *
63 * The remote processor firmware should contain a "resource table":
64 * array of 'struct fw_resource' entries.
65 *
66 * Some resources entries are mere announcements, where the host is informed
67 * of specific remoteproc configuration. Other entries require the host to
68 * do something (e.g. reserve a requested resource) and possibly also reply
69 * by overwriting a member inside 'struct fw_resource' with info about the
70 * allocated resource.
71 *
72 * Different resource entries use different members of this struct,
73 * with different meanings. This is pretty limiting and error-prone,
74 * so the plan is to move to variable-length TLV-based resource entries,
75 * where each resource type will have its own structure.
76 */
77struct fw_resource {
78 u32 type;
79 u32 id;
80 u64 da;
81 u64 pa;
82 u32 len;
83 u32 flags;
84 u8 reserved[16];
85 u8 name[48];
86} __packed;
87
88/**
89 * enum fw_resource_type - types of resource entries
90 *
91 * @RSC_CARVEOUT: request for allocation of a physically contiguous
92 * memory region.
93 * @RSC_DEVMEM: request to iommu_map a memory-based peripheral.
94 * @RSC_TRACE: announces the availability of a trace buffer into which
95 * the remote processor will be writing logs. In this case,
96 * 'da' indicates the device address where logs are written to,
97 * and 'len' is the size of the trace buffer.
98 * @RSC_VRING: request for allocation of a virtio vring (address should
99 * be indicated in 'da', and 'len' should contain the number
100 * of buffers supported by the vring).
101 * @RSC_VIRTIO_DEV: this entry declares about support for a virtio device,
102 * and serves as the virtio header. 'da' holds the
103 * the virtio device features, 'pa' holds the virtio guest
104 * features, 'len' holds the virtio status, and 'flags' holds
105 * the virtio id (currently only VIRTIO_ID_RPMSG is supported).
106 *
107 * Most of the resource entries share the basic idea of address/length
108 * negotiation with the host: the firmware usually asks (on behalf of the
109 * remote processor that will soon be booted with it) for memory
110 * of size 'len' bytes, and the host needs to allocate it and provide
111 * the device/physical address (when relevant) in 'da'/'pa' respectively.
112 *
113 * If the firmware is compiled with hard coded device addresses, and
114 * can't handle dynamically allocated 'da' values, then the 'da' field
115 * will contain the expected device addresses (today we actually only support
116 * this scheme, as there aren't yet any use cases for dynamically allocated
117 * device addresses).
118 */
119enum fw_resource_type {
120 RSC_CARVEOUT = 0,
121 RSC_DEVMEM = 1,
122 RSC_TRACE = 2,
123 RSC_VRING = 3,
124 RSC_VIRTIO_DEV = 4,
125 RSC_VIRTIO_CFG = 5,
126};
127
128/**
129 * struct rproc_mem_entry - memory entry descriptor
130 * @va: virtual address
131 * @dma: dma address
132 * @len: length, in bytes
133 * @da: device address
134 * @priv: associated data
135 * @node: list node
136 */
137struct rproc_mem_entry {
138 void *va;
139 dma_addr_t dma;
140 int len;
141 u64 da;
142 void *priv;
143 struct list_head node;
144};
145
146struct rproc;
147
148/**
149 * struct rproc_ops - platform-specific device handlers
150 * @start: power on the device and boot it
151 * @stop: power off the device
152 * @kick: kick a virtqueue (virtqueue id given as a parameter)
153 */
154struct rproc_ops {
155 int (*start)(struct rproc *rproc);
156 int (*stop)(struct rproc *rproc);
157 void (*kick)(struct rproc *rproc, int vqid);
158};
159
160/**
161 * enum rproc_state - remote processor states
162 * @RPROC_OFFLINE: device is powered off
163 * @RPROC_SUSPENDED: device is suspended; needs to be woken up to receive
164 * a message.
165 * @RPROC_RUNNING: device is up and running
166 * @RPROC_CRASHED: device has crashed; need to start recovery
167 * @RPROC_LAST: just keep this one at the end
168 *
169 * Please note that the values of these states are used as indices
170 * to rproc_state_string, a state-to-name lookup table,
171 * so please keep the two synchronized. @RPROC_LAST is used to check
172 * the validity of an index before the lookup table is accessed, so
173 * please update it as needed too.
174 */
175enum rproc_state {
176 RPROC_OFFLINE = 0,
177 RPROC_SUSPENDED = 1,
178 RPROC_RUNNING = 2,
179 RPROC_CRASHED = 3,
180 RPROC_LAST = 4,
181};
182
183/**
184 * struct rproc - represents a physical remote processor device
185 * @node: klist node of this rproc object
186 * @domain: iommu domain
187 * @name: human readable name of the rproc
188 * @firmware: name of firmware file to be loaded
189 * @priv: private data which belongs to the platform-specific rproc module
190 * @ops: platform-specific start/stop rproc handlers
191 * @dev: underlying device
192 * @refcount: refcount of users that have a valid pointer to this rproc
193 * @power: refcount of users who need this rproc powered up
194 * @state: state of the device
195 * @lock: lock which protects concurrent manipulations of the rproc
196 * @dbg_dir: debugfs directory of this rproc device
197 * @traces: list of trace buffers
198 * @num_traces: number of trace buffers
199 * @carveouts: list of physically contiguous memory allocations
200 * @mappings: list of iommu mappings we initiated, needed on shutdown
201 * @firmware_loading_complete: marks e/o asynchronous firmware loading
202 * @bootaddr: address of first instruction to boot rproc with (optional)
203 * @rvdev: virtio device (we only support a single rpmsg virtio device for now)
204 */
205struct rproc {
206 struct klist_node node;
207 struct iommu_domain *domain;
208 const char *name;
209 const char *firmware;
210 void *priv;
211 const struct rproc_ops *ops;
212 struct device *dev;
213 struct kref refcount;
214 atomic_t power;
215 unsigned int state;
216 struct mutex lock;
217 struct dentry *dbg_dir;
218 struct list_head traces;
219 int num_traces;
220 struct list_head carveouts;
221 struct list_head mappings;
222 struct completion firmware_loading_complete;
223 u64 bootaddr;
224 struct rproc_vdev *rvdev;
225};
226
227/**
228 * struct rproc_vdev - remoteproc state for a supported virtio device
229 * @rproc: the rproc handle
230 * @vdev: the virio device
231 * @vq: the virtqueues for this vdev
232 * @vring: the vrings for this vdev
233 * @dfeatures: virtio device features
234 * @gfeatures: virtio guest features
235 */
236struct rproc_vdev {
237 struct rproc *rproc;
238 struct virtio_device vdev;
239 struct virtqueue *vq[2];
240 struct rproc_mem_entry vring[2];
241 unsigned long dfeatures;
242 unsigned long gfeatures;
243};
244
245struct rproc *rproc_get_by_name(const char *name);
246void rproc_put(struct rproc *rproc);
247
248struct rproc *rproc_alloc(struct device *dev, const char *name,
249 const struct rproc_ops *ops,
250 const char *firmware, int len);
251void rproc_free(struct rproc *rproc);
252int rproc_register(struct rproc *rproc);
253int rproc_unregister(struct rproc *rproc);
254
255int rproc_boot(struct rproc *rproc);
256void rproc_shutdown(struct rproc *rproc);
257
258static inline struct rproc *vdev_to_rproc(struct virtio_device *vdev)
259{
260 struct rproc_vdev *rvdev = container_of(vdev, struct rproc_vdev, vdev);
261
262 return rvdev->rproc;
263}
264
265#endif /* REMOTEPROC_H */