OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (c) 2009 NVIDIA Corporation. |
| 3 * All rights reserved. |
| 4 * |
| 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are met: |
| 7 * |
| 8 * Redistributions of source code must retain the above copyright notice, |
| 9 * this list of conditions and the following disclaimer. |
| 10 * |
| 11 * Redistributions in binary form must reproduce the above copyright notice, |
| 12 * this list of conditions and the following disclaimer in the documentation |
| 13 * and/or other materials provided with the distribution. |
| 14 * |
| 15 * Neither the name of the NVIDIA Corporation nor the names of its contributors |
| 16 * may be used to endorse or promote products derived from this software |
| 17 * without specific prior written permission. |
| 18 * |
| 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 29 * POSSIBILITY OF SUCH DAMAGE. |
| 30 * |
| 31 */ |
| 32 |
| 33 #ifndef INCLUDED_nvrm_memmgr_H |
| 34 #define INCLUDED_nvrm_memmgr_H |
| 35 |
| 36 |
| 37 #if defined(__cplusplus) |
| 38 extern "C" |
| 39 { |
| 40 #endif |
| 41 |
| 42 #include "nvrm_init.h" |
| 43 |
| 44 #include "nvos.h" |
| 45 |
| 46 /** |
| 47 * FAQ for commonly asked questions: |
| 48 * |
| 49 * Q) Why can NvRmMemMap fail? |
| 50 * A) Some operating systems don't allow user mode applications to map arbitrary |
| 51 * memory regions, this is a huge security hole. In other environments, such |
| 52 * as simulation, its just not even possible to get a direct pointer to |
| 53 * the memory, because the simulation is in a different process. |
| 54 * |
| 55 * Q) What do I do if NvRmMemMap fails? |
| 56 * A) Driver writers have two choices. If the driver must have a mapping, for |
| 57 * example direct draw requires a pointer to the memory then the driver |
| 58 * will have to fail whatever operation it is doing and return an error. |
| 59 * The other choice is to fall back to using NvRmMemRead/Write functions |
| 60 * or NvRmMemRdxx/NvRmMemWrxx functions, which are guaranteed to succeed. |
| 61 * |
| 62 * Q) Why should I use NvRmMemMap instead of NvOsPhysicalMemMap? |
| 63 * A) NvRmMemMap will do a lot of extra work in an OS like WinCE to create |
| 64 * a new mapping to the memory in your process space. NvOsPhysicalMemMap |
| 65 * will is for mapping registers and other non-memory locations. Using |
| 66 * this API on WindowsCE will cause WindowsCE to crash. |
| 67 */ |
| 68 |
| 69 |
| 70 |
| 71 /** |
| 72 * UNRESOLVED ISSUES: |
| 73 * |
| 74 * 1. Should we have NvRmFill* APIs in addition to NvRmWrite*? Say, if you just |
| 75 * want to clear a buffer to zero? |
| 76 * |
| 77 * 2. There is currently an issue with a memhandle that is shared across |
| 78 * processes. If a MemHandle is created, and then duplicated into another |
| 79 * process uesing NvRmMemHandleGetId/NvRmMemHandleFromId it's not clear |
| 80 * what would happen if both processes tried to do an NvRmAlloc on a handle. |
| 81 * Perhaps make NvRmMemHandleGetId fail if the memory is not already |
| 82 * allocated. |
| 83 * |
| 84 * 3. It may be desirable to have more hMem query functions, for debuggability. |
| 85 * Part of the information associated with a memory buffer will live in |
| 86 * kernel space, and not be accesible efficiently from a user process. |
| 87 * Knowing which heap a buffer is in, or whether a buffer is pinned or |
| 88 * mapped could be useful. Note that queries like this could involve race |
| 89 * conditions. For example, memory could be moved from one heap to another |
| 90 * the moment after you ask what heap it's in. |
| 91 */ |
| 92 |
| 93 /** |
| 94 * @defgroup nvrm_memmgr RM Memory Management Services |
| 95 * |
| 96 * @ingroup nvddk_rm |
| 97 * |
| 98 * The APIs in this header file are intended to be used for allocating and |
| 99 * managing memory that needs to be accessed by HW devices. It is not intended |
| 100 * as a replacement for malloc() -- that functionality is provided by |
| 101 * NvOsAlloc(). If only the CPU will ever access the memory, this API is |
| 102 * probably extreme overkill for your needs. |
| 103 * |
| 104 * Memory allocated by NvRmMemAlloc() is intended to be asynchronously movable |
| 105 * by the RM at any time. Although discouraged, it is possible to permanently |
| 106 * lock down ("pin") a memory buffer such that it can never be moved. Normally, |
| 107 * however, the intent is that you would only pin a buffer for short periods of |
| 108 * time, on an as-needed basis. |
| 109 * |
| 110 * The first step to allocating memory is allocating a handle to refer to the |
| 111 * allocation. The handle has a separate lifetime from the underlying buffer. |
| 112 * Some properties of the memory, such as its size in bytes, must be declared at |
| 113 * handle allocation time and can never be changed. |
| 114 * |
| 115 * After successfully allocating a handle, you can specify properties of the |
| 116 * memory buffer that are allowed to change over time. (Currently no such |
| 117 * properties exist, but in the past a "priority" attribute existed and may |
| 118 * return some day in the future.) |
| 119 * |
| 120 * After specifying the properties of the memory buffer, it can be allocated. |
| 121 * Some additional properties, such as the set of heaps that the memory is |
| 122 * permitted to be allocated from, must be specified at allocation time and |
| 123 * cannot be changed over the buffer's lifetime of the buffer. |
| 124 * |
| 125 * The contents of memory can be examined and modified using a variety of read |
| 126 * and write APIs, such as NvRmMemRead and NvRmMemWrite. However, in some |
| 127 * cases, it is necessary for the driver or application to be able to directly |
| 128 * read or write the buffer using a pointer. In this case, the NvRmMemMap API |
| 129 * can be used to obtain such a mapping into the current process's virtual |
| 130 * address space. It is important to note that the map operation is not |
| 131 * guaranteed to succeed. Drivers that use mappings are strongly encouraged |
| 132 * to support two code paths: one for when the mapping succeeds, and one for |
| 133 * when the mapping fails. A memory buffer is allowed to be mapped multiple |
| 134 * times, and the mappings are permitted to be of subregions of the buffer if |
| 135 * desired. |
| 136 * |
| 137 * Before the memory buffer is used, it must be pinned. While pinned, the |
| 138 * buffer will not be moved, and its physical address can be safely queried. A |
| 139 * memory buffer can be pinned multiple times, and the pinning will be reference |
| 140 * counted. Assuming a valid handle and a successful allocation, pinning can |
| 141 * never fail. |
| 142 * |
| 143 * After the memory buffer is done being used, it should be unpinned. Unpinning |
| 144 * never fails. Any unpinned memory is free to be moved to any location which |
| 145 * satisfies the current properties in the handle. Drivers are strongly |
| 146 * encouraged to unpin memory when they reach a quiescent state. It is not |
| 147 * unreasonable to have a goal that all memory buffers (with the possible |
| 148 * exception of memory being continuously scanned out by the display) be |
| 149 * unpinned when the system is idle. |
| 150 * |
| 151 * The NvRmMemPin API is only one of the two ways to pin a buffer. In the case |
| 152 * of modules that are programmed through command buffers submitted through |
| 153 * host, it is not the preferred way to pin a buffer. The "RELOC" facility in |
| 154 * the stream API should be used instead if possible. It is conceivable that in |
| 155 * the distant future, the NvRmMemPin API might be removed. In such a world, |
| 156 * all graphics modules would be expected to use the RELOC API or a similar API, |
| 157 * and all IO modules would be expected to use zero-copy DMA directly from the |
| 158 * application buffer using NvOsPageLock. |
| 159 * |
| 160 * Some properties of a buffer can be changed at any point in its handle's |
| 161 * lifetime. Properties that are changed while a memory buffer is pinned will |
| 162 * have no effect until the memory is unpinned. |
| 163 * |
| 164 * After you are done with a memory buffer, you must free its handle. This |
| 165 * automatically unpins the memory (if necessary) and frees the storage (if any) |
| 166 * associated with it. |
| 167 * |
| 168 * @ingroup nvrm_memmgr |
| 169 * @{ |
| 170 */ |
| 171 |
| 172 |
| 173 /** |
| 174 * A type-safe handle for a memory buffer. |
| 175 */ |
| 176 |
| 177 typedef struct NvRmMemRec *NvRmMemHandle; |
| 178 |
| 179 /** |
| 180 * Define for invalid Physical address |
| 181 */ |
| 182 #define NV_RM_INVALID_PHYS_ADDRESS (0xffffffff) |
| 183 |
| 184 /** |
| 185 * NvRm heap identifiers. |
| 186 */ |
| 187 |
| 188 typedef enum |
| 189 { |
| 190 |
| 191 /** |
| 192 * External (non-carveout, i.e., OS-managed) memory heap. |
| 193 */ |
| 194 NvRmHeap_External = 1, |
| 195 |
| 196 /** |
| 197 * GART memory heap. The GART heap is really an alias for the External |
| 198 * heap. All GART allocations will come out of the External heap, but |
| 199 * additionally all such allocations will be mapped in the GART. Calling |
| 200 * NvRmMemGetAddress() on a buffer allocated in the GART heap will return |
| 201 * the GART address, not the underlying memory address. |
| 202 */ |
| 203 NvRmHeap_GART, |
| 204 |
| 205 /** |
| 206 * Carve-out memory heap within external memory. |
| 207 */ |
| 208 NvRmHeap_ExternalCarveOut, |
| 209 |
| 210 /** |
| 211 * IRAM memory heap. |
| 212 */ |
| 213 NvRmHeap_IRam, |
| 214 NvRmHeap_Num, |
| 215 NvRmHeap_Force32 = 0x7FFFFFFF |
| 216 } NvRmHeap; |
| 217 |
| 218 /** |
| 219 * NvRm heap statistics. See NvRmMemGetStat() for further details. |
| 220 */ |
| 221 |
| 222 typedef enum |
| 223 { |
| 224 |
| 225 /** |
| 226 * Total number of bytes reserved for the carveout heap. |
| 227 */ |
| 228 NvRmMemStat_TotalCarveout = 1, |
| 229 |
| 230 /** |
| 231 * Number of bytes used in the carveout heap. |
| 232 */ |
| 233 NvRmMemStat_UsedCarveout, |
| 234 |
| 235 /** |
| 236 * Size of the largest free block in the carveout heap. |
| 237 * Size can be less than the difference of total and |
| 238 * used memory. |
| 239 */ |
| 240 NvRmMemStat_LargestFreeCarveoutBlock, |
| 241 |
| 242 /** |
| 243 * Total number of bytes in the GART heap. |
| 244 */ |
| 245 NvRmMemStat_TotalGart, |
| 246 |
| 247 /** |
| 248 * Number of bytes reserved from the GART heap. |
| 249 */ |
| 250 NvRmMemStat_UsedGart, |
| 251 |
| 252 /** |
| 253 * Size of the largest free block in GART heap. Size can be |
| 254 * less than the difference of total and used memory. |
| 255 */ |
| 256 NvRmMemStat_LargestFreeGartBlock, |
| 257 NvRmMemStat_Num, |
| 258 NvRmMemStat_Force32 = 0x7FFFFFFF |
| 259 } NvRmMemStat; |
| 260 |
| 261 /** |
| 262 * Allocates a memory handle that can be used to specify a memory allocation |
| 263 * request and manipulate the resulting storage. |
| 264 * |
| 265 * @see NvRmMemHandleFree() |
| 266 * |
| 267 * @param hDevice An RM device handle. |
| 268 * @param phMem A pointer to an opaque handle that will be filled in with the |
| 269 * new memory handle. |
| 270 * @param Size Specifies the requested size of the memory buffer in bytes. |
| 271 * |
| 272 * @retval NvSuccess Indicates the memory handle was successfully allocated. |
| 273 * @retval NvError_InsufficientMemory Insufficient system memory exists to |
| 274 * allocate the memory handle. |
| 275 */ |
| 276 |
| 277 NvError NvRmMemHandleCreate( |
| 278 NvRmDeviceHandle hDevice, |
| 279 NvRmMemHandle * phMem, |
| 280 NvU32 Size ); |
| 281 |
| 282 /** |
| 283 * Looks up a pre-existing memory handle whose allocation was preserved through |
| 284 * the boot process. |
| 285 * |
| 286 * Looking up a memory handle is a one-time event. Once a preserved handle |
| 287 * has been successfully looked up, it may not be looked up again. Memory |
| 288 * handles created with this mechanism behave identically to memory handles |
| 289 * created through NvRmMemHandleCreate, including freeing the allocation with |
| 290 * NvRmMemHandleFree. |
| 291 * |
| 292 * @param hDevice An RM device handle. |
| 293 * @param Key The key value that was returned by the earlier call to |
| 294 * @see NvRmMemHandlePreserveHandle. |
| 295 * @param phMem A pointer to an opaque handle that will be filled in with the |
| 296 * queried memory handle, if a preserved handle matching the key is found. |
| 297 * |
| 298 * @retval NvSuccess Indicates that the key was found and the memory handle |
| 299 * was successfully created. |
| 300 * @retval NvError_InsufficientMemory Insufficient system memory was available |
| 301 * to perform the operation, or if no memory handle exists for the specified |
| 302 * Key. |
| 303 */ |
| 304 |
| 305 NvError NvRmMemHandleClaimPreservedHandle( |
| 306 NvRmDeviceHandle hDevice, |
| 307 NvU32 Key, |
| 308 NvRmMemHandle * phMem ); |
| 309 |
| 310 /** |
| 311 * Adds a memory handle to the set of memory handles which will be preserved |
| 312 * between the current OS context and a subsequent OS context. |
| 313 * |
| 314 * @param hMem The handle which will be marked for preservation |
| 315 * @param Key A key which can be used to claim the memory handle in a |
| 316 * different OS context. |
| 317 * |
| 318 * @retval NvSuccess Indicates that the memory handle will be preserved |
| 319 * @retval NvError_InsufficientMemory Insufficient system or BootArg memory |
| 320 * was avaialable to mark the memory handle as preserved. |
| 321 */ |
| 322 |
| 323 NvError NvRmMemHandlePreserveHandle( |
| 324 NvRmMemHandle hMem, |
| 325 NvU32 * Key ); |
| 326 |
| 327 /** |
| 328 * Frees a memory handle obtained from NvRmMemHandleCreate(), |
| 329 * or NvRmMemHandleFromId(). |
| 330 * |
| 331 * Fully disposing of a handle requires calling this API one time, plus one |
| 332 * time for each NvRmMemHandleFromId(). When the internal reference count of |
| 333 * the handle reaches zero, all resources for the handle will be released, even |
| 334 * if the memory is marked as pinned and/or mapped. It is the caller's |
| 335 * responsibility to ensure mappings are released before calling this API. |
| 336 * |
| 337 * When the last handle is closed, the associated storage will be implicitly |
| 338 * unpinned and freed. |
| 339 * |
| 340 * This API cannot fail. |
| 341 * |
| 342 * @see NvRmMemHandleCreate() |
| 343 * @see NvRmMemHandleFromId() |
| 344 * |
| 345 * @param hMem A previously allocated memory handle. If hMem is NULL, this API |
| 346 * has no effect. |
| 347 */ |
| 348 |
| 349 void NvRmMemHandleFree( |
| 350 NvRmMemHandle hMem ); |
| 351 |
| 352 /** |
| 353 * Allocate storage for a memory handle. The storage must satisfy: |
| 354 * 1) all specified properties in the hMem handle |
| 355 * 2) the alignment parameters |
| 356 * |
| 357 * Memory allocated by this API is intended to be used by modules which |
| 358 * control hardware devices such as media accelerators or I/O controllers. |
| 359 * |
| 360 * The memory will initially be in an unpinned state. |
| 361 * |
| 362 * Assert encountered in debug mode if alignment was not a power of two, |
| 363 * or coherency is not one of NvOsMemAttribute_Uncached, |
| 364 * NvOsMemAttribute_WriteBack or NvOsMemAttribute_WriteCombined. |
| 365 * |
| 366 * @see NvRmMemPin() |
| 367 * |
| 368 * @param hMem The memory handle to allocate storage for. |
| 369 * @param Heaps[] An array of heap enumerants that indicate which heaps the |
| 370 * memory buffer is allowed to live in. When a memory buffer is requested |
| 371 * to be allocated or needs to be moved, Heaps[0] will be the first choice |
| 372 * to allocate from or move to, Heaps[1] will be the second choice, and so |
| 373 * on until the end of the array. |
| 374 * @params NumHeaps The size of the Heaps[] array. If NumHeaps is zero, then |
| 375 * Heaps must also be NULL, and the RM will select a default list of heaps |
| 376 * on the client's behalf. |
| 377 * @param Alignment Specifies the requested alignment of the buffer, measured in |
| 378 * bytes. Must be a power of two. |
| 379 * @param Coherency Specifies the cache coherency mode desired if the memory |
| 380 * is ever mapped. |
| 381 * |
| 382 * @retval NvSuccess Indicates the memory buffer was successfully |
| 383 * allocated. |
| 384 * @retval NvError_InsufficientMemory Insufficient memory exists that |
| 385 * satisfies the specified memory handle properties and API parameters. |
| 386 * @retval NvError_AlreadyAllocated hMem already has a memory buffer |
| 387 * allocated. |
| 388 */ |
| 389 |
| 390 NvError NvRmMemAlloc( |
| 391 NvRmMemHandle hMem, |
| 392 const NvRmHeap * Heaps, |
| 393 NvU32 NumHeaps, |
| 394 NvU32 Alignment, |
| 395 NvOsMemAttribute Coherency ); |
| 396 |
| 397 /** |
| 398 * Attempts to lock down a piece of previously allocated memory. By default |
| 399 * memory is "movable" until it is pinned -- the RM is free to relocate it from |
| 400 * one address or heap to another at any time for any reason (say, to defragment |
| 401 * a heap). This function can be called to prevent the RM from moving the |
| 402 * memory. |
| 403 * |
| 404 * While a memory buffer is pinned, its physical address can safely be queried |
| 405 * with NvRmMemGetAddress(). |
| 406 * |
| 407 * This API always succeeds. |
| 408 * |
| 409 * Pins are reference counted, so the memory will remain pinned until all Pin |
| 410 * calls have had a matching Unpin call. |
| 411 * |
| 412 * Pinning and mapping a memory buffer are completely orthogonal. It is not |
| 413 * necessary to pin a buffer before mapping it. Mapping a buffer does not imply |
| 414 * that it is pinned. |
| 415 * |
| 416 * @see NvRmMemGetAddress() |
| 417 * @see NvRmMemUnpin() |
| 418 * |
| 419 * @param hMem A memory handle returned from NvRmMemHandleCreate, |
| 420 * NvRmMemHandleFromId. |
| 421 * |
| 422 * @returns The physical address of the first byte in the specified memory |
| 423 * handle's storage. If the memory is mapped through the GART, the |
| 424 * GART address will be returned, not the address of the underlying memory. |
| 425 */ |
| 426 |
| 427 NvU32 NvRmMemPin( |
| 428 NvRmMemHandle hMem ); |
| 429 |
| 430 /** |
| 431 * A multiple handle version of NvRmMemPin to reduce kernel trap overhead. |
| 432 * |
| 433 * @see NvRmMemPin |
| 434 * |
| 435 * @param hMems An array of memory handles to pin |
| 436 * @param Addrs An arary of address (the result of the pin) |
| 437 * @param Count The number of handles and addresses |
| 438 */ |
| 439 |
| 440 void NvRmMemPinMult( |
| 441 NvRmMemHandle * hMems, |
| 442 NvU32 * Addrs, |
| 443 NvU32 Count ); |
| 444 |
| 445 /** |
| 446 * Retrieves a physical address for an hMem handle and an offset into that |
| 447 * handle's memory buffer. |
| 448 * |
| 449 * If the memory referred to by hMem is not pinned, the return value is |
| 450 * undefined, and an assert will fire in a debug build. |
| 451 * |
| 452 * @see NvRmMemPin() |
| 453 * |
| 454 * @param hMem A memory handle returned from NvRmMemHandleCreate/FromId. |
| 455 * @param Offset The offset into the memory buffer for which the |
| 456 * address is desired. |
| 457 * |
| 458 * @returns The physical address of the specified byte within the specified |
| 459 * memory handle's storage. If the memory is mapped through the GART, the |
| 460 * GART address will be returned, not the address of the underlying memory. |
| 461 */ |
| 462 |
| 463 NvU32 NvRmMemGetAddress( |
| 464 NvRmMemHandle hMem, |
| 465 NvU32 Offset ); |
| 466 |
| 467 /** |
| 468 * Unpins a memory buffer so that it is once again free to be moved. Pins are |
| 469 * reference counted, so the memory will not become movable until all Pin calls |
| 470 * have had a matching Unpin call. |
| 471 * |
| 472 * If the pin count is already zero when this API is called, the behavior is |
| 473 * undefined, and an assert will fire in a debug build. |
| 474 * |
| 475 * This API cannot fail. |
| 476 * |
| 477 * @see NvRmMemPin() |
| 478 * |
| 479 * @param hMem A memory handle returned from NvRmMemHandleCreate/FromId. |
| 480 * If hMem is NULL, this API will do nothing. |
| 481 */ |
| 482 |
| 483 void NvRmMemUnpin( |
| 484 NvRmMemHandle hMem ); |
| 485 |
| 486 /** |
| 487 * A multiple handle version of NvRmMemUnpin to reduce kernel trap overhead. |
| 488 * |
| 489 * @see NvRmMemPin |
| 490 * |
| 491 * @param hMems An array of memory handles to unpin |
| 492 * @param Count The number of handles and addresses |
| 493 */ |
| 494 |
| 495 void NvRmMemUnpinMult( |
| 496 NvRmMemHandle * hMems, |
| 497 NvU32 Count ); |
| 498 |
| 499 /** |
| 500 * Attempts to map a memory buffer into the process's virtual address space. |
| 501 * |
| 502 * It is recommended that mappings be short-lived as some systems have a limited |
| 503 * number of concurrent mappings that can be supported, or because virtual |
| 504 * address space may be scarce. |
| 505 * |
| 506 * It is legal to have multiple concurrent mappings of a single memory buffer. |
| 507 * |
| 508 * Pinning and mapping a memory buffer are completely orthogonal. It is not |
| 509 * necessary to pin a buffer before mapping it. Mapping a buffer does not imply |
| 510 * that it is pinned. |
| 511 * |
| 512 * There is no guarantee that the mapping will succeed. For example, on some |
| 513 * operating systems, the OS's security mechanisms make it impossible for |
| 514 * untrusted applications to map certain types of memory. A mapping might also |
| 515 * fail due to exhaustion of memory or virtual address space. Therefore, you |
| 516 * must implement code paths that can handle mapping failures. For example, if |
| 517 * the mapping fails, you may want to fall back to using NvRmMemRead() and |
| 518 * NvRmMemWrite(). Alternatively, you may want to consider avoiding the use of |
| 519 * this API altogether, unless there is a compelling reason why you need |
| 520 * mappings. |
| 521 * |
| 522 * @see NvRmMemUnmap() |
| 523 * |
| 524 * @param hMem A memory handle returned from NvRmMemHandleCreate/FromId. |
| 525 * @param Offset Byte offset within the memory buffer to start the map at. |
| 526 * @param Size Size in bytes of mapping requested. Must be greater than 0. |
| 527 * @param Flags Special flags -- use NVOS_MEM_* (see nvos.h for details) |
| 528 * @param pVirtAddr If the mapping is successful, provides a virtual |
| 529 * address through which the memory buffer can be accessed. |
| 530 * |
| 531 * @retval NvSuccess Indicates that the memory was successfully mapped. |
| 532 * @retval NvError_InsufficientMemory The mapping was unsuccessful. |
| 533 * This can occur if it is impossible to map the memory, or if offset+size |
| 534 * is greater than the size of the buffer referred to by hMem. |
| 535 * @retval NvError_NotSupported Mapping not allowed (e.g., for GART heap) |
| 536 */ |
| 537 |
| 538 NvError |
| 539 NvRmMemMap( |
| 540 NvRmMemHandle hMem, |
| 541 NvU32 Offset, |
| 542 NvU32 Size, |
| 543 NvU32 Flags, |
| 544 void **pVirtAddr); |
| 545 |
| 546 /** |
| 547 * Unmaps a memory buffer from the process's virtual address space. This API |
| 548 * cannot fail. |
| 549 * |
| 550 * If hMem is NULL, this API will do nothing. |
| 551 * If pVirtAddr is NULL, this API will do nothing. |
| 552 * |
| 553 * @see NvRmMemMap() |
| 554 * |
| 555 * @param hMem A memory handle returned from NvRmMemHandleCreate/FromId. |
| 556 * @param pVirtAddr The virtual address returned by a previous call to |
| 557 * NvRmMemMap with hMem. |
| 558 * @param Size The size in bytes of the mapped region. Must be the same as the |
| 559 * Size value originally passed to NvRmMemMap. |
| 560 */ |
| 561 |
| 562 void NvRmMemUnmap(NvRmMemHandle hMem, void *pVirtAddr, NvU32 Size); |
| 563 |
| 564 /** |
| 565 * Reads 8 bits of data from a buffer. This API cannot fail. |
| 566 * |
| 567 * If hMem refers to an unallocated memory buffer, this function's behavior is |
| 568 * undefined and an assert will trigger in a debug build. |
| 569 * |
| 570 * @param hMem A memory handle returned from NvRmMemHandleCreate/FromId. |
| 571 * @param Offset Byte offset relative to the base of hMem. |
| 572 * May be arbitrarily aligned -- need not be a multiple of 2 or 4. |
| 573 * |
| 574 * @returns The value read from the memory location. |
| 575 */ |
| 576 |
| 577 NvU8 NvRmMemRd08(NvRmMemHandle hMem, NvU32 Offset); |
| 578 |
| 579 /** |
| 580 * Reads 16 bits of data from a buffer. This API cannot fail. |
| 581 * |
| 582 * If hMem refers to an unallocated memory buffer, this function's behavior is |
| 583 * undefined and an assert will trigger in a debug build. |
| 584 * |
| 585 * @param hMem A memory handle returned from NvRmMemHandleCreate/FromId. |
| 586 * @param Offset Byte offset relative to the base of hMem. |
| 587 * Must be a multiple of 2. |
| 588 * |
| 589 * @returns The value read from the memory location. |
| 590 */ |
| 591 |
| 592 NvU16 NvRmMemRd16(NvRmMemHandle hMem, NvU32 Offset); |
| 593 |
| 594 /** |
| 595 * Reads 32 bits of data from a buffer. This API cannot fail. |
| 596 * |
| 597 * If hMem refers to an unallocated memory buffer, this function's behavior is |
| 598 * undefined and an assert will trigger in a debug build. |
| 599 * |
| 600 * @param hMem A memory handle returned from NvRmMemHandleCreate/FromId. |
| 601 * @param Offset Byte offset relative to the base of hMem. |
| 602 * Must be a multiple of 4. |
| 603 * |
| 604 * @returns The value read from the memory location. |
| 605 */ |
| 606 |
| 607 NvU32 NvRmMemRd32(NvRmMemHandle hMem, NvU32 Offset); |
| 608 |
| 609 /** |
| 610 * Writes 8 bits of data to a buffer. This API cannot fail. |
| 611 * |
| 612 * If hMem refers to an unallocated memory buffer, this function's behavior is |
| 613 * undefined and an assert will trigger in a debug build. |
| 614 * |
| 615 * @param hMem A memory handle returned from NvRmMemHandleCreate/FromId. |
| 616 * @param Offset Byte offset relative to the base of hMem. |
| 617 * May be arbitrarily aligned -- need not be a multiple of 2 or 4. |
| 618 * @param Data The data to write to the memory location. |
| 619 */ |
| 620 |
| 621 void NvRmMemWr08(NvRmMemHandle hMem, NvU32 Offset, NvU8 Data); |
| 622 |
| 623 /** |
| 624 * Writes 16 bits of data to a buffer. This API cannot fail. |
| 625 * |
| 626 * If hMem refers to an unallocated memory buffer, this function's behavior is |
| 627 * undefined and an assert will trigger in a debug build. |
| 628 * |
| 629 * @param hMem A memory handle returned from NvRmMemHandleCreate/FromId. |
| 630 * @param Offset Byte offset relative to the base of hMem. |
| 631 * Must be a multiple of 2. |
| 632 * @param Data The data to write to the memory location. |
| 633 */ |
| 634 |
| 635 void NvRmMemWr16(NvRmMemHandle hMem, NvU32 Offset, NvU16 Data); |
| 636 |
| 637 /** |
| 638 * Writes 32 bits of data to a buffer. This API cannot fail. |
| 639 * |
| 640 * If hMem refers to an unallocated memory buffer, this function's behavior is |
| 641 * undefined and an assert will trigger in a debug build. |
| 642 * |
| 643 * @param hMem A memory handle returned from NvRmMemHandleCreate/FromId. |
| 644 * @param Offset Byte offset relative to the base of hMem. |
| 645 * Must be a multiple of 4. |
| 646 * @param Data The data to write to the memory location. |
| 647 */ |
| 648 |
| 649 void NvRmMemWr32(NvRmMemHandle hMem, NvU32 Offset, NvU32 Data); |
| 650 |
| 651 /** |
| 652 * Reads a block of data from a buffer. This API cannot fail. |
| 653 * |
| 654 * If hMem refers to an unallocated memory buffer, this function's behavior is |
| 655 * undefined and an assert will trigger in a debug build. |
| 656 * |
| 657 * @param hMem A memory handle returned from NvRmMemHandleCreate/FromId. |
| 658 * @param Offset Byte offset relative to the base of hMem. |
| 659 * May be arbitrarily aligned -- need not be a multiple of 2 or 4. |
| 660 * @param pDst The buffer where the data should be placed. |
| 661 * May be arbitrarily aligned -- need not be located at a word boundary. |
| 662 * @param Size The number of bytes of data to be read. |
| 663 * May be arbitrarily sized -- need not be a multiple of 2 or 4. |
| 664 */ |
| 665 void NvRmMemRead(NvRmMemHandle hMem, NvU32 Offset, void *pDst, NvU32 Size); |
| 666 |
| 667 /** |
| 668 * Writes a block of data to a buffer. This API cannot fail. |
| 669 * |
| 670 * If hMem refers to an unallocated memory buffer, this function's behavior is |
| 671 * undefined and an assert will trigger in a debug build. |
| 672 * |
| 673 * @param hMem A memory handle returned from NvRmMemHandleCreate/FromId. |
| 674 * @param Offset Byte offset relative to the base of hMem. |
| 675 * May be arbitrarily aligned -- need not be a multiple of 2 or 4. |
| 676 * @param pSrc The buffer to obtain the data from. |
| 677 * May be arbitrarily aligned -- need not be located at a word boundary. |
| 678 * @param Size The number of bytes of data to be written. |
| 679 * May be arbitrarily sized -- need not be a multiple of 2 or 4. |
| 680 */ |
| 681 void NvRmMemWrite( |
| 682 NvRmMemHandle hMem, |
| 683 NvU32 Offset, |
| 684 const void *pSrc, |
| 685 NvU32 Size); |
| 686 |
| 687 /** |
| 688 * Reads a strided series of blocks of data from a buffer. This API cannot |
| 689 * fail. |
| 690 * |
| 691 * The total number of bytes copied is Count*ElementSize. |
| 692 * |
| 693 * If hMem refers to an unallocated memory buffer, this function's behavior is |
| 694 * undefined and an assert will trigger in a debug build. |
| 695 * |
| 696 * @param hMem A memory handle returned from NvRmMemHandleCreate. |
| 697 * @param Offset Byte offset relative to the base of hMem. |
| 698 * May be arbitrarily aligned -- need not be a multiple of 2 or 4. |
| 699 * @param SrcStride The number of bytes separating each source element. |
| 700 * May be arbitrarily aligned -- need not be a multiple of 2 or 4. |
| 701 * @param pDst The buffer where the data should be placed. |
| 702 * May be arbitrarily aligned -- need not be located at a word boundary. |
| 703 * @param DstStride The number of bytes separating each destination element. |
| 704 * May be arbitrarily aligned -- need not be a multiple of 2 or 4. |
| 705 * @param ElementSize The number of bytes in each element. |
| 706 * May be arbitrarily sized -- need not be a multiple of 2 or 4. |
| 707 * @param Count The number of destination elements. |
| 708 */ |
| 709 void NvRmMemReadStrided( |
| 710 NvRmMemHandle hMem, |
| 711 NvU32 Offset, |
| 712 NvU32 SrcStride, |
| 713 void *pDst, |
| 714 NvU32 DstStride, |
| 715 NvU32 ElementSize, |
| 716 NvU32 Count); |
| 717 |
| 718 /** |
| 719 * Writes a strided series of blocks of data to a buffer. This API cannot |
| 720 * fail. |
| 721 * |
| 722 * The total number of bytes copied is Count*ElementSize. |
| 723 * |
| 724 * If hMem refers to an unallocated memory buffer, this function's behavior is |
| 725 * undefined and an assert will trigger in a debug build. |
| 726 * |
| 727 * @param hMem A memory handle returned from NvRmMemHandleCreate. |
| 728 * @param Offset Byte offset relative to the base of hMem. |
| 729 * May be arbitrarily aligned -- need not be a multiple of 2 or 4. |
| 730 * @param DstStride The number of bytes separating each destination element. |
| 731 * May be arbitrarily aligned -- need not be a multiple of 2 or 4. |
| 732 * @param pSrc The buffer to obtain the data from. |
| 733 * May be arbitrarily aligned -- need not be located at a word boundary. |
| 734 * @param SrcStride The number of bytes separating each source element. |
| 735 * May be arbitrarily aligned -- need not be a multiple of 2 or 4. |
| 736 * @param ElementSize The number of bytes in each element. |
| 737 * May be arbitrarily sized -- need not be a multiple of 2 or 4. |
| 738 * @param Count The number of source elements. |
| 739 */ |
| 740 void NvRmMemWriteStrided( |
| 741 NvRmMemHandle hMem, |
| 742 NvU32 Offset, |
| 743 NvU32 DstStride, |
| 744 const void *pSrc, |
| 745 NvU32 SrcStride, |
| 746 NvU32 ElementSize, |
| 747 NvU32 Count); |
| 748 |
| 749 /** |
| 750 * Moves (copies) a block of data to a different (or the same) hMem. This |
| 751 * API cannot fail. Overlapping copies are supported. |
| 752 * |
| 753 * NOTE: While easy to use, this is NOT the fastest way to copy memory. Using |
| 754 * the 2D engine to perform a blit can be much faster than this function. |
| 755 * |
| 756 * If hDstMem or hSrcMem refers to an unallocated memory buffer, this function's |
| 757 * behavior is undefined and an assert will trigger in a debug build. |
| 758 * |
| 759 * @param hDstMem A memory handle returned from NvRmMemHandleCreate/FromId. |
| 760 * @param DstOffset Byte offset relative to the base of hMem. |
| 761 * May be arbitrarily aligned -- need not be a multiple of 2 or 4. |
| 762 * @param hSrcMem A memory handle returned from NvRmMemHandleCreate/FromId. |
| 763 * @param SrcOffset Byte offset relative to the base of hMem. |
| 764 * May be arbitrarily aligned -- need not be a multiple of 2 or 4. |
| 765 * @param Size The number of bytes of data to be copied from hSrcMem to hDstMem. |
| 766 * May be arbitrarily sized -- need not be a multiple of 2 or 4. |
| 767 */ |
| 768 |
| 769 void NvRmMemMove( |
| 770 NvRmMemHandle hDstMem, |
| 771 NvU32 DstOffset, |
| 772 NvRmMemHandle hSrcMem, |
| 773 NvU32 SrcOffset, |
| 774 NvU32 Size ); |
| 775 |
| 776 /** |
| 777 * Optionally writes back and/or invalidates a range of the memory from the |
| 778 * data cache, if applicable. Does nothing for memory that was not allocated |
| 779 * as cached. Memory must be mapped into the calling process. |
| 780 * |
| 781 * @param hMem A memory handle returned from NvRmMemHandleCreate/FromId. |
| 782 * @param pMapping Starting address (must be within the mapped region of the |
| 783 hMem) to clean |
| 784 * @param Size The number of bytes of data to be written. |
| 785 * May be arbitrarily sized -- need not be a multiple of 2 or 4. |
| 786 */ |
| 787 |
| 788 void NvRmMemCacheMaint( |
| 789 NvRmMemHandle hMem, |
| 790 void *pMapping, |
| 791 NvU32 Size, |
| 792 NvBool WriteBack, |
| 793 NvBool Invalidate); |
| 794 |
| 795 /** |
| 796 * Get the size of the buffer associated with a memory handle. |
| 797 * |
| 798 * @param hMem A memory handle returned from NvRmMemHandleCreate/FromId. |
| 799 * |
| 800 * @returns Size in bytes of memory allocated for this handle. |
| 801 */ |
| 802 |
| 803 NvU32 NvRmMemGetSize( |
| 804 NvRmMemHandle hMem ); |
| 805 |
| 806 /** |
| 807 * Get the alignment of the buffer associated with a memory handle. |
| 808 * |
| 809 * @param hMem A memory handle returned from NvRmMemHandleCreate/FromId. |
| 810 * |
| 811 * @returns Alignment in bytes of memory allocated for this handle. |
| 812 */ |
| 813 |
| 814 NvU32 NvRmMemGetAlignment( |
| 815 NvRmMemHandle hMem ); |
| 816 |
| 817 /** |
| 818 * Queries the maximum cache line size (in bytes) for all of the caches |
| 819 * L1 and L2 in the system |
| 820 * |
| 821 * @returns The largest cache line size of the system |
| 822 */ |
| 823 |
| 824 NvU32 NvRmMemGetCacheLineSize( |
| 825 void ); |
| 826 |
| 827 /** |
| 828 * Queries for the heap type associated with a given memory handle. Also |
| 829 * returns base physical address for the buffer, if the type is carveout or |
| 830 * GART. For External type, this parameter does not make sense. |
| 831 * |
| 832 * @param hMem A memory handle returned from NvRmMemHandleCreate/FromId. |
| 833 * @param BasePhysAddr Output parameter receives the physical address of the |
| 834 * buffer. |
| 835 * |
| 836 * @returns The heap type allocated for this memory handle. |
| 837 */ |
| 838 |
| 839 NvRmHeap NvRmMemGetHeapType( |
| 840 NvRmMemHandle hMem, |
| 841 NvU32 * BasePhysAddr ); |
| 842 |
| 843 /** |
| 844 * Dynamically allocates memory, on CPU this will result in a call to |
| 845 * NvOsAlloc and on AVP, memAPI's are used to allocate memory. |
| 846 * @param size The memory size to be allocated. |
| 847 * @returns Pointer to the allocated buffer. |
| 848 */ |
| 849 void* NvRmHostAlloc(size_t Size); |
| 850 |
| 851 /** |
| 852 * Frees a dynamic memory allocation, previously allocated using NvRmHostAlloc. |
| 853 * |
| 854 * @param ptr The pointer to buffer which need to be deallocated. |
| 855 */ |
| 856 void NvRmHostFree(void* ptr); |
| 857 |
| 858 /** |
| 859 * This is generally not a publically available function. It is only available |
| 860 * on WinCE to the nvrm device driver. Attempting to use this function will |
| 861 * result in a linker error, you should use NvRmMemMap instead, which will do |
| 862 * the "right" thing for all platforms. |
| 863 * |
| 864 * Under WinCE NvRmMemMap has a custom marshaller, the custom marshaller will |
| 865 * do the following: |
| 866 * - Allocate virtual space |
| 867 * - ioctl to the nvrm driver |
| 868 * - nvrm driver will create a mapping from the allocated buffer to |
| 869 * the newly allocated virtual space. |
| 870 */ |
| 871 NvError NvRmMemMapIntoCallerPtr( |
| 872 NvRmMemHandle hMem, |
| 873 void *pCallerPtr, |
| 874 NvU32 Offset, |
| 875 NvU32 Size); |
| 876 |
| 877 /** |
| 878 * Create a unique identifier which can be used from any process/processor |
| 879 * to generate a new memory handle. This can be used to share a memory handle |
| 880 * between processes, or from AVP and CPU. |
| 881 * |
| 882 * Typical usage would be |
| 883 * GetId |
| 884 * Pass Id to client process/procssor |
| 885 * Client calls: NvRmMemHandleFromId |
| 886 * |
| 887 * See Also NvRmMemHandleFromId |
| 888 * |
| 889 * NOTE: Getting an id _does not_ increment the reference count of the |
| 890 * memory handle. You must be sure that whichever process/processor |
| 891 * that is passed an Id calls @NvRmMemHandleFromId@ before you free |
| 892 * a handle. |
| 893 * |
| 894 * @param hMem The memory handle to retrieve the id for. |
| 895 * @returns a unique id that identifies the memory handle. |
| 896 */ |
| 897 |
| 898 NvU32 NvRmMemGetId( |
| 899 NvRmMemHandle hMem ); |
| 900 |
| 901 /** |
| 902 * Create a new memory handle, which refers to the memory handle identified |
| 903 * by @id@. This function will increment the reference count on the handle. |
| 904 * |
| 905 * See Also NvRmMemGetId |
| 906 * |
| 907 * @param id value that refers to a memory handle, returned from NvRmMemGetId |
| 908 * @param hMem The newly created memory handle |
| 909 * @returns NvSuccess if a unique id is created. |
| 910 */ |
| 911 |
| 912 NvError NvRmMemHandleFromId( |
| 913 NvU32 id, |
| 914 NvRmMemHandle * hMem ); |
| 915 |
| 916 /** |
| 917 * Get a memory statistics value. |
| 918 * |
| 919 * Querying values may have an effect on system performance and may include |
| 920 * processing, like heap traversal. |
| 921 * |
| 922 * @param Stat NvRmMemStat value that chooses the value to return. |
| 923 * @param Result Result, if the call was successful. Otherwise value |
| 924 * is not touched. |
| 925 * @returns NvSuccess on success, NvError_BadParameter if Stat is |
| 926 * not a valid value, NvError_NotSupported if the Stat is |
| 927 * not available for some reason, or |
| 928 * NvError_InsufficientMemory. |
| 929 */ |
| 930 |
| 931 NvError NvRmMemGetStat( |
| 932 NvRmMemStat Stat, |
| 933 NvS32 * Result ); |
| 934 |
| 935 #define NVRM_MEM_CHECK_ID 0 |
| 936 #define NVRM_MEM_TRACE 0 |
| 937 #if NVRM_MEM_TRACE |
| 938 #ifndef NV_IDL_IS_STUB |
| 939 #ifndef NV_IDL_IS_DISPATCH |
| 940 #define NvRmMemHandleCreate(d,m,s) \ |
| 941 NvRmMemHandleCreateTrace(d,m,s,__FILE__,__LINE__) |
| 942 #define NvRmMemHandleFree(m) \ |
| 943 NvRmMemHandleFreeTrace(m,__FILE__,__LINE__) |
| 944 #define NvRmMemGetId(m) \ |
| 945 NvRmMemGetIdTrace(m,__FILE__,__LINE__) |
| 946 #define NvRmMemHandleFromId(i,m) \ |
| 947 NvRmMemHandleFromIdTrace(i,m,__FILE__,__LINE__) |
| 948 |
| 949 static NV_INLINE NvError NvRmMemHandleCreateTrace( |
| 950 NvRmDeviceHandle hDevice, |
| 951 NvRmMemHandle * phMem, |
| 952 NvU32 Size, |
| 953 const char *file, |
| 954 NvU32 line) |
| 955 { |
| 956 NvError err; |
| 957 err = (NvRmMemHandleCreate)(hDevice, phMem, Size); |
| 958 NvOsDebugPrintf("RMMEMTRACE: Create %08x at %s:%d %s\n", |
| 959 (int)*phMem, |
| 960 file, |
| 961 line, |
| 962 err?"FAILED":""); |
| 963 return err; |
| 964 } |
| 965 |
| 966 static NV_INLINE void NvRmMemHandleFreeTrace( |
| 967 NvRmMemHandle hMem, |
| 968 const char *file, |
| 969 NvU32 line) |
| 970 { |
| 971 NvOsDebugPrintf("RMMEMTRACE: Free %08x at %s:%d\n", |
| 972 (int)hMem, |
| 973 file, |
| 974 line); |
| 975 (NvRmMemHandleFree)(hMem); |
| 976 } |
| 977 |
| 978 static NV_INLINE NvU32 NvRmMemGetIdTrace( |
| 979 NvRmMemHandle hMem, |
| 980 const char *file, |
| 981 NvU32 line) |
| 982 { |
| 983 NvOsDebugPrintf("RMMEMTRACE: GetId %08x at %s:%d\n", |
| 984 (int)hMem, |
| 985 file, |
| 986 line); |
| 987 return (NvRmMemGetId)(hMem); |
| 988 } |
| 989 |
| 990 static NV_INLINE NvError NvRmMemHandleFromIdTrace( |
| 991 NvU32 id, |
| 992 NvRmMemHandle * hMem, |
| 993 const char *file, |
| 994 NvU32 line) |
| 995 { |
| 996 NvOsDebugPrintf("RMMEMTRACE: FromId %08x at %s:%d\n", |
| 997 id, |
| 998 file, |
| 999 line); |
| 1000 return (NvRmMemHandleFromId)(id,hMem); |
| 1001 } |
| 1002 |
| 1003 #endif // NV_IDL_IS_DISPATCH |
| 1004 #endif // NV_IDL_IS_STUB |
| 1005 #endif // NVRM_MEM_TRACE |
| 1006 |
| 1007 /** @} */ |
| 1008 |
| 1009 #if defined(__cplusplus) |
| 1010 } |
| 1011 #endif |
| 1012 |
| 1013 #endif |
OLD | NEW |