aml.h 25.9 KB
Newer Older
Swann Perarnau's avatar
Swann Perarnau committed
1 2 3 4 5 6 7 8 9 10
/*******************************************************************************
 * Copyright 2019 UChicago Argonne, LLC.
 * (c.f. AUTHORS, LICENSE)
 *
 * This file is part of the AML project.
 * For more info, see https://xgitlab.cels.anl.gov/argo/aml
 *
 * SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/

11 12 13 14 15 16 17
/**
 * \file aml.h
 *
 * \brief Main AML header file, contains all high level
 * abstractions declarations.
 **/

18 19 20
#ifndef AML_H
#define AML_H 1

21
#include <assert.h>
22
#include <errno.h>
23 24 25 26 27 28 29
#include <inttypes.h>
#include <numa.h>
#include <numaif.h>
#include <pthread.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
30
#include <stdlib.h>
31 32
#include <string.h>
#include <strings.h>
33 34 35
#include <sys/mman.h>
#include <unistd.h>

36
#include "aml/utils/bitmap.h"
Nicolas Denoyelle's avatar
Nicolas Denoyelle committed
37
#include "aml/utils/error.h"
38
#include "aml/utils/vector.h"
Nicolas Denoyelle's avatar
Nicolas Denoyelle committed
39
#include "aml/utils/version.h"
40

41
////////////////////////////////////////////////////////////////////////////////
42

43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
/**
 * @}
 * @defgroup aml "AML Library functions"
 * @brief Initialize/Finalize library.
 *
 * General functions of aml library.
 * Initialization of internal structures, cleanup of everything at the end.
 *
 * @see aml_error
 * @see aml_version
 * @{
 **/

////////////////////////////////////////////////////////////////////////////////

/**
59
 * Initializes the library.
60 61 62 63 64 65
 * @param argc: pointer to the main()'s argc argument; contents can get
 *        modified.
 * @param argv: pointer to the main()'s argv argument; contents can get
 *        modified.
 * @return 0 if successful; an error code otherwise.
 **/
66
int aml_init(int *argc, char **argv[]);
67 68

/**
69
 * Terminates the library.
70 71
 * @return 0 if successful; an error code otherwise.
 **/
72
int aml_finalize(void);
73

74
////////////////////////////////////////////////////////////////////////////////
75

Nicolas Denoyelle's avatar
Nicolas Denoyelle committed
76
/**
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
 * @}
 * @defgroup aml_area "AML Area"
 * @brief Area High-Level API
 *
 * AML areas represent places where data can belong.
 * In shared memory systems, locality is a major concern for performance.
 * Beeing able to query memory from specific places is of a major interest
 * two achieve this goal. AML Areas provide mmap / munmap low level functions
 * to query memory from specific places materialized as areas. Available area
 * implementations dictate the way such places can be arranged and with which
 * properties. It is important to notice that function provided through Area API
 * are low-level functions and are not optimized for performance as allocator
 * are.
 *
 * @image html area.png "Illustration of areas on a copmlex system." width=700cm
 *
 * @see aml_area_linux
 *
 * @{
Nicolas Denoyelle's avatar
Nicolas Denoyelle committed
96 97
 **/

98 99 100 101 102 103
////////////////////////////////////////////////////////////////////////////////

/**
 * aml_area_data is an opaque handle defined by each aml_area
 * implementation. This not supposed to be used by end users.
 **/
104 105
struct aml_area_data;

106 107 108 109 110 111
/**
 * aml_area_ops is a structure containing implementations
 * of an area operations.
 * Aware users may create or modify implementation by assembling
 * appropriate operations in such a structure.
 **/
