/// <summary> /// Maps a given range of pages to the specified CPU virtual address. /// </summary> /// <remarks> /// All addresses and sizes must be page aligned. /// </remarks> /// <param name="pa">CPU virtual address to map into</param> /// <param name="va">GPU virtual address to be mapped</param> /// <param name="size">Size in bytes of the mapping</param> public void Map(ulong pa, ulong va, ulong size) { lock (_pageTable) { MemoryUnmapped?.Invoke(this, new UnmapEventArgs(va, size)); for (ulong offset = 0; offset < size; offset += PageSize) { SetPte(va + offset, pa + offset); } } }
/// <summary> /// Frees memory that was previously allocated by a map or reserved. /// </summary> /// <param name="va">GPU virtual address to free</param> /// <param name="size">Size in bytes of the region being freed</param> public void Free(ulong va, ulong size) { lock (_pageTable) { // Event handlers are not expected to be thread safe. MemoryUnmapped?.Invoke(this, new UnmapEventArgs(va, size)); for (ulong offset = 0; offset < size; offset += PageSize) { SetPte(va + offset, PteUnmapped); } } }
/// <summary> /// Reserves memory at a fixed GPU memory location. /// This prevents the reserved region from being used for memory allocation for map. /// </summary> /// <param name="va">GPU virtual address to reserve</param> /// <param name="size">Size in bytes of the reservation</param> /// <returns>GPU virtual address of the reservation, or an all ones mask in case of failure</returns> public ulong ReserveFixed(ulong va, ulong size) { lock (_pageTable) { MemoryUnmapped?.Invoke(this, new UnmapEventArgs(va, size)); for (ulong offset = 0; offset < size; offset += PageSize) { if (IsPageInUse(va + offset)) { return(PteUnmapped); } } for (ulong offset = 0; offset < size; offset += PageSize) { SetPte(va + offset, PteReserved); } } return(va); }