xref: /linux/include/linux/rsc_table.h (revision 67f8bc848ee31831336bd478e57d2f993551902e)
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /*
3  * Copyright(c) 2011 Texas Instruments, Inc.
4  * Copyright(c) 2011 Google, Inc.
5  * All rights reserved.
6  */
7 
8 #ifndef RSC_TABLE_H
9 #define RSC_TABLE_H
10 
11 /**
12  * struct resource_table - firmware resource table header
13  * @ver: version number
14  * @num: number of resource entries
15  * @reserved: reserved (must be zero)
16  * @offset: array of offsets pointing at the various resource entries
17  *
18  * A resource table is essentially a list of system resources required
19  * by the remote processor. It may also include configuration entries.
20  * If needed, the remote processor firmware should contain this table
21  * as a dedicated ".resource_table" ELF section.
22  *
23  * Some resources entries are mere announcements, where the host is informed
24  * of specific remoteproc configuration. Other entries require the host to
25  * do something (e.g. allocate a system resource). Sometimes a negotiation
26  * is expected, where the firmware requests a resource, and once allocated,
27  * the host should provide back its details (e.g. address of an allocated
28  * memory region).
29  *
30  * The header of the resource table, as expressed by this structure,
31  * contains a version number (should we need to change this format in the
32  * future), the number of available resource entries, and their offsets
33  * in the table.
34  *
35  * Immediately following this header are the resource entries themselves,
36  * each of which begins with a resource entry header (as described below).
37  */
38 struct resource_table {
39 	u32 ver;
40 	u32 num;
41 	u32 reserved[2];
42 	u32 offset[];
43 } __packed;
44 
45 /**
46  * struct fw_rsc_hdr - firmware resource entry header
47  * @type: resource type
48  * @data: resource data
49  *
50  * Every resource entry begins with a 'struct fw_rsc_hdr' header providing
51  * its @type. The content of the entry itself will immediately follow
52  * this header, and it should be parsed according to the resource type.
53  */
54 struct fw_rsc_hdr {
55 	u32 type;
56 	u8 data[];
57 } __packed;
58 
59 /**
60  * enum fw_resource_type - types of resource entries
61  *
62  * @RSC_CARVEOUT:   request for allocation of a physically contiguous
63  *		    memory region.
64  * @RSC_DEVMEM:     request to iommu_map a memory-based peripheral.
65  * @RSC_TRACE:	    announces the availability of a trace buffer into which
66  *		    the remote processor will be writing logs.
67  * @RSC_VDEV:       declare support for a virtio device, and serve as its
68  *		    virtio header.
69  * @RSC_LAST:       just keep this one at the end of standard resources
70  * @RSC_VENDOR_START:	start of the vendor specific resource types range
71  * @RSC_VENDOR_END:	end of the vendor specific resource types range
72  *
73  * For more details regarding a specific resource type, please see its
74  * dedicated structure below.
75  *
76  * Please note that these values are used as indices to the rproc_handle_rsc
77  * lookup table, so please keep them sane. Moreover, @RSC_LAST is used to
78  * check the validity of an index before the lookup table is accessed, so
79  * please update it as needed.
80  */
81 enum fw_resource_type {
82 	RSC_CARVEOUT		= 0,
83 	RSC_DEVMEM		= 1,
84 	RSC_TRACE		= 2,
85 	RSC_VDEV		= 3,
86 	RSC_LAST		= 4,
87 	RSC_VENDOR_START	= 128,
88 	RSC_VENDOR_END		= 512,
89 };
90 
91 #define FW_RSC_ADDR_ANY (-1)
92 
93 /**
94  * struct fw_rsc_carveout - physically contiguous memory request
95  * @da: device address
96  * @pa: physical address
97  * @len: length (in bytes)
98  * @flags: iommu protection flags
99  * @reserved: reserved (must be zero)
100  * @name: human-readable name of the requested memory region
101  *
102  * This resource entry requests the host to allocate a physically contiguous
103  * memory region.
104  *
105  * These request entries should precede other firmware resource entries,
106  * as other entries might request placing other data objects inside
107  * these memory regions (e.g. data/code segments, trace resource entries, ...).
108  *
109  * Allocating memory this way helps utilizing the reserved physical memory
110  * (e.g. CMA) more efficiently, and also minimizes the number of TLB entries
111  * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB
112  * pressure is important; it may have a substantial impact on performance.
113  *
114  * If the firmware is compiled with static addresses, then @da should specify
115  * the expected device address of this memory region. If @da is set to
116  * FW_RSC_ADDR_ANY, then the host will dynamically allocate it, and then
117  * overwrite @da with the dynamically allocated address.
118  *
119  * We will always use @da to negotiate the device addresses, even if it
120  * isn't using an iommu. In that case, though, it will obviously contain
121  * physical addresses.
122  *
123  * Some remote processors needs to know the allocated physical address
124  * even if they do use an iommu. This is needed, e.g., if they control
125  * hardware accelerators which access the physical memory directly (this
126  * is the case with OMAP4 for instance). In that case, the host will
127  * overwrite @pa with the dynamically allocated physical address.
128  * Generally we don't want to expose physical addresses if we don't have to
129  * (remote processors are generally _not_ trusted), so we might want to
130  * change this to happen _only_ when explicitly required by the hardware.
131  *
132  * @flags is used to provide IOMMU protection flags, and @name should
133  * (optionally) contain a human readable name of this carveout region
134  * (mainly for debugging purposes).
135  */
136 struct fw_rsc_carveout {
137 	u32 da;
138 	u32 pa;
139 	u32 len;
140 	u32 flags;
141 	u32 reserved;
142 	u8 name[32];
143 } __packed;
144 
145 /**
146  * struct fw_rsc_devmem - iommu mapping request
147  * @da: device address
148  * @pa: physical address
149  * @len: length (in bytes)
150  * @flags: iommu protection flags
151  * @reserved: reserved (must be zero)
152  * @name: human-readable name of the requested region to be mapped
153  *
154  * This resource entry requests the host to iommu map a physically contiguous
155  * memory region. This is needed in case the remote processor requires
156  * access to certain memory-based peripherals; _never_ use it to access
157  * regular memory.
158  *
159  * This is obviously only needed if the remote processor is accessing memory
160  * via an iommu.
161  *
162  * @da should specify the required device address, @pa should specify
163  * the physical address we want to map, @len should specify the size of
164  * the mapping and @flags is the IOMMU protection flags. As always, @name may
165  * (optionally) contain a human readable name of this mapping (mainly for
166  * debugging purposes).
167  *
168  * Note: at this point we just "trust" those devmem entries to contain valid
169  * physical addresses, but this isn't safe and will be changed: eventually we
170  * want remoteproc implementations to provide us ranges of physical addresses
171  * the firmware is allowed to request, and not allow firmwares to request
172  * access to physical addresses that are outside those ranges.
173  */
174 struct fw_rsc_devmem {
175 	u32 da;
176 	u32 pa;
177 	u32 len;
178 	u32 flags;
179 	u32 reserved;
180 	u8 name[32];
181 } __packed;
182 
183 /**
184  * struct fw_rsc_trace - trace buffer declaration
185  * @da: device address
186  * @len: length (in bytes)
187  * @reserved: reserved (must be zero)
188  * @name: human-readable name of the trace buffer
189  *
190  * This resource entry provides the host information about a trace buffer
191  * into which the remote processor will write log messages.
192  *
193  * @da specifies the device address of the buffer, @len specifies
194  * its size, and @name may contain a human readable name of the trace buffer.
195  *
196  * After booting the remote processor, the trace buffers are exposed to the
197  * user via debugfs entries (called trace0, trace1, etc..).
198  */
199 struct fw_rsc_trace {
200 	u32 da;
201 	u32 len;
202 	u32 reserved;
203 	u8 name[32];
204 } __packed;
205 
206 /**
207  * struct fw_rsc_vdev_vring - vring descriptor entry
208  * @da: device address
209  * @align: the alignment between the consumer and producer parts of the vring
210  * @num: num of buffers supported by this vring (must be power of two)
211  * @notifyid: a unique rproc-wide notify index for this vring. This notify
212  * index is used when kicking a remote processor, to let it know that this
213  * vring is triggered.
214  * @pa: physical address
215  *
216  * This descriptor is not a resource entry by itself; it is part of the
217  * vdev resource type (see below).
218  *
219  * Note that @da should either contain the device address where
220  * the remote processor is expecting the vring, or indicate that
221  * dynamically allocation of the vring's device address is supported.
222  */
223 struct fw_rsc_vdev_vring {
224 	u32 da;
225 	u32 align;
226 	u32 num;
227 	u32 notifyid;
228 	u32 pa;
229 } __packed;
230 
231 /**
232  * struct fw_rsc_vdev - virtio device header
233  * @id: virtio device id (as in virtio_ids.h)
234  * @notifyid: a unique rproc-wide notify index for this vdev. This notify
235  * index is used when kicking a remote processor, to let it know that the
236  * status/features of this vdev have changes.
237  * @dfeatures: specifies the virtio device features supported by the firmware
238  * @gfeatures: a place holder used by the host to write back the
239  * negotiated features that are supported by both sides.
240  * @config_len: the size of the virtio config space of this vdev. The config
241  * space lies in the resource table immediate after this vdev header.
242  * @status: a place holder where the host will indicate its virtio progress.
243  * @num_of_vrings: indicates how many vrings are described in this vdev header
244  * @reserved: reserved (must be zero)
245  * @vring: an array of @num_of_vrings entries of 'struct fw_rsc_vdev_vring'.
246  *
247  * This resource is a virtio device header: it provides information about
248  * the vdev, and is then used by the host and its peer remote processors
249  * to negotiate and share certain virtio properties.
250  *
251  * By providing this resource entry, the firmware essentially asks remoteproc
252  * to statically allocate a vdev upon registration of the rproc (dynamic vdev
253  * allocation is not yet supported).
254  *
255  * Note:
256  * 1. unlike virtualization systems, the term 'host' here means
257  *    the Linux side which is running remoteproc to control the remote
258  *    processors. We use the name 'gfeatures' to comply with virtio's terms,
259  *    though there isn't really any virtualized guest OS here: it's the host
260  *    which is responsible for negotiating the final features.
261  *    Yeah, it's a bit confusing.
262  *
263  * 2. immediately following this structure is the virtio config space for
264  *    this vdev (which is specific to the vdev; for more info, read the virtio
265  *    spec). The size of the config space is specified by @config_len.
266  */
267 struct fw_rsc_vdev {
268 	u32 id;
269 	u32 notifyid;
270 	u32 dfeatures;
271 	u32 gfeatures;
272 	u32 config_len;
273 	u8 status;
274 	u8 num_of_vrings;
275 	u8 reserved[2];
276 	struct fw_rsc_vdev_vring vring[];
277 } __packed;
278 
279 /**
280  * rsc_table_for_each_entry() - iterate over all entries in a resource table
281  * @table:    pointer to the resource table
282  * @table_sz: total size of the table buffer in bytes
283  * @dev:      device used for error logging
284  * @cb:       callback invoked for each entry:
285  *              @type   - value from enum fw_resource_type
286  *              @rsc    - pointer to the entry payload (past struct fw_rsc_hdr)
287  *              @offset - byte offset of the payload within the table; callers
288  *                        that write back into the table (e.g. to record a
289  *                        dynamically allocated address) use this to locate the
290  *                        entry for later update
291  *              @avail  - bytes available in the payload
292  *              @data   - caller-supplied private pointer
293  *            Return 0 to continue iteration, non-zero to stop.
294  * @data:     private pointer forwarded to @cb on every call
295  *
296  * Iterates over every resource entry in @table, performing the standard
297  * truncation check, and invokes @cb for each one. Iteration stops on the
298  * first non-zero return from @cb or on a malformed table.
299  *
300  * Returns 0 after a complete iteration, -EINVAL if the table is truncated,
301  * or the first non-zero value returned by @cb.
302  */
303 static inline int rsc_table_for_each_entry(struct resource_table *table,
304 					   size_t table_sz,
305 					   struct device *dev,
306 					   int (*cb)(u32 type, void *rsc,
307 						     int offset, int avail,
308 						     void *data),
309 					   void *data) {
310 	int i, ret;
311 
312 	for (i = 0; i < table->num; i++) {
313 		u32 offset = table->offset[i];
314 		struct fw_rsc_hdr *hdr;
315 		int avail, rsc_offset;
316 		void *rsc;
317 
318 		if (offset < sizeof(*table) || offset >= table_sz ||
319 		    table_sz - offset < sizeof(*hdr)) {
320 			dev_err(dev, "rsc table is truncated\n");
321 			return -EINVAL;
322 		}
323 
324 		hdr = (void *)table + offset;
325 		avail = table_sz - offset - sizeof(*hdr);
326 		rsc_offset = offset + sizeof(*hdr);
327 		rsc = (void *)hdr + sizeof(*hdr);
328 
329 		ret = cb(hdr->type, rsc, rsc_offset, avail, data);
330 		if (ret)
331 			return ret;
332 	}
333 
334 	return 0;
335 }
336 
337 #endif /* RSC_TABLE_H */
338