112 113
struct aml_area_ops {
	/**
114
	 * Building block for coarse grain allocator of virtual memory.
115
	 *
116 117 118
	 * @param data: Opaque handle to implementation specific data.
	 * @param ptr: A virtual address to be used by underlying
	 *        implementation.
119
	 *        Can be NULL.
120 121 122 123 124 125 126
	 * @param size: The minimum size of allocation.
	 *        Is greater than 0. Must not fail unless not enough
	 *        memory is available, or ptr argument does not point to a
	 *        suitable address.
	 *        In case of failure, aml_errno must be set to an appropriate
	 *        value.
	 * @return a pointer to allocated memory object.
127
	 **/
128
	void* (*mmap)(const struct aml_area_data  *data,
129 130 131 132
		      void                        *ptr,
		      size_t                       size);

	/**
133 134
	 * Building block for unmapping of virtual memory mapped with mmap()
	 * of the same area.
135
	 *
136 137 138 139 140 141
	 * @param data: An opaque handle to implementation specific data.
	 * @param ptr: Pointer to data mapped in physical memory. Cannot be
	 *        NULL.
	 * @param size: The size of data. Cannot be 0.
	 * @return: AML_AREA_* error code.
	 * @see mmap()
142
	 **/
143
	int (*munmap)(const struct aml_area_data *data,
144 145 146 147
		      void                       *ptr,
		      size_t                      size);
};

148 149 150 151 152 153 154
/**
 * An AML area is an implementation of memory operations for several type
 * of devices through a consistent abstraction.
 * This abstraction is meant to be implemented for several kind of devices,
 * i.e the same function calls allocate different kinds of devices depending
 * on the area implementation provided.
 **/
155
struct aml_area {
156
	/** Basic memory operations implementation **/
157
	struct aml_area_ops *ops;
158
	/** Implementation specific data. Set to NULL at creation. **/
159 160
	struct aml_area_data *data;
};
Nicolas Denoyelle's avatar
Nicolas Denoyelle committed
161 162

/**
163 164 165 166 167
 * Low-level function for getting memory from an area.
 * @param area: A valid area implementing access to target memory.
 * @param ptr: Implementation specific argument. See specific header.
 * @param size: The usable size of memory returned.
 * @return virtual memory from this area with at least queried size bytes.
Nicolas Denoyelle's avatar
Nicolas Denoyelle committed
168
 **/
169 170 171
void *aml_area_mmap(const struct aml_area *area,
		    void                 **ptr,
		    size_t                 size);
Nicolas Denoyelle's avatar
Nicolas Denoyelle committed
172 173 174

/**
 * Release data provided with aml_area_mmap() and the same area.
175 176
 * @param area: A valid area implementing access to target memory.
 * @param ptr: A pointer to memory address provided with aml_area_mmap()
Nicolas Denoyelle's avatar
Nicolas Denoyelle committed
177
 *        by same area and size.
178 179 180
 * @param size: The size of memory region pointed by "ptr".
 * @return an AML error code on operation success.
 * @see aml_area_mmap()
Nicolas Denoyelle's avatar
Nicolas Denoyelle committed
181 182 183 184 185
 **/
int
aml_area_munmap(const struct aml_area *area,
		void                  *ptr,
		size_t                 size);
186

187
////////////////////////////////////////////////////////////////////////////////
188

189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
/**
 * @}
 * @defgroup aml_tiling "AML Tiling"
 * @brief Tiling Data Structure High-Level API
 *
 * Tiling is an array representation of data structures.
 * AML tiling structure can be defined as 1D or 2D contiguous arrays.
 * Tiles in tilings can be of custom size and AML provides iterators to
 * easily access tiles element.
 * @{
 **/

////////////////////////////////////////////////////////////////////////////////

/**
 * Tiling types passed to some tiling routines.
 * Regular, linear tiling with uniform tile sizes.
 **/
207
#define AML_TILING_TYPE_1D 0
208 209 210 211 212 213

/**
 * Tiling types passed to some tiling routines.
 * 2-dimensional cartesian tiling with uniform tile sizes, stored
 * in rowmajor order
 **/
214
#define AML_TILING_TYPE_2D_ROWMAJOR 1
215 216 217 218 219 220

