aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOhad Ben-Cohen <ohad@wizery.com>2012-02-01 14:56:16 -0500
committerOhad Ben-Cohen <ohad@wizery.com>2012-03-06 12:13:39 -0500
commitfd2c15ec1dd3c2fdfc6ff03bb9644da9d530e3b9 (patch)
tree29e38853a3fac9e547a20fcb9f857c53ca7019b9
parent9d8ae5c22b73852e9b23ba4e520a64c29bbfc939 (diff)
remoteproc: resource table overhaul
The resource table is an array of 'struct fw_resource' members, where each resource entry is expressed as a single member of that array. This approach got us this far, but it has a few drawbacks: 1. Different resource entries end up overloading the same members of 'struct fw_resource' with different meanings. The resulting code is error prone and hard to read and maintain. 2. It's impossible to extend 'struct fw_resource' without breaking the existing firmware images (and we already want to: we can't introduce the new virito device resource entry with the current scheme). 3. It doesn't scale: 'struct fw_resource' must be as big as the largest resource entry type. As a result, smaller resource entries end up utilizing only small part of it. This is fixed by defining a dedicated structure for every resource type, and then converting the resource table to a list of type-value members. Instead of a rigid array of homogeneous structs, the resource table is turned into a collection of heterogeneous structures. This way: 1. Resource entries consume exactly the amount of bytes they need. 2. It's easy to extend: just create a new resource entry structure, and assign it a new type. 3. The code is easier to read and maintain: the structures' members names are meaningful. While we're at it, this patch has several other resource table changes: 1. The resource table gains a simple header which contains the number of entries in the table and their offsets within the table. This makes the parsing code simpler and easier to read. 2. A version member is added to the resource table. Should we change the format again, we'll bump up this version to prevent breakage with existing firmware images. 3. The VRING and VIRTIO_DEV resource entries are combined to a single VDEV entry. This paves the way to supporting multiple VDEV entries. 4. Since we don't really support 64-bit rprocs yet, convert two stray u64 members to u32. Signed-off-by: Ohad Ben-Cohen <ohad@wizery.com> Cc: Brian Swetland <swetland@google.com> Cc: Iliyan Malchev <malchev@google.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Grant Likely <grant.likely@secretlab.ca> Cc: Rusty Russell <rusty@rustcorp.com.au> Cc: Mark Grosen <mgrosen@ti.com> Cc: John Williams <john.williams@petalogix.com> Cc: Michal Simek <monstr@monstr.eu> Cc: Loic PALLARDY <loic.pallardy@stericsson.com> Cc: Ludovic BARRE <ludovic.barre@stericsson.com> Cc: Omar Ramirez Luna <omar.luna@linaro.org> Cc: Guzman Lugo Fernando <fernando.lugo@ti.com> Cc: Anna Suman <s-anna@ti.com> Cc: Clark Rob <rob@ti.com> Cc: Stephen Boyd <sboyd@codeaurora.org> Cc: Saravana Kannan <skannan@codeaurora.org> Cc: David Brown <davidb@codeaurora.org> Cc: Kieran Bingham <kieranbingham@gmail.com> Cc: Tony Lindgren <tony@atomide.com>
-rw-r--r--Documentation/remoteproc.txt127
-rw-r--r--drivers/remoteproc/remoteproc_core.c306
-rw-r--r--include/linux/remoteproc.h289
3 files changed, 505 insertions, 217 deletions
diff --git a/Documentation/remoteproc.txt b/Documentation/remoteproc.txt
index 23ff7349ffe7..07057cacfeae 100644
--- a/Documentation/remoteproc.txt
+++ b/Documentation/remoteproc.txt
@@ -221,43 +221,52 @@ resource entries that publish the existence of supported features
221or configurations by the remote processor, such as trace buffers and 221or configurations by the remote processor, such as trace buffers and
222supported virtio devices (and their configurations). 222supported virtio devices (and their configurations).
223 223
224Currently the resource table is just an array of: 224The resource table begins with this header:
225 225
226/** 226/**
227 * struct fw_resource - describes an entry from the resource section 227 * struct resource_table - firmware resource table header
228 * @ver: version number
229 * @num: number of resource entries
230 * @reserved: reserved (must be zero)
231 * @offset: array of offsets pointing at the various resource entries
232 *
233 * The header of the resource table, as expressed by this structure,
234 * contains a version number (should we need to change this format in the
235 * future), the number of available resource entries, and their offsets
236 * in the table.
237 */
238struct resource_table {
239 u32 ver;
240 u32 num;
241 u32 reserved[2];
242 u32 offset[0];
243} __packed;
244
245Immediately following this header are the resource entries themselves,
246each of which begins with the following resource entry header:
247
248/**
249 * struct fw_rsc_hdr - firmware resource entry header
228 * @type: resource type 250 * @type: resource type
229 * @id: index number of the resource 251 * @data: resource data
230 * @da: device address of the resource 252 *
231 * @pa: physical address of the resource 253 * Every resource entry begins with a 'struct fw_rsc_hdr' header providing
232 * @len: size, in bytes, of the resource 254 * its @type. The content of the entry itself will immediately follow
233 * @flags: properties of the resource, e.g. iommu protection required 255 * this header, and it should be parsed according to the resource type.
234 * @reserved: must be 0 atm
235 * @name: name of resource
236 */ 256 */
237struct fw_resource { 257struct fw_rsc_hdr {
238 u32 type; 258 u32 type;
239 u32 id; 259 u8 data[0];
240 u64 da;
241 u64 pa;
242 u32 len;
243 u32 flags;
244 u8 reserved[16];
245 u8 name[48];
246} __packed; 260} __packed;
247 261
248Some resources entries are mere announcements, where the host is informed 262Some resources entries are mere announcements, where the host is informed
249of specific remoteproc configuration. Other entries require the host to 263of specific remoteproc configuration. Other entries require the host to
250do something (e.g. reserve a requested resource) and possibly also reply 264do something (e.g. allocate a system resource). Sometimes a negotiation
251by overwriting a member inside 'struct fw_resource' with info about the 265is expected, where the firmware requests a resource, and once allocated,
252allocated resource. 266the host should provide back its details (e.g. address of an allocated
253 267memory region).
254Different resource entries use different members of this struct,
255with different meanings. This is pretty limiting and error-prone,
256so the plan is to move to variable-length TLV-based resource entries,
257where each resource will begin with a type and length fields, followed by
258its own specific structure.
259 268
260Here are the resource types that are currently being used: 269Here are the various resource types that are currently supported:
261 270
262/** 271/**
263 * enum fw_resource_type - types of resource entries 272 * enum fw_resource_type - types of resource entries
@@ -266,59 +275,45 @@ Here are the resource types that are currently being used:
266 * memory region. 275 * memory region.
267 * @RSC_DEVMEM: request to iommu_map a memory-based peripheral. 276 * @RSC_DEVMEM: request to iommu_map a memory-based peripheral.
268 * @RSC_TRACE: announces the availability of a trace buffer into which 277 * @RSC_TRACE: announces the availability of a trace buffer into which
269 * the remote processor will be writing logs. In this case, 278 * the remote processor will be writing logs.
270 * 'da' indicates the device address where logs are written to, 279 * @RSC_VDEV: declare support for a virtio device, and serve as its
271 * and 'len' is the size of the trace buffer. 280 * virtio header.
272 * @RSC_VRING: request for allocation of a virtio vring (address should 281 * @RSC_LAST: just keep this one at the end
273 * be indicated in 'da', and 'len' should contain the number 282 *
274 * of buffers supported by the vring). 283 * Please note that these values are used as indices to the rproc_handle_rsc
275 * @RSC_VIRTIO_DEV: announces support for a virtio device, and serves as 284 * lookup table, so please keep them sane. Moreover, @RSC_LAST is used to
276 * the virtio header. 'da' contains the virtio device 285 * check the validity of an index before the lookup table is accessed, so
277 * features, 'pa' holds the virtio guest features (host 286 * please update it as needed.
278 * will write them here after they're negotiated), 'len'
279 * holds the virtio status, and 'flags' holds the virtio
280 * device id (currently only VIRTIO_ID_RPMSG is supported).
281 */ 287 */
282enum fw_resource_type { 288enum fw_resource_type {
283 RSC_CARVEOUT = 0, 289 RSC_CARVEOUT = 0,
284 RSC_DEVMEM = 1, 290 RSC_DEVMEM = 1,
285 RSC_TRACE = 2, 291 RSC_TRACE = 2,
286 RSC_VRING = 3, 292 RSC_VDEV = 3,
287 RSC_VIRTIO_DEV = 4, 293 RSC_LAST = 4,
288 RSC_VIRTIO_CFG = 5,
289}; 294};
290 295
291Most of the resource entries share the basic idea of address/length 296For more details regarding a specific resource type, please see its
292negotiation with the host: the firmware usually asks for memory 297dedicated structure in include/linux/remoteproc.h.
293of size 'len' bytes, and the host needs to allocate it and provide
294the device/physical address (when relevant) in 'da'/'pa' respectively.
295
296If the firmware is compiled with hard coded device addresses, and
297can't handle dynamically allocated 'da' values, then the 'da' field
298will contain the expected device addresses (today we actually only support
299this scheme, as there aren't yet any use cases for dynamically allocated
300device addresses).
301 298
302We also expect that platform-specific resource entries will show up 299We also expect that platform-specific resource entries will show up
303at some point. When that happens, we could easily add a new RSC_PLAFORM 300at some point. When that happens, we could easily add a new RSC_PLATFORM
304type, and hand those resources to the platform-specific rproc driver to handle. 301type, and hand those resources to the platform-specific rproc driver to handle.
305 302
3067. Virtio and remoteproc 3037. Virtio and remoteproc
307 304
308The firmware should provide remoteproc information about virtio devices 305The firmware should provide remoteproc information about virtio devices
309that it supports, and their configurations: a RSC_VIRTIO_DEV resource entry 306that it supports, and their configurations: a RSC_VDEV resource entry
310should specify the virtio device id, and subsequent RSC_VRING resource entries 307should specify the virtio device id (as in virtio_ids.h), virtio features,
311should indicate the vring size (i.e. how many buffers do they support) and 308virtio config space, vrings information, etc.
312where should they be mapped (i.e. which device address). Note: the alignment 309
313between the consumer and producer parts of the vring is assumed to be 4096. 310When a new remote processor is registered, the remoteproc framework
314 311will look for its resource table and will register the virtio devices
315At this point we only support a single virtio rpmsg device per remote 312it supports. A firmware may support any number of virtio devices, and
316processor, but the plan is to remove this limitation. In addition, once we 313of any type (a single remote processor can also easily support several
317move to TLV-based resource table, the plan is to have a single RSC_VIRTIO 314rpmsg virtio devices this way, if desired).
318entry per supported virtio device, which will include the virtio header, 315
319the vrings information and the virtio config space. 316Of course, RSC_VDEV resource entries are only good enough for static
320
321Of course, RSC_VIRTIO resource entries are only good enough for static
322allocation of virtio devices. Dynamic allocations will also be made possible 317allocation of virtio devices. Dynamic allocations will also be made possible
323using the rpmsg bus (similar to how we already do dynamic allocations of 318using the rpmsg bus (similar to how we already do dynamic allocations of
324rpmsg channels; read more about it in rpmsg.txt). 319rpmsg channels; read more about it in rpmsg.txt).
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 8990c51c16f0..10348451c6c9 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -63,9 +63,8 @@ static void klist_rproc_put(struct klist_node *n);
63static DEFINE_KLIST(rprocs, klist_rproc_get, klist_rproc_put); 63static DEFINE_KLIST(rprocs, klist_rproc_get, klist_rproc_put);
64 64
65typedef int (*rproc_handle_resources_t)(struct rproc *rproc, 65typedef int (*rproc_handle_resources_t)(struct rproc *rproc,
66 struct fw_resource *rsc, int len); 66 struct resource_table *table, int len);
67typedef int (*rproc_handle_resource_t)(struct rproc *rproc, 67typedef int (*rproc_handle_resource_t)(struct rproc *rproc, void *, int avail);
68 struct fw_resource *rsc);
69 68
70/* 69/*
71 * This is the IOMMU fault handler we register with the IOMMU API 70 * This is the IOMMU fault handler we register with the IOMMU API
@@ -281,9 +280,10 @@ rproc_load_segments(struct rproc *rproc, const u8 *elf_data, size_t len)
281} 280}
282 281
283/** 282/**
284 * rproc_handle_virtio_hdr() - handle a virtio header resource 283 * rproc_handle_early_vdev() - early handle a virtio header resource
285 * @rproc: the remote processor 284 * @rproc: the remote processor
286 * @rsc: the resource descriptor 285 * @rsc: the resource descriptor
286 * @avail: size of available data (for sanity checking the image)
287 * 287 *
288 * The existence of this virtio hdr resource entry means that the firmware 288 * The existence of this virtio hdr resource entry means that the firmware
289 * of this @rproc supports this virtio device. 289 * of this @rproc supports this virtio device.
@@ -291,37 +291,32 @@ rproc_load_segments(struct rproc *rproc, const u8 *elf_data, size_t len)
291 * Currently we support only a single virtio device of type VIRTIO_ID_RPMSG, 291 * Currently we support only a single virtio device of type VIRTIO_ID_RPMSG,
292 * but the plan is to remove this limitation and support any number 292 * but the plan is to remove this limitation and support any number
293 * of virtio devices (and of any type). We'll also add support for dynamically 293 * of virtio devices (and of any type). We'll also add support for dynamically
294 * adding (and removing) virtio devices over the rpmsg bus, but small 294 * adding (and removing) virtio devices over the rpmsg bus, but simple
295 * firmwares that doesn't want to get involved with rpmsg will be able 295 * firmwares that doesn't want to get involved with rpmsg will be able
296 * to simple use the resource table for this. 296 * to simply use the resource table for this.
297 *
298 * At this point this virtio header entry is rather simple: it just
299 * announces the virtio device id and the supported virtio device features.
300 * The plan though is to extend this to include the vring information and
301 * the virtio config space, too (but first, some resource table overhaul
302 * is needed: move from fixed-sized to variable-length TLV entries).
303 *
304 * For now, the 'flags' member of the resource entry contains the virtio
305 * device id, the 'da' member contains the device features, and 'pa' is
306 * where we need to store the guest features once negotiation completes.
307 * As usual, the 'id' member of this resource contains the index of this
308 * resource type (i.e. is this the first virtio hdr entry, the 2nd, ...).
309 * 297 *
310 * Returns 0 on success, or an appropriate error code otherwise 298 * Returns 0 on success, or an appropriate error code otherwise
311 */ 299 */
312static int rproc_handle_virtio_hdr(struct rproc *rproc, struct fw_resource *rsc) 300static int rproc_handle_early_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc,
301 int avail)
313{ 302{
314 struct rproc_vdev *rvdev; 303 struct rproc_vdev *rvdev;
315 304
305 /* make sure resource isn't truncated */
306 if (sizeof(*rsc) > avail) {
307 dev_err(rproc->dev, "vdev rsc is truncated\n");
308 return -EINVAL;
309 }
310
316 /* we only support VIRTIO_ID_RPMSG devices for now */ 311 /* we only support VIRTIO_ID_RPMSG devices for now */
317 if (rsc->flags != VIRTIO_ID_RPMSG) { 312 if (rsc->id != VIRTIO_ID_RPMSG) {
318 dev_warn(rproc->dev, "unsupported vdev: %d\n", rsc->flags); 313 dev_warn(rproc->dev, "unsupported vdev: %d\n", rsc->id);
319 return -EINVAL; 314 return -EINVAL;
320 } 315 }
321 316
322 /* we only support a single vdev per rproc for now */ 317 /* we only support a single vdev per rproc for now */
323 if (rsc->id || rproc->rvdev) { 318 if (rproc->rvdev) {
324 dev_warn(rproc->dev, "redundant vdev entry: %s\n", rsc->name); 319 dev_warn(rproc->dev, "redundant vdev entry\n");
325 return -EINVAL; 320 return -EINVAL;
326 } 321 }
327 322
@@ -330,7 +325,7 @@ static int rproc_handle_virtio_hdr(struct rproc *rproc, struct fw_resource *rsc)
330 return -ENOMEM; 325 return -ENOMEM;
331 326
332 /* remember the device features */ 327 /* remember the device features */
333 rvdev->dfeatures = rsc->da; 328 rvdev->dfeatures = rsc->dfeatures;
334 329
335 rproc->rvdev = rvdev; 330 rproc->rvdev = rvdev;
336 rvdev->rproc = rproc; 331 rvdev->rproc = rproc;
@@ -339,9 +334,10 @@ static int rproc_handle_virtio_hdr(struct rproc *rproc, struct fw_resource *rsc)
339} 334}
340 335
341/** 336/**
342 * rproc_handle_vring() - handle a vring fw resource 337 * rproc_handle_vdev() - handle a vdev fw resource
343 * @rproc: the remote processor 338 * @rproc: the remote processor
344 * @rsc: the vring resource descriptor 339 * @rsc: the vring resource descriptor
340 * @avail: size of available data (for sanity checking the image)
345 * 341 *
346 * This resource entry requires allocation of non-cacheable memory 342 * This resource entry requires allocation of non-cacheable memory
347 * for a virtio vring. Currently we only support two vrings per remote 343 * for a virtio vring. Currently we only support two vrings per remote
@@ -360,57 +356,82 @@ static int rproc_handle_virtio_hdr(struct rproc *rproc, struct fw_resource *rsc)
360 * 356 *
361 * Returns 0 on success, or an appropriate error code otherwise 357 * Returns 0 on success, or an appropriate error code otherwise
362 */ 358 */
363static int rproc_handle_vring(struct rproc *rproc, struct fw_resource *rsc) 359static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc,
360 int avail)
364{ 361{
365 struct device *dev = rproc->dev; 362 struct device *dev = rproc->dev;
366 struct rproc_vdev *rvdev = rproc->rvdev; 363 struct rproc_vdev *rvdev = rproc->rvdev;
367 dma_addr_t dma; 364 int i;
368 int size, id = rsc->id;
369 void *va;
370 365
371 /* no vdev is in place ? */ 366 /* make sure resource isn't truncated */
372 if (!rvdev) { 367 if (sizeof(*rsc) + rsc->num_of_vrings * sizeof(struct fw_rsc_vdev_vring)
373 dev_err(dev, "vring requested without a virtio dev entry\n"); 368 + rsc->config_len > avail) {
369 dev_err(rproc->dev, "vdev rsc is truncated\n");
374 return -EINVAL; 370 return -EINVAL;
375 } 371 }
376 372
377 /* the firmware must provide the expected queue size */ 373 /* make sure reserved bytes are zeroes */
378 if (!rsc->len) { 374 if (rsc->reserved[0] || rsc->reserved[1]) {
379 dev_err(dev, "missing expected queue size\n"); 375 dev_err(dev, "vdev rsc has non zero reserved bytes\n");
380 return -EINVAL; 376 return -EINVAL;
381 } 377 }
382 378
383 /* we currently support two vrings per rproc (for rx and tx) */ 379 dev_dbg(dev, "vdev rsc: id %d, dfeatures %x, cfg len %d, %d vrings\n",
384 if (id >= ARRAY_SIZE(rvdev->vring)) { 380 rsc->id, rsc->dfeatures, rsc->config_len, rsc->num_of_vrings);
385 dev_err(dev, "%s: invalid vring id %d\n", rsc->name, id); 381
382 /* no vdev is in place ? */
383 if (!rvdev) {
384 dev_err(dev, "vring requested without a virtio dev entry\n");
386 return -EINVAL; 385 return -EINVAL;
387 } 386 }
388 387
389 /* have we already allocated this vring id ? */ 388 /* we currently support two vrings per rproc (for rx and tx) */
390 if (rvdev->vring[id].len) { 389 if (rsc->num_of_vrings != ARRAY_SIZE(rvdev->vring)) {
391 dev_err(dev, "%s: duplicated id %d\n", rsc->name, id); 390 dev_err(dev, "too many vrings: %d\n", rsc->num_of_vrings);
392 return -EINVAL; 391 return -EINVAL;
393 } 392 }
394 393
395 /* actual size of vring (in bytes) */ 394 /* initialize the vrings */
396 size = PAGE_ALIGN(vring_size(rsc->len, AMP_VRING_ALIGN)); 395 for (i = 0; i < rsc->num_of_vrings; i++) {
396 struct fw_rsc_vdev_vring *vring = &rsc->vring[i];
397 dma_addr_t dma;
398 int size;
399 void *va;
400
401 /* make sure reserved bytes are zeroes */
402 if (vring->reserved) {
403 dev_err(dev, "vring rsc has non zero reserved bytes\n");
404 return -EINVAL;
405 }
397 406
398 /* 407 /* the firmware must provide the expected queue size */
399 * Allocate non-cacheable memory for the vring. In the future 408 if (!vring->num) {
400 * this call will also configure the IOMMU for us 409 dev_err(dev, "missing expected queue size\n");
401 */ 410 /* potential cleanups are taken care of later on */
402 va = dma_alloc_coherent(dev, size, &dma, GFP_KERNEL); 411 return -EINVAL;
403 if (!va) { 412 }
404 dev_err(dev, "dma_alloc_coherent failed\n");
405 return -ENOMEM;
406 }
407 413
408 dev_dbg(dev, "vring%d: va %p dma %x qsz %d ring size %x\n", id, va, 414 /* actual size of vring (in bytes) */
409 dma, rsc->len, size); 415 size = PAGE_ALIGN(vring_size(vring->num, AMP_VRING_ALIGN));
410 416
411 rvdev->vring[id].len = rsc->len; 417 /*
412 rvdev->vring[id].va = va; 418 * Allocate non-cacheable memory for the vring. In the future
413 rvdev->vring[id].dma = dma; 419 * this call will also configure the IOMMU for us
420 */
421 va = dma_alloc_coherent(dev, size, &dma, GFP_KERNEL);
422 if (!va) {
423 dev_err(dev, "dma_alloc_coherent failed\n");
424 /* potential cleanups are taken care of later on */
425 return -EINVAL;
426 }
427
428 dev_dbg(dev, "vring%d: va %p dma %x qsz %d ring size %x\n", i,
429 va, dma, vring->num, size);
430
431 rvdev->vring[i].len = vring->num;
432 rvdev->vring[i].va = va;
433 rvdev->vring[i].dma = dma;
434 }
414 435
415 return 0; 436 return 0;
416} 437}
@@ -419,6 +440,7 @@ static int rproc_handle_vring(struct rproc *rproc, struct fw_resource *rsc)
419 * rproc_handle_trace() - handle a shared trace buffer resource 440 * rproc_handle_trace() - handle a shared trace buffer resource
420 * @rproc: the remote processor 441 * @rproc: the remote processor
421 * @rsc: the trace resource descriptor 442 * @rsc: the trace resource descriptor
443 * @avail: size of available data (for sanity checking the image)
422 * 444 *
423 * In case the remote processor dumps trace logs into memory, 445 * In case the remote processor dumps trace logs into memory,
424 * export it via debugfs. 446 * export it via debugfs.
@@ -430,13 +452,25 @@ static int rproc_handle_vring(struct rproc *rproc, struct fw_resource *rsc)
430 * 452 *
431 * Returns 0 on success, or an appropriate error code otherwise 453 * Returns 0 on success, or an appropriate error code otherwise
432 */ 454 */
433static int rproc_handle_trace(struct rproc *rproc, struct fw_resource *rsc) 455static int rproc_handle_trace(struct rproc *rproc, struct fw_rsc_trace *rsc,
456 int avail)
434{ 457{
435 struct rproc_mem_entry *trace; 458 struct rproc_mem_entry *trace;
436 struct device *dev = rproc->dev; 459 struct device *dev = rproc->dev;
437 void *ptr; 460 void *ptr;
438 char name[15]; 461 char name[15];
439 462
463 if (sizeof(*rsc) > avail) {
464 dev_err(rproc->dev, "trace rsc is truncated\n");
465 return -EINVAL;
466 }
467
468 /* make sure reserved bytes are zeroes */
469 if (rsc->reserved) {
470 dev_err(dev, "trace rsc has non zero reserved bytes\n");
471 return -EINVAL;
472 }
473
440 /* what's the kernel address of this resource ? */ 474 /* what's the kernel address of this resource ? */
441 ptr = rproc_da_to_va(rproc, rsc->da, rsc->len); 475 ptr = rproc_da_to_va(rproc, rsc->da, rsc->len);
442 if (!ptr) { 476 if (!ptr) {
@@ -469,7 +503,7 @@ static int rproc_handle_trace(struct rproc *rproc, struct fw_resource *rsc)
469 503
470 rproc->num_traces++; 504 rproc->num_traces++;
471 505
472 dev_dbg(dev, "%s added: va %p, da 0x%llx, len 0x%x\n", name, ptr, 506 dev_dbg(dev, "%s added: va %p, da 0x%x, len 0x%x\n", name, ptr,
473 rsc->da, rsc->len); 507 rsc->da, rsc->len);
474 508
475 return 0; 509 return 0;
@@ -479,6 +513,7 @@ static int rproc_handle_trace(struct rproc *rproc, struct fw_resource *rsc)
479 * rproc_handle_devmem() - handle devmem resource entry 513 * rproc_handle_devmem() - handle devmem resource entry
480 * @rproc: remote processor handle 514 * @rproc: remote processor handle
481 * @rsc: the devmem resource entry 515 * @rsc: the devmem resource entry
516 * @avail: size of available data (for sanity checking the image)
482 * 517 *
483 * Remote processors commonly need to access certain on-chip peripherals. 518 * Remote processors commonly need to access certain on-chip peripherals.
484 * 519 *
@@ -499,7 +534,8 @@ static int rproc_handle_trace(struct rproc *rproc, struct fw_resource *rsc)
499 * and not allow firmwares to request access to physical addresses that 534 * and not allow firmwares to request access to physical addresses that
500 * are outside those ranges. 535 * are outside those ranges.
501 */ 536 */
502static int rproc_handle_devmem(struct rproc *rproc, struct fw_resource *rsc) 537static int rproc_handle_devmem(struct rproc *rproc, struct fw_rsc_devmem *rsc,
538 int avail)
503{ 539{
504 struct rproc_mem_entry *mapping; 540 struct rproc_mem_entry *mapping;
505 int ret; 541 int ret;
@@ -508,6 +544,17 @@ static int rproc_handle_devmem(struct rproc *rproc, struct fw_resource *rsc)
508 if (!rproc->domain) 544 if (!rproc->domain)
509 return -EINVAL; 545 return -EINVAL;
510 546
547 if (sizeof(*rsc) > avail) {
548 dev_err(rproc->dev, "devmem rsc is truncated\n");
549 return -EINVAL;
550 }
551
552 /* make sure reserved bytes are zeroes */
553 if (rsc->reserved) {
554 dev_err(rproc->dev, "devmem rsc has non zero reserved bytes\n");
555 return -EINVAL;
556 }
557
511 mapping = kzalloc(sizeof(*mapping), GFP_KERNEL); 558 mapping = kzalloc(sizeof(*mapping), GFP_KERNEL);
512 if (!mapping) { 559 if (!mapping) {
513 dev_err(rproc->dev, "kzalloc mapping failed\n"); 560 dev_err(rproc->dev, "kzalloc mapping failed\n");
@@ -531,7 +578,7 @@ static int rproc_handle_devmem(struct rproc *rproc, struct fw_resource *rsc)
531 mapping->len = rsc->len; 578 mapping->len = rsc->len;
532 list_add_tail(&mapping->node, &rproc->mappings); 579 list_add_tail(&mapping->node, &rproc->mappings);
533 580
534 dev_dbg(rproc->dev, "mapped devmem pa 0x%llx, da 0x%llx, len 0x%x\n", 581 dev_dbg(rproc->dev, "mapped devmem pa 0x%x, da 0x%x, len 0x%x\n",
535 rsc->pa, rsc->da, rsc->len); 582 rsc->pa, rsc->da, rsc->len);
536 583
537 return 0; 584 return 0;
@@ -545,6 +592,7 @@ out:
545 * rproc_handle_carveout() - handle phys contig memory allocation requests 592 * rproc_handle_carveout() - handle phys contig memory allocation requests
546 * @rproc: rproc handle 593 * @rproc: rproc handle
547 * @rsc: the resource entry 594 * @rsc: the resource entry
595 * @avail: size of available data (for image validation)
548 * 596 *
549 * This function will handle firmware requests for allocation of physically 597 * This function will handle firmware requests for allocation of physically
550 * contiguous memory regions. 598 * contiguous memory regions.
@@ -558,7 +606,8 @@ out:
558 * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB 606 * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB
559 * pressure is important; it may have a substantial impact on performance. 607 * pressure is important; it may have a substantial impact on performance.
560 */ 608 */
561static int rproc_handle_carveout(struct rproc *rproc, struct fw_resource *rsc) 609static int rproc_handle_carveout(struct rproc *rproc,
610 struct fw_rsc_carveout *rsc, int avail)
562{ 611{
563 struct rproc_mem_entry *carveout, *mapping; 612 struct rproc_mem_entry *carveout, *mapping;
564 struct device *dev = rproc->dev; 613 struct device *dev = rproc->dev;
@@ -566,6 +615,20 @@ static int rproc_handle_carveout(struct rproc *rproc, struct fw_resource *rsc)
566 void *va; 615 void *va;
567 int ret; 616 int ret;
568 617
618 if (sizeof(*rsc) > avail) {
619 dev_err(rproc->dev, "carveout rsc is truncated\n");
620 return -EINVAL;
621 }
622
623 /* make sure reserved bytes are zeroes */
624 if (rsc->reserved) {
625 dev_err(dev, "carveout rsc has non zero reserved bytes\n");
626 return -EINVAL;
627 }
628
629 dev_dbg(dev, "carveout rsc: da %x, pa %x, len %x, flags %x\n",
630 rsc->da, rsc->pa, rsc->len, rsc->flags);
631
569 mapping = kzalloc(sizeof(*mapping), GFP_KERNEL); 632 mapping = kzalloc(sizeof(*mapping), GFP_KERNEL);
570 if (!mapping) { 633 if (!mapping) {
571 dev_err(dev, "kzalloc mapping failed\n"); 634 dev_err(dev, "kzalloc mapping failed\n");
@@ -624,7 +687,7 @@ static int rproc_handle_carveout(struct rproc *rproc, struct fw_resource *rsc)
624 mapping->len = rsc->len; 687 mapping->len = rsc->len;
625 list_add_tail(&mapping->node, &rproc->mappings); 688 list_add_tail(&mapping->node, &rproc->mappings);
626 689
627 dev_dbg(dev, "carveout mapped 0x%llx to 0x%x\n", rsc->da, dma); 690 dev_dbg(dev, "carveout mapped 0x%x to 0x%x\n", rsc->da, dma);
628 691
629 /* 692 /*
630 * Some remote processors might need to know the pa 693 * Some remote processors might need to know the pa
@@ -665,36 +728,44 @@ free_mapping:
665 * enum fw_resource_type. 728 * enum fw_resource_type.
666 */ 729 */
667static rproc_handle_resource_t rproc_handle_rsc[] = { 730static rproc_handle_resource_t rproc_handle_rsc[] = {
668 [RSC_CARVEOUT] = rproc_handle_carveout, 731 [RSC_CARVEOUT] = (rproc_handle_resource_t)rproc_handle_carveout,
669 [RSC_DEVMEM] = rproc_handle_devmem, 732 [RSC_DEVMEM] = (rproc_handle_resource_t)rproc_handle_devmem,
670 [RSC_TRACE] = rproc_handle_trace, 733 [RSC_TRACE] = (rproc_handle_resource_t)rproc_handle_trace,
671 [RSC_VRING] = rproc_handle_vring, 734 [RSC_VDEV] = (rproc_handle_resource_t)rproc_handle_vdev,
672 [RSC_VIRTIO_DEV] = NULL, /* handled early upon registration */
673}; 735};
674 736
675/* handle firmware resource entries before booting the remote processor */ 737/* handle firmware resource entries before booting the remote processor */
676static int 738static int
677rproc_handle_boot_rsc(struct rproc *rproc, struct fw_resource *rsc, int len) 739rproc_handle_boot_rsc(struct rproc *rproc, struct resource_table *table, int len)
678{ 740{
679 struct device *dev = rproc->dev; 741 struct device *dev = rproc->dev;
680 rproc_handle_resource_t handler; 742 rproc_handle_resource_t handler;
681 int ret = 0; 743 int ret = 0, i;
744
745 for (i = 0; i < table->num; i++) {
746 int offset = table->offset[i];
747 struct fw_rsc_hdr *hdr = (void *)table + offset;
748 int avail = len - offset - sizeof(*hdr);
749 void *rsc = (void *)hdr + sizeof(*hdr);
750
751 /* make sure table isn't truncated */
752 if (avail < 0) {
753 dev_err(dev, "rsc table is truncated\n");
754 return -EINVAL;
755 }
682 756
683 for (; len >= sizeof(*rsc); rsc++, len -= sizeof(*rsc)) { 757 dev_dbg(dev, "rsc: type %d\n", hdr->type);
684 dev_dbg(dev, "rsc: type %d, da 0x%llx, pa 0x%llx, len 0x%x, "
685 "id %d, name %s, flags %x\n", rsc->type, rsc->da,
686 rsc->pa, rsc->len, rsc->id, rsc->name, rsc->flags);
687 758
688 if (rsc->type >= RSC_LAST) { 759 if (hdr->type >= RSC_LAST) {
689 dev_warn(dev, "unsupported resource %d\n", rsc->type); 760 dev_warn(dev, "unsupported resource %d\n", hdr->type);
690 continue; 761 continue;
691 } 762 }
692 763
693 handler = rproc_handle_rsc[rsc->type]; 764 handler = rproc_handle_rsc[hdr->type];
694 if (!handler) 765 if (!handler)
695 continue; 766 continue;
696 767
697 ret = handler(rproc, rsc); 768 ret = handler(rproc, rsc, avail);
698 if (ret) 769 if (ret)
699 break; 770 break;
700 } 771 }
@@ -704,18 +775,31 @@ rproc_handle_boot_rsc(struct rproc *rproc, struct fw_resource *rsc, int len)
704 775
705/* handle firmware resource entries while registering the remote processor */ 776/* handle firmware resource entries while registering the remote processor */
706static int 777static int
707rproc_handle_virtio_rsc(struct rproc *rproc, struct fw_resource *rsc, int len) 778rproc_handle_virtio_rsc(struct rproc *rproc, struct resource_table *table, int len)
708{ 779{
709 struct device *dev = rproc->dev; 780 struct device *dev = rproc->dev;
710 int ret = -ENODEV; 781 int ret = 0, i;
782
783 for (i = 0; i < table->num; i++) {
784 int offset = table->offset[i];
785 struct fw_rsc_hdr *hdr = (void *)table + offset;
786 int avail = len - offset - sizeof(*hdr);
711 787
712 for (; len >= sizeof(*rsc); rsc++, len -= sizeof(*rsc)) 788 /* make sure table isn't truncated */
713 if (rsc->type == RSC_VIRTIO_DEV) { 789 if (avail < 0) {
714 dev_dbg(dev, "found vdev %d/%s features %llx\n", 790 dev_err(dev, "rsc table is truncated\n");
715 rsc->flags, rsc->name, rsc->da); 791 return -EINVAL;
716 ret = rproc_handle_virtio_hdr(rproc, rsc); 792 }
793
794 dev_dbg(dev, "%s: rsc type %d\n", __func__, hdr->type);
795
796 if (hdr->type == RSC_VDEV) {
797 struct fw_rsc_vdev *vrsc =
798 (struct fw_rsc_vdev *)hdr->data;
799 ret = rproc_handle_early_vdev(rproc, vrsc, avail);
717 break; 800 break;
718 } 801 }
802 }
719 803
720 return ret; 804 return ret;
721} 805}
@@ -744,7 +828,9 @@ static int rproc_handle_resources(struct rproc *rproc, const u8 *elf_data,
744 struct elf32_hdr *ehdr; 828 struct elf32_hdr *ehdr;
745 struct elf32_shdr *shdr; 829 struct elf32_shdr *shdr;
746 const char *name_table; 830 const char *name_table;
831 struct device *dev = rproc->dev;
747 int i, ret = -EINVAL; 832 int i, ret = -EINVAL;
833 struct resource_table *table;
748 834
749 ehdr = (struct elf32_hdr *)elf_data; 835 ehdr = (struct elf32_hdr *)elf_data;
750 shdr = (struct elf32_shdr *)(elf_data + ehdr->e_shoff); 836 shdr = (struct elf32_shdr *)(elf_data + ehdr->e_shoff);
@@ -752,21 +838,47 @@ static int rproc_handle_resources(struct rproc *rproc, const u8 *elf_data,
752 838
753 /* look for the resource table and handle it */ 839 /* look for the resource table and handle it */
754 for (i = 0; i < ehdr->e_shnum; i++, shdr++) { 840 for (i = 0; i < ehdr->e_shnum; i++, shdr++) {
755 if (!strcmp(name_table + shdr->sh_name, ".resource_table")) { 841 int size = shdr->sh_size;
756 struct fw_resource *table = (struct fw_resource *) 842 int offset = shdr->sh_offset;
757 (elf_data + shdr->sh_offset);
758 843
759 if (shdr->sh_offset + shdr->sh_size > len) { 844 if (strcmp(name_table + shdr->sh_name, ".resource_table"))
760 dev_err(rproc->dev, 845 continue;
761 "truncated fw: need 0x%x avail 0x%x\n",
762 shdr->sh_offset + shdr->sh_size, len);
763 ret = -EINVAL;
764 }
765 846
766 ret = handler(rproc, table, shdr->sh_size); 847 table = (struct resource_table *)(elf_data + offset);
767 848
768 break; 849 /* make sure we have the entire table */
850 if (offset + size > len) {
851 dev_err(dev, "resource table truncated\n");
852 return -EINVAL;
853 }
854
855 /* make sure table has at least the header */
856 if (sizeof(struct resource_table) > size) {
857 dev_err(dev, "header-less resource table\n");
858 return -EINVAL;
769 } 859 }
860
861 /* we don't support any version beyond the first */
862 if (table->ver != 1) {
863 dev_err(dev, "unsupported fw ver: %d\n", table->ver);
864 return -EINVAL;
865 }
866
867 /* make sure reserved bytes are zeroes */
868 if (table->reserved[0] || table->reserved[1]) {
869 dev_err(dev, "non zero reserved bytes\n");
870 return -EINVAL;
871 }
872
873 /* make sure the offsets array isn't truncated */
874 if (table->num * sizeof(table->offset[0]) +
875 sizeof(struct resource_table) > size) {
876 dev_err(dev, "resource table incomplete\n");
877 return -EINVAL;
878 }
879
880 ret = handler(rproc, table, shdr->sh_size);
881 break;
770 } 882 }
771 883
772 return ret; 884 return ret;
@@ -980,7 +1092,7 @@ static void rproc_fw_config_virtio(const struct firmware *fw, void *context)
980 if (rproc_fw_sanity_check(rproc, fw) < 0) 1092 if (rproc_fw_sanity_check(rproc, fw) < 0)
981 goto out; 1093 goto out;
982 1094
983 /* does the fw supports any virtio devices ? */ 1095 /* does the fw support any virtio devices ? */
984 ret = rproc_handle_resources(rproc, fw->data, fw->size, 1096 ret = rproc_handle_resources(rproc, fw->data, fw->size,
985 rproc_handle_virtio_rsc); 1097 rproc_handle_virtio_rsc);
986 if (ret) { 1098 if (ret) {
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index ada4cb063dfe..6040f831f626 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -50,39 +50,51 @@
50#define AMP_VRING_ALIGN (4096) 50#define AMP_VRING_ALIGN (4096)
51 51
52/** 52/**
53 * struct fw_resource - describes an entry from the resource section 53 * struct resource_table - firmware resource table header
54 * @type: resource type 54 * @ver: version number
55 * @id: index number of the resource 55 * @num: number of resource entries
56 * @da: device address of the resource 56 * @reserved: reserved (must be zero)
57 * @pa: physical address of the resource 57 * @offset: array of offsets pointing at the various resource entries
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 * 58 *
63 * The remote processor firmware should contain a "resource table": 59 * A resource table is essentially a list of system resources required
64 * array of 'struct fw_resource' entries. 60 * by the remote processor. It may also include configuration entries.
61 * If needed, the remote processor firmware should contain this table
62 * as a dedicated ".resource_table" ELF section.
65 * 63 *
66 * Some resources entries are mere announcements, where the host is informed 64 * Some resources entries are mere announcements, where the host is informed
67 * of specific remoteproc configuration. Other entries require the host to 65 * of specific remoteproc configuration. Other entries require the host to
68 * do something (e.g. reserve a requested resource) and possibly also reply 66 * do something (e.g. allocate a system resource). Sometimes a negotiation
69 * by overwriting a member inside 'struct fw_resource' with info about the 67 * is expected, where the firmware requests a resource, and once allocated,
70 * allocated resource. 68 * the host should provide back its details (e.g. address of an allocated
71 * 69 * memory region).
72 * Different resource entries use different members of this struct, 70 *
73 * with different meanings. This is pretty limiting and error-prone, 71 * The header of the resource table, as expressed by this structure,
74 * so the plan is to move to variable-length TLV-based resource entries, 72 * contains a version number (should we need to change this format in the
75 * where each resource type will have its own structure. 73 * future), the number of available resource entries, and their offsets
74 * in the table.
75 *
76 * Immediately following this header are the resource entries themselves,
77 * each of which begins with a resource entry header (as described below).
78 */
79struct resource_table {
80 u32 ver;
81 u32 num;
82 u32 reserved[2];
83 u32 offset[0];
84} __packed;
85
86/**
87 * struct fw_rsc_hdr - firmware resource entry header
88 * @type: resource type
89 * @data: resource data
90 *
91 * Every resource entry begins with a 'struct fw_rsc_hdr' header providing
92 * its @type. The content of the entry itself will immediately follow
93 * this header, and it should be parsed according to the resource type.
76 */ 94 */
77struct fw_resource { 95struct fw_rsc_hdr {
78 u32 type; 96 u32 type;
79 u32 id; 97 u8 data[0];
80 u64 da;
81 u64 pa;
82 u32 len;
83 u32 flags;
84 u8 reserved[16];
85 u8 name[48];
86} __packed; 98} __packed;
87 99
88/** 100/**
@@ -92,30 +104,13 @@ struct fw_resource {
92 * memory region. 104 * memory region.
93 * @RSC_DEVMEM: request to iommu_map a memory-based peripheral. 105 * @RSC_DEVMEM: request to iommu_map a memory-based peripheral.
94 * @RSC_TRACE: announces the availability of a trace buffer into which 106 * @RSC_TRACE: announces the availability of a trace buffer into which
95 * the remote processor will be writing logs. In this case, 107 * the remote processor will be writing logs.
96 * 'da' indicates the device address where logs are written to, 108 * @RSC_VDEV: declare support for a virtio device, and serve as its
97 * and 'len' is the size of the trace buffer. 109 * virtio header.
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 * @RSC_LAST: just keep this one at the end 110 * @RSC_LAST: just keep this one at the end
107 * 111 *
108 * Most of the resource entries share the basic idea of address/length 112 * For more details regarding a specific resource type, please see its
109 * negotiation with the host: the firmware usually asks (on behalf of the 113 * dedicated structure below.
110 * remote processor that will soon be booted with it) for memory
111 * of size 'len' bytes, and the host needs to allocate it and provide
112 * the device/physical address (when relevant) in 'da'/'pa' respectively.
113 *
114 * If the firmware is compiled with hard coded device addresses, and
115 * can't handle dynamically allocated 'da' values, then the 'da' field
116 * will contain the expected device addresses (today we actually only support
117 * this scheme, as there aren't yet any use cases for dynamically allocated
118 * device addresses).
119 * 114 *
120 * Please note that these values are used as indices to the rproc_handle_rsc 115 * Please note that these values are used as indices to the rproc_handle_rsc
121 * lookup table, so please keep them sane. Moreover, @RSC_LAST is used to 116 * lookup table, so please keep them sane. Moreover, @RSC_LAST is used to
@@ -126,11 +121,197 @@ enum fw_resource_type {
126 RSC_CARVEOUT = 0, 121 RSC_CARVEOUT = 0,
127 RSC_DEVMEM = 1, 122 RSC_DEVMEM = 1,
128 RSC_TRACE = 2, 123 RSC_TRACE = 2,
129 RSC_VRING = 3, 124 RSC_VDEV = 3,
130 RSC_VIRTIO_DEV = 4, 125 RSC_LAST = 4,
131 RSC_LAST = 5,
132}; 126};
133 127
128#define FW_RSC_ADDR_ANY (0xFFFFFFFFFFFFFFFF)
129
130/**
131 * struct fw_rsc_carveout - physically contiguous memory request
132 * @da: device address
133 * @pa: physical address
134 * @len: length (in bytes)
135 * @flags: iommu protection flags
136 * @reserved: reserved (must be zero)
137 * @name: human-readable name of the requested memory region
138 *
139 * This resource entry requests the host to allocate a physically contiguous
140 * memory region.
141 *
142 * These request entries should precede other firmware resource entries,
143 * as other entries might request placing other data objects inside
144 * these memory regions (e.g. data/code segments, trace resource entries, ...).
145 *
146 * Allocating memory this way helps utilizing the reserved physical memory
147 * (e.g. CMA) more efficiently, and also minimizes the number of TLB entries
148 * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB
149 * pressure is important; it may have a substantial impact on performance.
150 *
151 * If the firmware is compiled with static addresses, then @da should specify
152 * the expected device address of this memory region. If @da is set to
153 * FW_RSC_ADDR_ANY, then the host will dynamically allocate it, and then
154 * overwrite @da with the dynamically allocated address.
155 *
156 * We will always use @da to negotiate the device addresses, even if it
157 * isn't using an iommu. In that case, though, it will obviously contain
158 * physical addresses.
159 *
160 * Some remote processors needs to know the allocated physical address
161 * even if they do use an iommu. This is needed, e.g., if they control
162 * hardware accelerators which access the physical memory directly (this
163 * is the case with OMAP4 for instance). In that case, the host will
164 * overwrite @pa with the dynamically allocated physical address.
165 * Generally we don't want to expose physical addresses if we don't have to
166 * (remote processors are generally _not_ trusted), so we might want to
167 * change this to happen _only_ when explicitly required by the hardware.
168 *
169 * @flags is used to provide IOMMU protection flags, and @name should
170 * (optionally) contain a human readable name of this carveout region
171 * (mainly for debugging purposes).
172 */
173struct fw_rsc_carveout {
174 u32 da;
175 u32 pa;
176 u32 len;
177 u32 flags;
178 u32 reserved;
179 u8 name[32];
180} __packed;
181
182/**
183 * struct fw_rsc_devmem - iommu mapping request
184 * @da: device address
185 * @pa: physical address
186 * @len: length (in bytes)
187 * @flags: iommu protection flags
188 * @reserved: reserved (must be zero)
189 * @name: human-readable name of the requested region to be mapped
190 *
191 * This resource entry requests the host to iommu map a physically contiguous
192 * memory region. This is needed in case the remote processor requires
193 * access to certain memory-based peripherals; _never_ use it to access
194 * regular memory.
195 *
196 * This is obviously only needed if the remote processor is accessing memory
197 * via an iommu.
198 *
199 * @da should specify the required device address, @pa should specify
200 * the physical address we want to map, @len should specify the size of
201 * the mapping and @flags is the IOMMU protection flags. As always, @name may
202 * (optionally) contain a human readable name of this mapping (mainly for
203 * debugging purposes).
204 *
205 * Note: at this point we just "trust" those devmem entries to contain valid
206 * physical addresses, but this isn't safe and will be changed: eventually we
207 * want remoteproc implementations to provide us ranges of physical addresses
208 * the firmware is allowed to request, and not allow firmwares to request
209 * access to physical addresses that are outside those ranges.
210 */
211struct fw_rsc_devmem {
212 u32 da;
213 u32 pa;
214 u32 len;
215 u32 flags;
216 u32 reserved;
217 u8 name[32];
218} __packed;
219
220/**
221 * struct fw_rsc_trace - trace buffer declaration
222 * @da: device address
223 * @len: length (in bytes)
224 * @reserved: reserved (must be zero)
225 * @name: human-readable name of the trace buffer
226 *
227 * This resource entry provides the host information about a trace buffer
228 * into which the remote processor will write log messages.
229 *
230 * @da specifies the device address of the buffer, @len specifies
231 * its size, and @name may contain a human readable name of the trace buffer.
232 *
233 * After booting the remote processor, the trace buffers are exposed to the
234 * user via debugfs entries (called trace0, trace1, etc..).
235 */
236struct fw_rsc_trace {
237 u32 da;
238 u32 len;
239 u32 reserved;
240 u8 name[32];
241} __packed;
242
243/**
244 * struct fw_rsc_vdev_vring - vring descriptor entry
245 * @da: device address
246 * @align: the alignment between the consumer and producer parts of the vring
247 * @num: num of buffers supported by this vring (must be power of two)
248 * @notifyid is a unique rproc-wide notify index for this vring. This notify
249 * index is used when kicking a remote processor, to let it know that this
250 * vring is triggered.
251 * @reserved: reserved (must be zero)
252 *
253 * This descriptor is not a resource entry by itself; it is part of the
254 * vdev resource type (see below).
255 *
256 * Note that @da should either contain the device address where
257 * the remote processor is expecting the vring, or indicate that
258 * dynamically allocation of the vring's device address is supported.
259 */
260struct fw_rsc_vdev_vring {
261 u32 da;
262 u32 align;
263 u32 num;
264 u32 notifyid;
265 u32 reserved;
266} __packed;
267
268/**
269 * struct fw_rsc_vdev - virtio device header
270 * @id: virtio device id (as in virtio_ids.h)
271 * @notifyid is a unique rproc-wide notify index for this vdev. This notify
272 * index is used when kicking a remote processor, to let it know that the
273 * status/features of this vdev have changes.
274 * @dfeatures specifies the virtio device features supported by the firmware
275 * @gfeatures is a place holder used by the host to write back the
276 * negotiated features that are supported by both sides.
277 * @config_len is the size of the virtio config space of this vdev. The config
278 * space lies in the resource table immediate after this vdev header.
279 * @status is a place holder where the host will indicate its virtio progress.
280 * @num_of_vrings indicates how many vrings are described in this vdev header
281 * @reserved: reserved (must be zero)
282 * @vring is an array of @num_of_vrings entries of 'struct fw_rsc_vdev_vring'.
283 *
284 * This resource is a virtio device header: it provides information about
285 * the vdev, and is then used by the host and its peer remote processors
286 * to negotiate and share certain virtio properties.
287 *
288 * By providing this resource entry, the firmware essentially asks remoteproc
289 * to statically allocate a vdev upon registration of the rproc (dynamic vdev
290 * allocation is not yet supported).
291 *
292 * Note: unlike virtualization systems, the term 'host' here means
293 * the Linux side which is running remoteproc to control the remote
294 * processors. We use the name 'gfeatures' to comply with virtio's terms,
295 * though there isn't really any virtualized guest OS here: it's the host
296 * which is responsible for negotiating the final features.
297 * Yeah, it's a bit confusing.
298 *
299 * Note: immediately following this structure is the virtio config space for
300 * this vdev (which is specific to the vdev; for more info, read the virtio
301 * spec). the size of the config space is specified by @config_len.
302 */
303struct fw_rsc_vdev {
304 u32 id;
305 u32 notifyid;
306 u32 dfeatures;
307 u32 gfeatures;
308 u32 config_len;
309 u8 status;
310 u8 num_of_vrings;
311 u8 reserved[2];
312 struct fw_rsc_vdev_vring vring[0];
313} __packed;
314
134/** 315/**
135 * struct rproc_mem_entry - memory entry descriptor 316 * struct rproc_mem_entry - memory entry descriptor
136 * @va: virtual address 317 * @va: virtual address
@@ -144,7 +325,7 @@ struct rproc_mem_entry {
144 void *va; 325 void *va;
145 dma_addr_t dma; 326 dma_addr_t dma;
146 int len; 327 int len;
147 u64 da; 328 u32 da;
148 void *priv; 329 void *priv;
149 struct list_head node; 330 struct list_head node;
150}; 331};
@@ -226,7 +407,7 @@ struct rproc {
226 struct list_head carveouts; 407 struct list_head carveouts;
227 struct list_head mappings; 408 struct list_head mappings;
228 struct completion firmware_loading_complete; 409 struct completion firmware_loading_complete;
229 u64 bootaddr; 410 u32 bootaddr;
230 struct rproc_vdev *rvdev; 411 struct rproc_vdev *rvdev;
231}; 412};
232 413