Something went wrong. Try again.
(I'm so sorry!) Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428/* SPDX-License-Identifier: BSD-3-Clause *//* * Copyright(c) 2011 Texas Instruments, Inc. * Copyright(c) 2011 Google, Inc. * All rights reserved. */
#ifndef REMOTEPROC_H#define REMOTEPROC_H
#include <linux/types.h>#include <linux/mutex.h>#include <linux/spinlock.h>#include <linux/virtio.h>#include <linux/cdev.h>#include <linux/completion.h>#include <linux/idr.h>#include <linux/srcu.h>#include <linux/of.h>#include <linux/rsc_table.h>
struct rproc;
/** * struct rproc_mem_entry - memory entry descriptor * @va: virtual address * @is_iomem: io memory * @dma: dma address * @len: length, in bytes * @da: device address * @release: release associated memory * @priv: associated data * @name: associated memory region name (optional) * @node: list node * @rsc_offset: offset in resource table * @flags: iommu protection flags * @of_resm_idx: reserved memory phandle index * @alloc: specific memory allocator function */struct rproc_mem_entry { void *va; bool is_iomem; dma_addr_t dma; size_t len; u32 da; void *priv; char name[32]; struct list_head node; u32 rsc_offset; u32 flags; u32 of_resm_idx; int (*alloc)(struct rproc *rproc, struct rproc_mem_entry *mem); int (*release)(struct rproc *rproc, struct rproc_mem_entry *mem);};
struct firmware;
/** * enum rsc_handling_status - return status of rproc_ops handle_rsc hook * @RSC_HANDLED: resource was handled * @RSC_IGNORED: resource was ignored */enum rsc_handling_status { RSC_HANDLED = 0, RSC_IGNORED = 1,};
/** * struct rproc_ops - platform-specific device handlers * @prepare: prepare device for code loading * @unprepare: unprepare device after stop * @start: power on the device and boot it * @stop: power off the device * @attach: attach to a device that his already powered up * @detach: detach from a device, leaving it powered up * @kick: kick a virtqueue (virtqueue id given as a parameter) * @da_to_va: optional platform hook to perform address translations * @parse_fw: parse firmware to extract information (e.g. resource table) * @handle_rsc: optional platform hook to handle vendor resources. Should return * RSC_HANDLED if resource was handled, RSC_IGNORED if not handled * and a negative value on error * @find_loaded_rsc_table: find the loaded resource table from firmware image * @get_loaded_rsc_table: get resource table installed in memory * by external entity * @load: load firmware to memory, where the remote processor * expects to find it * @sanity_check: sanity check the fw image * @get_boot_addr: get boot address to entry point specified in firmware * @panic: optional callback to react to system panic, core will delay * panic at least the returned number of milliseconds * @coredump: collect firmware dump after the subsystem is shutdown */struct rproc_ops { int (*prepare)(struct rproc *rproc); int (*unprepare)(struct rproc *rproc); int (*start)(struct rproc *rproc); int (*stop)(struct rproc *rproc); int (*attach)(struct rproc *rproc); int (*detach)(struct rproc *rproc); void (*kick)(struct rproc *rproc, int vqid); void * (*da_to_va)(struct rproc *rproc, u64 da, size_t len, bool *is_iomem); int (*parse_fw)(struct rproc *rproc, const struct firmware *fw); int (*handle_rsc)(struct rproc *rproc, u32 rsc_type, void *rsc, int offset, int avail); struct resource_table *(*find_loaded_rsc_table)(struct rproc *rproc, const struct firmware *fw); struct resource_table *(*get_loaded_rsc_table)(struct rproc *rproc, size_t *size); int (*load)(struct rproc *rproc, const struct firmware *fw); int (*sanity_check)(struct rproc *rproc, const struct firmware *fw); u64 (*get_boot_addr)(struct rproc *rproc, const struct firmware *fw); unsigned long (*panic)(struct rproc *rproc); void (*coredump)(struct rproc *rproc);};
/** * enum rproc_state - remote processor states * @RPROC_OFFLINE: device is powered off * @RPROC_SUSPENDED: device is suspended; needs to be woken up to receive * a message. * @RPROC_RUNNING: device is up and running * @RPROC_CRASHED: device has crashed; need to start recovery * @RPROC_ATTACHED: device has been booted by another entity and the core * has attached to it * @RPROC_DETACHED: device has been booted by another entity and waiting * for the core to attach to it * @RPROC_LAST: just keep this one at the end * * Please note that the values of these states are used as indices * to rproc_state_string, a state-to-name lookup table, * so please keep the two synchronized. @RPROC_LAST is used to check * the validity of an index before the lookup table is accessed, so * please update it as needed too. */enum rproc_state { RPROC_OFFLINE = 0, RPROC_SUSPENDED = 1, RPROC_RUNNING = 2, RPROC_CRASHED = 3, RPROC_ATTACHED = 4, RPROC_DETACHED = 5, RPROC_LAST = 6,};
/** * enum rproc_crash_type - remote processor crash types * @RPROC_MMUFAULT: iommu fault * @RPROC_WATCHDOG: watchdog bite * @RPROC_FATAL_ERROR: fatal error * * Each element of the enum is used as an array index. So that, the value of * the elements should be always something sane. * * Feel free to add more types when needed. */enum rproc_crash_type { RPROC_MMUFAULT, RPROC_WATCHDOG, RPROC_FATAL_ERROR,};
/** * enum rproc_dump_mechanism - Coredump options for core * @RPROC_COREDUMP_DISABLED: Don't perform any dump * @RPROC_COREDUMP_ENABLED: Copy dump to separate buffer and carry on with * recovery * @RPROC_COREDUMP_INLINE: Read segments directly from device memory. Stall * recovery until all segments are read */enum rproc_dump_mechanism { RPROC_COREDUMP_DISABLED, RPROC_COREDUMP_ENABLED, RPROC_COREDUMP_INLINE,};
/** * struct rproc_dump_segment - segment info from ELF header * @node: list node related to the rproc segment list * @da: device address of the segment * @size: size of the segment * @priv: private data associated with the dump_segment * @dump: custom dump function to fill device memory segment associated * with coredump * @offset: offset of the segment */struct rproc_dump_segment { struct list_head node;
dma_addr_t da; size_t size;
void *priv; void (*dump)(struct rproc *rproc, struct rproc_dump_segment *segment, void *dest, size_t offset, size_t size); loff_t offset;};
/** * enum rproc_features - features supported * * @RPROC_FEAT_ATTACH_ON_RECOVERY: The remote processor does not need help * from Linux to recover, such as firmware * loading. Linux just needs to attach after * recovery. */
enum rproc_features { RPROC_FEAT_ATTACH_ON_RECOVERY, RPROC_MAX_FEATURES,};
/** * struct rproc - represents a physical remote processor device * @node: list node of this rproc object * @domain: iommu domain * @name: human readable name of the rproc * @firmware: name of firmware file to be loaded * @priv: private data which belongs to the platform-specific rproc module * @ops: platform-specific start/stop rproc handlers * @dev: virtual device for refcounting and common remoteproc behavior * @power: refcount of users who need this rproc powered up * @state: state of the device * @dump_conf: Currently selected coredump configuration * @lock: lock which protects concurrent manipulations of the rproc * @dbg_dir: debugfs directory of this rproc device * @traces: list of trace buffers * @num_traces: number of trace buffers * @carveouts: list of physically contiguous memory allocations * @mappings: list of iommu mappings we initiated, needed on shutdown * @bootaddr: address of first instruction to boot rproc with (optional) * @rvdevs: list of remote virtio devices * @vq_srcu: SRCU domain for the virtqueue callbacks of @rvdevs * @subdevs: list of subdevices, to following the running state * @notifyids: idr for dynamically assigning rproc-wide unique notify ids * @index: index of this rproc device * @attach_work: workqueue for attaching rproc * @crash_handler: workqueue for handling a crash * @crash_handler_lock: serializes crash handler queueing and deletion * @deleting: remoteproc deletion has begun * @crash_cnt: crash counter * @recovery_disabled: flag that state if recovery was disabled * @max_notifyid: largest allocated notify id. * @table_ptr: pointer to the resource table in effect * @clean_table: copy of the resource table without modifications. Used * when a remote processor is attached or detached from the core * @cached_table: copy of the resource table * @table_sz: size of @cached_table * @has_iommu: flag to indicate if remote processor is behind an MMU * @auto_boot: flag to indicate if remote processor should be auto-started * @sysfs_read_only: flag to make remoteproc sysfs files read only * @subdevs_started: flag to indicate if subdevs have started * @dump_segments: list of segments in the firmware * @nb_vdev: number of vdev currently handled by rproc * @elf_class: firmware ELF class * @elf_machine: firmware ELF machine * @cdev: character device of the rproc * @cdev_put_on_release: flag to indicate if remoteproc should be shutdown on @char_dev release * @features: indicate remoteproc features */struct rproc { struct list_head node; struct iommu_domain *domain; const char *name; const char *firmware; void *priv; struct rproc_ops *ops; struct device dev; atomic_t power; unsigned int state; enum rproc_dump_mechanism dump_conf; struct mutex lock; struct dentry *dbg_dir; struct list_head traces; int num_traces; struct list_head carveouts; struct list_head mappings; u64 bootaddr; struct list_head rvdevs; struct srcu_struct vq_srcu; struct list_head subdevs; struct idr notifyids; int index; struct work_struct attach_work; struct work_struct crash_handler; spinlock_t crash_handler_lock; bool deleting; unsigned int crash_cnt; bool recovery_disabled; int max_notifyid; struct resource_table *table_ptr; struct resource_table *clean_table; struct resource_table *cached_table; size_t table_sz; bool has_iommu; bool auto_boot; bool sysfs_read_only; bool subdevs_started; struct list_head dump_segments; int nb_vdev; u8 elf_class; u16 elf_machine; struct cdev cdev; bool cdev_put_on_release; DECLARE_BITMAP(features, RPROC_MAX_FEATURES);};
/** * struct rproc_subdev - subdevice tied to a remoteproc * @node: list node related to the rproc subdevs list * @prepare: prepare function, called before the rproc is started * @start: start function, called after the rproc has been started * @stop: stop function, called before the rproc is stopped; the @crashed * parameter indicates if this originates from a recovery * @unprepare: unprepare function, called after the rproc has been stopped */struct rproc_subdev { struct list_head node;
int (*prepare)(struct rproc_subdev *subdev); int (*start)(struct rproc_subdev *subdev); void (*stop)(struct rproc_subdev *subdev, bool crashed); void (*unprepare)(struct rproc_subdev *subdev);};
/* we currently support only two vrings per rvdev */
#define RVDEV_NUM_VRINGS 2
/** * struct rproc_vring - remoteproc vring state * @va: virtual address * @num: vring size * @da: device address * @align: vring alignment * @notifyid: rproc-specific unique vring index * @rvdev: remote vdev * @vq: the virtqueue of this vring */struct rproc_vring { void *va; int num; u32 da; u32 align; int notifyid; struct rproc_vdev *rvdev; struct virtqueue *vq;};
/** * struct rproc_vdev - remoteproc state for a supported virtio device * @subdev: handle for registering the vdev as a rproc subdevice * @pdev: remoteproc virtio platform device * @id: virtio device id (as in virtio_ids.h) * @node: list node * @rproc: the rproc handle * @vring: the vrings for this vdev * @rsc_offset: offset of the vdev's resource entry * @index: vdev position versus other vdev declared in resource table */struct rproc_vdev { struct rproc_subdev subdev; struct platform_device *pdev;
unsigned int id; struct list_head node; struct rproc *rproc; struct rproc_vring vring[RVDEV_NUM_VRINGS]; u32 rsc_offset; u32 index;};
struct rproc *rproc_get_by_phandle(phandle phandle);struct rproc *rproc_get_by_child(struct device *dev);
struct rproc *rproc_alloc(struct device *dev, const char *name, const struct rproc_ops *ops, const char *firmware, int len);void rproc_put(struct rproc *rproc);int rproc_add(struct rproc *rproc);int rproc_del(struct rproc *rproc);void rproc_free(struct rproc *rproc);void rproc_resource_cleanup(struct rproc *rproc);
struct rproc *devm_rproc_alloc(struct device *dev, const char *name, const struct rproc_ops *ops, const char *firmware, int len);int devm_rproc_add(struct device *dev, struct rproc *rproc);
void rproc_add_carveout(struct rproc *rproc, struct rproc_mem_entry *mem);
struct rproc_mem_entry *rproc_mem_entry_init(struct device *dev, void *va, dma_addr_t dma, size_t len, u32 da, int (*alloc)(struct rproc *, struct rproc_mem_entry *), int (*release)(struct rproc *, struct rproc_mem_entry *), const char *name, ...);
struct rproc_mem_entry *rproc_of_resm_mem_entry_init(struct device *dev, u32 of_resm_idx, size_t len, u32 da, const char *name, ...);
int rproc_boot(struct rproc *rproc);int rproc_shutdown(struct rproc *rproc);int rproc_detach(struct rproc *rproc);int rproc_set_firmware(struct rproc *rproc, const char *fw_name);void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type);void *rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem);
/* from remoteproc_coredump.c */void rproc_coredump_cleanup(struct rproc *rproc);void rproc_coredump(struct rproc *rproc);void rproc_coredump_using_sections(struct rproc *rproc);int rproc_coredump_add_segment(struct rproc *rproc, dma_addr_t da, size_t size);int rproc_coredump_add_custom_segment(struct rproc *rproc, dma_addr_t da, size_t size, void (*dumpfn)(struct rproc *rproc, struct rproc_dump_segment *segment, void *dest, size_t offset, size_t size), void *priv);int rproc_coredump_set_elf_info(struct rproc *rproc, u8 class, u16 machine);
void rproc_add_subdev(struct rproc *rproc, struct rproc_subdev *subdev);
void rproc_remove_subdev(struct rproc *rproc, struct rproc_subdev *subdev);
#endif /* REMOTEPROC_H */