/**
 * Tiling types passed to some tiling routines.
 * 2-dimensional cartesian tiling with uniform tile sizes, stored
 * in colmajor order
 **/
221 222
#define AML_TILING_TYPE_2D_COLMAJOR 2

223 224 225 226
/**
 * aml_tiling_data is an opaque handle defined by each aml_tiling
 * implementation. This not supposed to be used by end users.
 **/
227
struct aml_tiling_data;
228 229 230 231 232 233

/**
 * aml_area_tiling_iterator_data is an opaque handle defined by each
 * aml_tiling_iterator implementation. This not supposed to be used
 * by end users.
 **/
234 235
struct aml_tiling_iterator_data;

236 237 238 239 240 241
/**
 * aml_tiling_iterator_ops contains the specific operations defined
 * by an aml_tiling_iterator.
 * Aware users may create or modify implementation by assembling
 * appropriate operations in such a structure.
 **/
242 243
struct aml_tiling_iterator_ops;

244 245 246 247 248 249
/**
 * \brief aml_tiling_iterator is a structure for iterating over
 * elements of an aml_tiling.
 * \todo Provide a detailed explanation of what is a tiling iterator.
 **/
struct aml_tiling_iterator;
250

251 252 253 254 255 256 257
/**
 * aml_tiling_ops is a structure containing a set of operation
 * over a tiling. These operation are the creation and destruction
 * of iterators, access to tiles indexing, size and tiling dimension.
 * Aware users may create or modify implementation by assembling
 * appropriate operations in such a structure.
 **/
258
struct aml_tiling_ops {
259 260 261
	/**
	 * \todo Doc
	 **/
262 263 264
	int (*create_iterator)(struct aml_tiling_data *tiling,
			       struct aml_tiling_iterator **iterator,
			       int flags);
265 266 267
	/**
	 * \todo Doc
	 **/
268 269
	int (*init_iterator)(struct aml_tiling_data *tiling,
			     struct aml_tiling_iterator *iterator, int flags);
270 271 272
	/**
	 * \todo Doc
	 **/
273
	int (*fini_iterator)(struct aml_tiling_data *tiling,
274
				struct aml_tiling_iterator *iterator);
275 276 277
	/**
	 * \todo Doc
	 **/
278 279
	int (*destroy_iterator)(struct aml_tiling_data *tiling,
				struct aml_tiling_iterator **iterator);
280 281 282
	/**
	 * \todo Doc
	 **/
283
	int (*tileid)(const struct aml_tiling_data *tiling, va_list coords);
284 285 286
	/**
	 * \todo Doc
	 **/
Kamil Iskra's avatar
Kamil Iskra committed
287
	size_t (*tilesize)(const struct aml_tiling_data *tiling, int tileid);
288 289 290
	/**
	 * \todo Doc
	 **/
Kamil Iskra's avatar
Kamil Iskra committed
291 292
	void* (*tilestart)(const struct aml_tiling_data *tiling,
			   const void *ptr, int tileid);
293 294 295
	/**
	 * \todo Doc
	 **/
296
	int (*ndims)(const struct aml_tiling_data *tiling, va_list results);
297 298
};

299 300 301 302 303 304 305
/**
 * An aml_tiling is a multi-dimensional grid of data, e.g a matrix, a stencil
 * etc...
 * Tilings are used in AML as a description of a macro data structure that will
 * be used by a library for doing its own work. This structure is exploitable
 * by AML to perform optimized movement operations.
 **/
306
struct aml_tiling {
307
	/** @see aml_tiling_ops **/
308
	struct aml_tiling_ops *ops;
309
	/** @see aml_tiling_data **/
310 311 312
	struct aml_tiling_data *data;
};

313
/**
314
 * Provides the tile id of a tile.
315 316 317 318 319 320
 * @param tiling: an initialized tiling structure.
 * @param coordinates: a list of size_t coordinates, one per dimension of the
 *        tiling.
 * @return -1 in case of invalid coordinates, else the id of the tile
 *         (that is, its order in memory), to use with other functions.
 **/
