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