xref: /linux/include/linux/remoteproc.h (revision 0590420c2f90de497d342c9a41a618f46f4d09ab)
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/mutex.h>
40 #include <linux/virtio.h>
41 #include <linux/cdev.h>
42 #include <linux/completion.h>
43 #include <linux/idr.h>
44 #include <linux/of.h>
45 #include <linux/rsc_table.h>
46 
47 struct rproc;
48 
49 /**
50  * struct rproc_mem_entry - memory entry descriptor
51  * @va:	virtual address
52  * @is_iomem: io memory
53  * @dma: dma address
54  * @len: length, in bytes
55  * @da: device address
56  * @release: release associated memory
57  * @priv: associated data
58  * @name: associated memory region name (optional)
59  * @node: list node
60  * @rsc_offset: offset in resource table
61  * @flags: iommu protection flags
62  * @of_resm_idx: reserved memory phandle index
63  * @alloc: specific memory allocator function
64  */
65 struct rproc_mem_entry {
66 	void *va;
67 	bool is_iomem;
68 	dma_addr_t dma;
69 	size_t len;
70 	u32 da;
71 	void *priv;
72 	char name[32];
73 	struct list_head node;
74 	u32 rsc_offset;
75 	u32 flags;
76 	u32 of_resm_idx;
77 	int (*alloc)(struct rproc *rproc, struct rproc_mem_entry *mem);
78 	int (*release)(struct rproc *rproc, struct rproc_mem_entry *mem);
79 };
80 
81 struct firmware;
82 
83 /**
84  * enum rsc_handling_status - return status of rproc_ops handle_rsc hook
85  * @RSC_HANDLED:	resource was handled
86  * @RSC_IGNORED:	resource was ignored
87  */
88 enum rsc_handling_status {
89 	RSC_HANDLED	= 0,
90 	RSC_IGNORED	= 1,
91 };
92 
93 /**
94  * struct rproc_ops - platform-specific device handlers
95  * @prepare:	prepare device for code loading
96  * @unprepare:	unprepare device after stop
97  * @start:	power on the device and boot it
98  * @stop:	power off the device
99  * @attach:	attach to a device that his already powered up
100  * @detach:	detach from a device, leaving it powered up
101  * @kick:	kick a virtqueue (virtqueue id given as a parameter)
102  * @da_to_va:	optional platform hook to perform address translations
103  * @parse_fw:	parse firmware to extract information (e.g. resource table)
104  * @handle_rsc:	optional platform hook to handle vendor resources. Should return
105  *		RSC_HANDLED if resource was handled, RSC_IGNORED if not handled
106  *		and a negative value on error
107  * @find_loaded_rsc_table: find the loaded resource table from firmware image
108  * @get_loaded_rsc_table: get resource table installed in memory
109  *			  by external entity
110  * @load:		load firmware to memory, where the remote processor
111  *			expects to find it
112  * @sanity_check:	sanity check the fw image
113  * @get_boot_addr:	get boot address to entry point specified in firmware
114  * @panic:	optional callback to react to system panic, core will delay
115  *		panic at least the returned number of milliseconds
116  * @coredump:	  collect firmware dump after the subsystem is shutdown
117  */
118 struct rproc_ops {
119 	int (*prepare)(struct rproc *rproc);
120 	int (*unprepare)(struct rproc *rproc);
121 	int (*start)(struct rproc *rproc);
122 	int (*stop)(struct rproc *rproc);
123 	int (*attach)(struct rproc *rproc);
124 	int (*detach)(struct rproc *rproc);
125 	void (*kick)(struct rproc *rproc, int vqid);
126 	void * (*da_to_va)(struct rproc *rproc, u64 da, size_t len, bool *is_iomem);
127 	int (*parse_fw)(struct rproc *rproc, const struct firmware *fw);
128 	int (*handle_rsc)(struct rproc *rproc, u32 rsc_type, void *rsc,
129 			  int offset, int avail);
130 	struct resource_table *(*find_loaded_rsc_table)(
131 				struct rproc *rproc, const struct firmware *fw);
132 	struct resource_table *(*get_loaded_rsc_table)(
133 				struct rproc *rproc, size_t *size);
134 	int (*load)(struct rproc *rproc, const struct firmware *fw);
135 	int (*sanity_check)(struct rproc *rproc, const struct firmware *fw);
136 	u64 (*get_boot_addr)(struct rproc *rproc, const struct firmware *fw);
137 	unsigned long (*panic)(struct rproc *rproc);
138 	void (*coredump)(struct rproc *rproc);
139 };
140 
141 /**
142  * enum rproc_state - remote processor states
143  * @RPROC_OFFLINE:	device is powered off
144  * @RPROC_SUSPENDED:	device is suspended; needs to be woken up to receive
145  *			a message.
146  * @RPROC_RUNNING:	device is up and running
147  * @RPROC_CRASHED:	device has crashed; need to start recovery
148  * @RPROC_DELETED:	device is deleted
149  * @RPROC_ATTACHED:	device has been booted by another entity and the core
150  *			has attached to it
151  * @RPROC_DETACHED:	device has been booted by another entity and waiting
152  *			for the core to attach to it
153  * @RPROC_LAST:		just keep this one at the end
154  *
155  * Please note that the values of these states are used as indices
156  * to rproc_state_string, a state-to-name lookup table,
157  * so please keep the two synchronized. @RPROC_LAST is used to check
158  * the validity of an index before the lookup table is accessed, so
159  * please update it as needed too.
160  */
161 enum rproc_state {
162 	RPROC_OFFLINE	= 0,
163 	RPROC_SUSPENDED	= 1,
164 	RPROC_RUNNING	= 2,
165 	RPROC_CRASHED	= 3,
166 	RPROC_DELETED	= 4,
167 	RPROC_ATTACHED	= 5,
168 	RPROC_DETACHED	= 6,
169 	RPROC_LAST	= 7,
170 };
171 
172 /**
173  * enum rproc_crash_type - remote processor crash types
174  * @RPROC_MMUFAULT:	iommu fault
175  * @RPROC_WATCHDOG:	watchdog bite
176  * @RPROC_FATAL_ERROR:	fatal error
177  *
178  * Each element of the enum is used as an array index. So that, the value of
179  * the elements should be always something sane.
180  *
181  * Feel free to add more types when needed.
182  */
183 enum rproc_crash_type {
184 	RPROC_MMUFAULT,
185 	RPROC_WATCHDOG,
186 	RPROC_FATAL_ERROR,
187 };
188 
189 /**
190  * enum rproc_dump_mechanism - Coredump options for core
191  * @RPROC_COREDUMP_DISABLED:	Don't perform any dump
192  * @RPROC_COREDUMP_ENABLED:	Copy dump to separate buffer and carry on with
193  *				recovery
194  * @RPROC_COREDUMP_INLINE:	Read segments directly from device memory. Stall
195  *				recovery until all segments are read
196  */
197 enum rproc_dump_mechanism {
198 	RPROC_COREDUMP_DISABLED,
199 	RPROC_COREDUMP_ENABLED,
200 	RPROC_COREDUMP_INLINE,
201 };
202 
203 /**
204  * struct rproc_dump_segment - segment info from ELF header
205  * @node:	list node related to the rproc segment list
206  * @da:		device address of the segment
207  * @size:	size of the segment
208  * @priv:	private data associated with the dump_segment
209  * @dump:	custom dump function to fill device memory segment associated
210  *		with coredump
211  * @offset:	offset of the segment
212  */
213 struct rproc_dump_segment {
214 	struct list_head node;
215 
216 	dma_addr_t da;
217 	size_t size;
218 
219 	void *priv;
220 	void (*dump)(struct rproc *rproc, struct rproc_dump_segment *segment,
221 		     void *dest, size_t offset, size_t size);
222 	loff_t offset;
223 };
224 
225 /**
226  * enum rproc_features - features supported
227  *
228  * @RPROC_FEAT_ATTACH_ON_RECOVERY: The remote processor does not need help
229  *				   from Linux to recover, such as firmware
230  *				   loading. Linux just needs to attach after
231  *				   recovery.
232  */
233 
234 enum rproc_features {
235 	RPROC_FEAT_ATTACH_ON_RECOVERY,
236 	RPROC_MAX_FEATURES,
237 };
238 
239 /**
240  * struct rproc - represents a physical remote processor device
241  * @node: list node of this rproc object
242  * @domain: iommu domain
243  * @name: human readable name of the rproc
244  * @firmware: name of firmware file to be loaded
245  * @priv: private data which belongs to the platform-specific rproc module
246  * @ops: platform-specific start/stop rproc handlers
247  * @dev: virtual device for refcounting and common remoteproc behavior
248  * @power: refcount of users who need this rproc powered up
249  * @state: state of the device
250  * @dump_conf: Currently selected coredump configuration
251  * @lock: lock which protects concurrent manipulations of the rproc
252  * @dbg_dir: debugfs directory of this rproc device
253  * @traces: list of trace buffers
254  * @num_traces: number of trace buffers
255  * @carveouts: list of physically contiguous memory allocations
256  * @mappings: list of iommu mappings we initiated, needed on shutdown
257  * @bootaddr: address of first instruction to boot rproc with (optional)
258  * @rvdevs: list of remote virtio devices
259  * @subdevs: list of subdevices, to following the running state
260  * @notifyids: idr for dynamically assigning rproc-wide unique notify ids
261  * @index: index of this rproc device
262  * @crash_handler: workqueue for handling a crash
263  * @crash_cnt: crash counter
264  * @recovery_disabled: flag that state if recovery was disabled
265  * @max_notifyid: largest allocated notify id.
266  * @table_ptr: pointer to the resource table in effect
267  * @clean_table: copy of the resource table without modifications.  Used
268  *		 when a remote processor is attached or detached from the core
269  * @cached_table: copy of the resource table
270  * @table_sz: size of @cached_table
271  * @has_iommu: flag to indicate if remote processor is behind an MMU
272  * @auto_boot: flag to indicate if remote processor should be auto-started
273  * @sysfs_read_only: flag to make remoteproc sysfs files read only
274  * @dump_segments: list of segments in the firmware
275  * @nb_vdev: number of vdev currently handled by rproc
276  * @elf_class: firmware ELF class
277  * @elf_machine: firmware ELF machine
278  * @cdev: character device of the rproc
279  * @cdev_put_on_release: flag to indicate if remoteproc should be shutdown on @char_dev release
280  * @features: indicate remoteproc features
281  */
282 struct rproc {
283 	struct list_head node;
284 	struct iommu_domain *domain;
285 	const char *name;
286 	const char *firmware;
287 	void *priv;
288 	struct rproc_ops *ops;
289 	struct device dev;
290 	atomic_t power;
291 	unsigned int state;
292 	enum rproc_dump_mechanism dump_conf;
293 	struct mutex lock;
294 	struct dentry *dbg_dir;
295 	struct list_head traces;
296 	int num_traces;
297 	struct list_head carveouts;
298 	struct list_head mappings;
299 	u64 bootaddr;
300 	struct list_head rvdevs;
301 	struct list_head subdevs;
302 	struct idr notifyids;
303 	int index;
304 	struct work_struct crash_handler;
305 	unsigned int crash_cnt;
306 	bool recovery_disabled;
307 	int max_notifyid;
308 	struct resource_table *table_ptr;
309 	struct resource_table *clean_table;
310 	struct resource_table *cached_table;
311 	size_t table_sz;
312 	bool has_iommu;
313 	bool auto_boot;
314 	bool sysfs_read_only;
315 	struct list_head dump_segments;
316 	int nb_vdev;
317 	u8 elf_class;
318 	u16 elf_machine;
319 	struct cdev cdev;
320 	bool cdev_put_on_release;
321 	DECLARE_BITMAP(features, RPROC_MAX_FEATURES);
322 };
323 
324 /**
325  * struct rproc_subdev - subdevice tied to a remoteproc
326  * @node: list node related to the rproc subdevs list
327  * @prepare: prepare function, called before the rproc is started
328  * @start: start function, called after the rproc has been started
329  * @stop: stop function, called before the rproc is stopped; the @crashed
330  *	    parameter indicates if this originates from a recovery
331  * @unprepare: unprepare function, called after the rproc has been stopped
332  */
333 struct rproc_subdev {
334 	struct list_head node;
335 
336 	int (*prepare)(struct rproc_subdev *subdev);
337 	int (*start)(struct rproc_subdev *subdev);
338 	void (*stop)(struct rproc_subdev *subdev, bool crashed);
339 	void (*unprepare)(struct rproc_subdev *subdev);
340 };
341 
342 /* we currently support only two vrings per rvdev */
343 
344 #define RVDEV_NUM_VRINGS 2
345 
346 /**
347  * struct rproc_vring - remoteproc vring state
348  * @va:	virtual address
349  * @num: vring size
350  * @da: device address
351  * @align: vring alignment
352  * @notifyid: rproc-specific unique vring index
353  * @rvdev: remote vdev
354  * @vq: the virtqueue of this vring
355  */
356 struct rproc_vring {
357 	void *va;
358 	int num;
359 	u32 da;
360 	u32 align;
361 	int notifyid;
362 	struct rproc_vdev *rvdev;
363 	struct virtqueue *vq;
364 };
365 
366 /**
367  * struct rproc_vdev - remoteproc state for a supported virtio device
368  * @subdev: handle for registering the vdev as a rproc subdevice
369  * @pdev: remoteproc virtio platform device
370  * @id: virtio device id (as in virtio_ids.h)
371  * @node: list node
372  * @rproc: the rproc handle
373  * @vring: the vrings for this vdev
374  * @rsc_offset: offset of the vdev's resource entry
375  * @index: vdev position versus other vdev declared in resource table
376  */
377 struct rproc_vdev {
378 
379 	struct rproc_subdev subdev;
380 	struct platform_device *pdev;
381 
382 	unsigned int id;
383 	struct list_head node;
384 	struct rproc *rproc;
385 	struct rproc_vring vring[RVDEV_NUM_VRINGS];
386 	u32 rsc_offset;
387 	u32 index;
388 };
389 
390 struct rproc *rproc_get_by_phandle(phandle phandle);
391 struct rproc *rproc_get_by_child(struct device *dev);
392 
393 struct rproc *rproc_alloc(struct device *dev, const char *name,
394 			  const struct rproc_ops *ops,
395 			  const char *firmware, int len);
396 void rproc_put(struct rproc *rproc);
397 int rproc_add(struct rproc *rproc);
398 int rproc_del(struct rproc *rproc);
399 void rproc_free(struct rproc *rproc);
400 void rproc_resource_cleanup(struct rproc *rproc);
401 
402 struct rproc *devm_rproc_alloc(struct device *dev, const char *name,
403 			       const struct rproc_ops *ops,
404 			       const char *firmware, int len);
405 int devm_rproc_add(struct device *dev, struct rproc *rproc);
406 
407 void rproc_add_carveout(struct rproc *rproc, struct rproc_mem_entry *mem);
408 
409 struct rproc_mem_entry *
410 rproc_mem_entry_init(struct device *dev,
411 		     void *va, dma_addr_t dma, size_t len, u32 da,
412 		     int (*alloc)(struct rproc *, struct rproc_mem_entry *),
413 		     int (*release)(struct rproc *, struct rproc_mem_entry *),
414 		     const char *name, ...);
415 
416 struct rproc_mem_entry *
417 rproc_of_resm_mem_entry_init(struct device *dev, u32 of_resm_idx, size_t len,
418 			     u32 da, const char *name, ...);
419 
420 int rproc_boot(struct rproc *rproc);
421 int rproc_shutdown(struct rproc *rproc);
422 int rproc_detach(struct rproc *rproc);
423 int rproc_set_firmware(struct rproc *rproc, const char *fw_name);
424 void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type);
425 void *rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem);
426 
427 /* from remoteproc_coredump.c */
428 void rproc_coredump_cleanup(struct rproc *rproc);
429 void rproc_coredump(struct rproc *rproc);
430 void rproc_coredump_using_sections(struct rproc *rproc);
431 int rproc_coredump_add_segment(struct rproc *rproc, dma_addr_t da, size_t size);
432 int rproc_coredump_add_custom_segment(struct rproc *rproc,
433 				      dma_addr_t da, size_t size,
434 				      void (*dumpfn)(struct rproc *rproc,
435 						     struct rproc_dump_segment *segment,
436 						     void *dest, size_t offset,
437 						     size_t size),
438 				      void *priv);
439 int rproc_coredump_set_elf_info(struct rproc *rproc, u8 class, u16 machine);
440 
441 void rproc_add_subdev(struct rproc *rproc, struct rproc_subdev *subdev);
442 
443 void rproc_remove_subdev(struct rproc *rproc, struct rproc_subdev *subdev);
444 
445 #endif /* REMOTEPROC_H */
446