321 322
int aml_tiling_tileid(const struct aml_tiling *tiling, ...);

323
/**
324
 * Provides the information on the size of a tile.
325 326 327 328 329
 * @param tiling: an initialized tiling structure.
 * @param tileid: an identifier of a tile (a value between 0 and the number
 *        of tiles minus 1).
 * @return the size of a tile.
 **/
Kamil Iskra's avatar
Kamil Iskra committed
330
size_t aml_tiling_tilesize(const struct aml_tiling *tiling, int tileid);
331

332
/**
333
 * Provides the information on the location of a tile in memory.
334 335 336 337 338 339
 * @param tiling: an initialized tiling structure.
 * @param ptr: an address of the start of the complete user data structure
 *        that this tiling describes.
 * @param tileid: an identifier of a tile (a value between 0 and the number
 *        of tiles minus 1).
 * @return the address of the start of the tile identified by "tileid", within
340
 * the provided user data structure.
341 342 343
 **/
void *aml_tiling_tilestart(const struct aml_tiling *tiling,
			   const void *ptr,
Kamil Iskra's avatar
Kamil Iskra committed
344
			   int tileid);
345

346
/**
347
 * Provides the dimensions of the entire tiling in tiles.
348 349 350 351 352
 * @param tiling: an initialized tiling structure.
 * @param sizes: a list of output (size_t *), one per dimension of the tiling.
 *               Will contain the size of each dimension in tiles upon return.
 * @return 0 if successful, an error code otherwise.
 **/
353 354
int aml_tiling_ndims(const struct aml_tiling *tiling, ...);

355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388
/**
 * \todo Doc
 **/
struct aml_tiling_iterator_ops {
	/**
	 * \todo Doc
	 **/
	int (*reset)(struct aml_tiling_iterator_data *iterator);
	/**
	 * \todo Doc
	 **/
	int (*next)(struct aml_tiling_iterator_data *iterator);
	/**
	 * \todo Doc
	 **/
	int (*end)(const struct aml_tiling_iterator_data *iterator);
	/**
	 * \todo Doc
	 **/
	int (*get)(const struct aml_tiling_iterator_data *iterator,
		   va_list args);
};

/**
 * \todo Doc
 **/
struct aml_tiling_iterator {
	/** @see aml_tiling_iterator_ops **/
	struct aml_tiling_iterator_ops *ops;
	/** @see aml_tiling_iterator_data **/
	struct aml_tiling_iterator_data *data;
};

/**
389
 * Allocates and initializes a new tiling iterator.
390 391 392 393 394 395
 * @param tiling: an initialized tiling structure.
 * @param iterator: an address where the pointer to the newly allocated iterator
 *        structure will be stored.
 * @param flags: reserved for future use; pass 0 for now.
 * @return 0 if successful; an error code otherwise.
 **/
396 397 398
int aml_tiling_create_iterator(struct aml_tiling *tiling,
			       struct aml_tiling_iterator **iterator,
			       int flags);
399
/**
400
 * Initializes a tiling iterator.
401 402 403 404 405
 * @param tiling: an initialized tiling structure.
 * @param iterator: an allocated tiling iterator structure.
 * @param flags: reserved for future use; pass 0 for now.
 * @return 0 if successful; an error code otherwise.
 **/
406 407
int aml_tiling_init_iterator(struct aml_tiling *tiling,
			     struct aml_tiling_iterator *iterator, int flags);
408

409
/**
410
 * Finalize an initialized tiling iterator.
411 412 413
 * @param tiling: an initialized tiling structure.
 * @param iterator: an initialized tiling iterator structure.
 **/
414 415
void aml_tiling_fini_iterator(struct aml_tiling *tiling,
			      struct aml_tiling_iterator *iterator);
416
/**
417
 * Tears down an initialized tiling iterator.
418 419 420 421
 * @param tiling: an initialized tiling structure.
 * @param iterator: an initialized tiling iterator structure.
 * @return 0 if successful; an error code otherwise.
 **/
422 423
void aml_tiling_destroy_iterator(struct aml_tiling *tiling,
				struct aml_tiling_iterator **iterator);
424 425


426
/**
427
 * Resets a tiling iterator to the first tile.
428 429 430
 * @param iterator: an initialized tiling iterator structure.
 * @return 0 if successful; an error code otherwise.
 **/
431
int aml_tiling_iterator_reset(struct aml_tiling_iterator *iterator);
432 433

/**
434
 * Advances a tiling iterator to the next tile.
435 436 437
 * @param iterator: an initialized tiling iterator structure.
 * @return 0 if successful; an error code otherwise.
 **/
438
int aml_tiling_iterator_next(struct aml_tiling_iterator *iterator);
439 440

/**
441
 * Checks whether the iterator is past the last tile.
442 443
 * @param iterator: an initialized tiling iterator structure.
 * @return 0 if the iterator points at a valid tile; 1 if it's past the last
444
 * tile.
445
 **/
Kamil Iskra's avatar
Kamil Iskra committed
446
int aml_tiling_iterator_end(const struct aml_tiling_iterator *iterator);
447 448

/**
449
 * Queries the iterator.
450 451
 * @param iterator: an initialized tiling iterator structure.
 * @param x: an argument of type unsigned long*; on return gets filled with the
452
 *        identifier of the tile currently pointed to.
453 454
 * @return 0 if successful; an error code otherwise.
 **/
Kamil Iskra's avatar
Kamil Iskra committed
455
int aml_tiling_iterator_get(const struct aml_tiling_iterator *iterator, ...);
456

457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472
////////////////////////////////////////////////////////////////////////////////

/**
 * @}
 * @defgroup aml_dma "AML DMA"
 * @brief Management of low-level memory movements.
 *
 * AML DMA is the abstraction for handling memory movements.
 * AML DMA can asynchronously move data from one area to another.
 * While performing a movement, DMA operation
 * may also translates from a source tiling to a different
 * destination tiling.
 *
 * @image html dma.png width=600
 * @{
 **/
473

474 475 476 477 478 479
////////////////////////////////////////////////////////////////////////////////

/**
 * Internal macros used for tracking DMA request types.
 * Invalid request type.  Used for marking inactive requests in the vector.
 **/
480
#define AML_DMA_REQUEST_TYPE_INVALID -1
481 482 483 484 485

/**
 * Internal macros used for tracking DMA request types.
 * Copy request type.  Uses memcpy() for data migration.
 **/
486 487
#define AML_DMA_REQUEST_TYPE_COPY 0

488 489 490 491 492 493 494
/**
 * aml_dma is mainly used to asynchronously move data.
 * aml_dma_request is an opaque structure containing information
 * about ongoing request for data movement in a dma operation.
 * @see aml_dma_ops
 * @see aml_dma_async_copy()
 **/
495
struct aml_dma_request;
496 497 498 499 500

/**
 * Opaque handle implemented by each aml_dma implementations.
 * Should not be used by end-users.
 **/
501 502
struct aml_dma_data;

503 504 505 506 507 508 509 510 511 512 513 514
/**
 aml_dma_ops is a structure containing operations for a specific
 * aml_dma implementation.
 * These operation are operation are detailed in the structure.
 * They are specific in:
 * - the type of aml_area source and destination,
 * - the progress engine performing the operation,
 * - the type of of source and destination data structures.
 *
 * Each different combination of these three points may require a different
 * set of dma operations.
 **/
515
struct aml_dma_ops {
516 517 518 519 520 521 522 523 524 525 526
	/**
	 * Initiate a data movement, from a source pointer to a destination
	 * pointer, and output a request handler for managing the transfer.
	 * @param dma: dma_implementation internal data.
	 * @param req: Output the request handle to manage termination
	 *        of the movement.
	 * @param type: A valid AML_DMA_REQUEST_TYPE_* specifying the kind
	 *        of operation to perform.
	 * @param args: list of variadic arguments provided to aml_dma_copy()
	 * @return an AML error code.
	 **/
527
	int (*create_request)(struct aml_dma_data *dma,
528
			      struct aml_dma_request **req, int type,
529
			      va_list args);
530 531 532 533 534 535 536 537 538

	/**
	 * Destroy the request handle. If the data movement is still ongoing,
	 * then cancel it.
	 *
	 * @param dma: dma_implementation internal data.
	 * @param req: the request handle to manage termination of the movement.
	 * @return an AML error code.
	 **/
539 540
	int (*destroy_request)(struct aml_dma_data *dma,
			       struct aml_dma_request *req);
541 542 543 544 545 546 547 548 549

	/**
	 * Wait for termination of a data movement and destroy the request
	 * handle.
	 *
	 * @param dma: dma_implementation internal data.
	 * @param req: the request handle to manage termination of the movement.
	 * @return an AML error code.
	 **/
550 551
	int (*wait_request)(struct aml_dma_data *dma,
			    struct aml_dma_request *req);
552 553
};

554 555 556 557 558 559 560
/**
 * aml_dma is an abstraction for (asynchronously) moving data
 * from one area to another. The implementation of dma to use
 * is depends on the source and destination areas. The appropriate
 * dma choice is delegated to the user.
 * @see struct aml_area.
 **/
561
struct aml_dma {
562
	/** @see aml_dma_ops **/
563
	struct aml_dma_ops *ops;
564
	/** @see aml_dma_data **/
565 566 567
	struct aml_dma_data *data;
};

568
/**
569 570
 * Requests a synchronous data copy between two different tiles, using
 * memcpy() or equivalent.
571 572 573 574 575 576 577 578 579 580 581 582 583
 * @param dma: an initialized DMA structure.
 * @param dt: an argument of type struct aml_tiling*; the destination tiling
 *        structure.
 * @param dptr: an argument of type void*; the start address of the complete
 *        destination user data structure.
 * @param dtid: an argument of type int; the destination tile identifier.
 * @param st: an argument of type struct aml_tiling*; the source tiling
 *        structure.
 * @param sptr: an argument of type void*; the start address of the
 *        complete source user data structure.
 * @param stid: an argument of type int; the source tile identifier.
 * @return 0 if successful; an error code otherwise.
 **/
584
int aml_dma_copy(struct aml_dma *dma, ...);
585 586

/**
587 588
 * Requests a data copy between two different tiles.  This is an asynchronous
 * version of aml_dma_copy().
589 590 591
 * @param dma: an initialized DMA structure.
 * @param req: an address where the pointer to the newly assigned DMA request
 *        will be stored.
592
 * Variadic arguments: see aml_dma_copy().
593 594
 * @return 0 if successful; an error code otherwise.
 **/
595
int aml_dma_async_copy(struct aml_dma *dma, struct aml_dma_request **req, ...);
596 597

/**
598
 * Waits for an asynchronous DMA request to complete.
599 600 601 602
 * @param dma: an initialized DMA structure.
 * @param req: a DMA request obtained using aml_dma_async_*() calls.
 * @return 0 if successful; an error code otherwise.
 **/
603
int aml_dma_wait(struct aml_dma *dma, struct aml_dma_request *req);
604 605

/**
606
 * Tears down an asynchronous DMA request before it completes.
607 608 609 610
 * @param dma: an initialized DMA structure.
 * @param req: a DMA request obtained using aml_dma_async_*() calls.
 * @return 0 if successful; an error code otherwise.
 **/
611
int aml_dma_cancel(struct aml_dma *dma, struct aml_dma_request *req);
612

613
////////////////////////////////////////////////////////////////////////////////
614

615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639
/**
 * @}
 * @defgroup aml_scratch "AML Scratchpad"
 * @brief Stage-in, Stage-out High Level Abstraction.
 *
 * Scratchpad in an abstraction fro moving data back and forth from
 * a data representation in an area to another data representation in another
 * areas. This is especially usefull from moving to user data representation
 * to an architecure optimized representation for heavy computational work,
 * then returning the to user representation.
 * Data movement is performed with two dma engines from one area and tiling to
 * another area and tiling.
 *
 * @image html scratch.png width=600
 * @see aml_dma
 * @{
 **/

////////////////////////////////////////////////////////////////////////////////

/**
 * Scratch is mainly used to asynchronously move data back and forth between
 * two areas. aml_scratch_request is an opaque structure containing information
 * about ongoing requests for data movement.
 **/
640
struct aml_scratch_request;
641 642 643 644 645

/**
 * Opaque handle implemented by each scratches implementation.
 * Should not be used by end users.
 **/
646 647
struct aml_scratch_data;

648 649 650 651
/**
 * Scratchpad request types.
 * Invalid request type.  Used for marking inactive requests in the vector.
 **/
652
#define AML_SCRATCH_REQUEST_TYPE_INVALID -1
653 654 655 656 657

/**
 * Scratchpad request types.
 * Push from the scratchpad to regular memory.
 **/
658
#define AML_SCRATCH_REQUEST_TYPE_PUSH 0
659 660 661 662 663

/**
 * Scratchpad request types.
 * Pull from regular memory to the scratchpad.
 **/
664
#define AML_SCRATCH_REQUEST_TYPE_PULL 1
665 666 667 668 669

/**
 * Scratchpad request types.
 * No-op/empty request
 **/
670
#define AML_SCRATCH_REQUEST_TYPE_NOOP 2
671

672 673 674 675 676 677 678 679 680
/**
 * aml_scratch_ops contain a scratch implementation specific operations.
 * These operations implementation may vary depending on the source and
 * destination of data, and thus scratch implementations use different
 * operations.
 * Aware users may create or modify implementation by assembling
 * appropriate operations in such a structure.
 * @see struct aml_scratch
 **/
681
struct aml_scratch_ops {
682 683 684
	/**
	 * \todo Doc
	 **/
685 686 687
	int (*create_request)(struct aml_scratch_data *scratch,
			      struct aml_scratch_request **req, int type,
			      va_list args);
688 689 690
	/**
	 * \todo Doc
	 **/
691 692
	int (*destroy_request)(struct aml_scratch_data *scratch,
			       struct aml_scratch_request *req);
693 694 695
	/**
	 * \todo Doc
	 **/
696 697
	int (*wait_request)(struct aml_scratch_data *scratch,
			    struct aml_scratch_request *req);
698 699 700
	/**
	 * \todo Doc
	 **/
701
	void *(*baseptr)(const struct aml_scratch_data *scratch);
702 703 704
	/**
	 * \todo Doc
	 **/
705
	int (*release)(struct aml_scratch_data *scratch, int scratchid);
706 707
};

708 709 710 711 712 713
/**
 * An aml_scratch is abstraction aimed toward temporary use of a data structures
 * in a different area than the one where data currently resides. Scratches in
 * AML take care of asynchornously allocating and moving the data back and forth
 * between areas.
 **/
714
struct aml_scratch {
715
	/** @see aml_scratch_ops **/
716
	struct aml_scratch_ops *ops;
717
	/** @see aml_scratch_data **/
718 719 720
	struct aml_scratch_data *data;
};

721
/**
722
 * Requests a synchronous pull from regular memory to the scratchpad.
723 724 725 726 727
 * @param scratch: an initialized scratchpad structure.
 * @param scratchptr: an argument of type void*; the scratchpad base pointer.
 * @param scratchid: an argument of type int*; gets filled with the scratch tile
 *        identifier where the data will be pulled into.
 * @param srcptr: an argument of type void*; the start address of the complete
728
 *             source user data structure.
729 730 731 732
 * @param srcid: an argument of type int; the source tile identifier.
 * @see aml_scratch_baseptr()
 * @return 0 if successful; an error code otherwise.
 **/
733
int aml_scratch_pull(struct aml_scratch *scratch, ...);
734 735 736

/**
 * Requests a pull from regular memory to the scratchpad. This is an
737
 * asynchronous version of aml_scratch_pull().
738 739 740 741 742 743 744
 * @param scratch: an initialized scratchpad structure.
 * @param req: an address where the pointer to the newly assigned scratch
 *        request will be stored.
 * @param variadic arguments: see aml_scratch_pull().
 * @return 0 if successful; an error code otherwise.
 * @see aml_scratch_pull()
 **/
745 746
int aml_scratch_async_pull(struct aml_scratch *scratch,
			   struct aml_scratch_request **req, ...);
747
/**
748
 * Requests a synchronous push from the scratchpad to regular memory.
749 750 751 752 753 754 755 756 757 758 759
 * @param scratch: an initialized scratchpad structure.
 * @param dstptr: an argument of type void*; the start address of the complete
 *        destination user data structure.
 * @param dstid: an argument of type int*; gets filled with the destination tile
 *        identifier where the data will be pushed into (and where it was
 *        pulled from in the first place).
 * @param scratchptr: an argument of type void*; the scratchpad base pointer.
 * @param scratchid: an argument of type int; the scratchpad tile identifier.
 * @return 0 if successful; an error code otherwise.
 * @see aml_scratch_baseptr()
 **/
760
int aml_scratch_push(struct aml_scratch *scratch, ...);
761 762

/**
763 764
 * Requests a push from the scratchpad to regular memory.  This is an
 * asynchronous version of aml_scratch_push().
765 766 767
 * @param scratch: an initialized scratchpad structure.
 * @param req: an address where the pointer to the newly assigned scratch
 *        request will be stored.
768
 * Variadic arguments: see aml_scratch_push().
769 770 771
 * @return 0 if successful; an error code otherwise.
 * @see aml_scratch_push()
 **/
772 773
int aml_scratch_async_push(struct aml_scratch *scratch,
			   struct aml_scratch_request **req, ...);
774
/**
775
 * Waits for an asynchronous scratch request to complete.
776 777 778 779
 * @param scratch: an initialized scratchpad structure.
 * @param req: a scratch request obtained using aml_scratch_async_*() calls.
 * @return 0 if successful; an error code otherwise.
 **/
780 781
int aml_scratch_wait(struct aml_scratch *scratch,
		     struct aml_scratch_request *req);
782

783
/**
784
 * Tears down an asynchronous scratch request before it completes.
785 786 787 788
 * @param scratch: an initialized scratchpad structure.
 * @param req: a scratch request obtained using aml_scratch_async_*() calls.
 * @return 0 if successful; an error code otherwise.
 **/
789 790
int aml_scratch_cancel(struct aml_scratch *scratch,
		       struct aml_scratch_request *req);
791
/**
792
 * Provides the location of the scratchpad.
793 794 795
 * @param scratch: an initialized scratchpad structure.
 * @return a base pointer to the scratchpad memory buffer.
 **/
796
void *aml_scratch_baseptr(const struct aml_scratch *scratch);
797

798
/**
799
 * Release a scratch tile for immediate reuse.
800 801 802 803
 * @param scratch: an initialized scratchpad structure.
 * @param scratchid: a scratchpad tile identifier.
 * @return 0 if successful; an error code otherwise.
 **/
804 805
int aml_scratch_release(struct aml_scratch *scratch, int scratchid);

806 807 808 809 810 811
////////////////////////////////////////////////////////////////////////////////

/**
 * @}
 **/

812
#endif