Files
nt-lite/code/public/ntlite/ddk/dma.h
T

147 lines
5.7 KiB
C

// Public nt-lite DMA declarations.
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <ntlite/status.h>
struct DEVICE_OBJECT;
struct PROCESS;
typedef struct IO_DMA_ADAPTER IO_DMA_ADAPTER;
typedef struct IO_DMA_BUFFER IO_DMA_BUFFER;
typedef struct IO_DMA_MAPPING IO_DMA_MAPPING;
typedef struct MM_PINNED_MEMORY MM_PINNED_MEMORY;
typedef enum IO_DMA_DIRECTION {
IoDmaToDevice = 1,
IoDmaFromDevice,
IoDmaBidirectional
} IO_DMA_DIRECTION;
// Fails a streaming mapping instead of allocating a bounce buffer.
#define IO_DMA_MAP_NO_BOUNCE 0x00000001u
// Describes immutable constraints shared by one device adapter. Address,
// alignment, and boundary limits apply to common buffers. Segment limits apply
// to streaming mappings. Zero selects the unconstrained default for each field.
typedef struct IO_DMA_REQUIREMENTS {
uint64_t MaximumDeviceAddress;
size_t Alignment;
size_t Boundary;
size_t MaximumSegmentLength;
uint32_t MaximumSegments;
} IO_DMA_REQUIREMENTS;
// Describes one device-visible span in a streaming mapping.
typedef struct IO_DMA_SEGMENT {
uint64_t DeviceAddress;
size_t Length;
} IO_DMA_SEGMENT;
// Reports cumulative activity and live ownership for validation.
typedef struct IO_DMA_STATS {
uint64_t AdaptersCreated;
uint64_t AdaptersDestroyed;
uint64_t AdaptersInUse;
uint64_t CommonBuffersAllocated;
uint64_t CommonBuffersFreed;
uint64_t CommonBuffersInUse;
uint64_t CommonBufferBytesInUse;
uint64_t PinnedKernelRanges;
uint64_t PinnedUserRanges;
uint64_t PinnedRangesReleased;
uint64_t PinnedRangesInUse;
uint64_t PinnedPagesInUse;
uint64_t StreamingMappings;
uint64_t StreamingMappingsUnmapped;
uint64_t StreamingMappingsInUse;
uint64_t DirectMappings;
uint64_t BounceMappings;
uint64_t BounceBytesCopiedToDevice;
uint64_t BounceBytesCopiedToCpu;
uint64_t FailedAllocations;
uint64_t FailedMappings;
} IO_DMA_STATS;
// Driver-visible DMA services. Device addresses are intentionally distinct
// from physical addresses even while the first implementation maps them one to
// one on x86-64.
typedef struct NTL_DDK_DMA {
// Returns the one adapter and requirement set owned by a device object.
KSTATUS (*GetAdapter)(struct DEVICE_OBJECT* device,
const IO_DMA_REQUIREMENTS* requirements,
IO_DMA_ADAPTER** outAdapter);
// Releases one caller-owned adapter reference.
void (*PutAdapter)(IO_DMA_ADAPTER* adapter);
// Allocates coherent memory with stable CPU and base device addresses. The
// caller must quiesce every device reference before releasing the buffer.
KSTATUS (*AllocateCommonBuffer)(IO_DMA_ADAPTER* adapter,
size_t size,
size_t alignment,
IO_DMA_BUFFER** outBuffer);
// Releases a coherent common buffer.
void (*FreeCommonBuffer)(IO_DMA_BUFFER* buffer);
// Returns the stable CPU address of a common buffer.
void* (*GetCommonBufferAddress)(const IO_DMA_BUFFER* buffer);
// Returns the stable device address of a common buffer.
uint64_t (*GetCommonBufferDeviceAddress)(const IO_DMA_BUFFER* buffer);
// Returns the caller-requested size of a common buffer.
size_t (*GetCommonBufferSize)(const IO_DMA_BUFFER* buffer);
// Stabilizes a kernel range for one or more streaming mappings. Pinning
// preserves the pages, but does not transfer ownership to a device.
KSTATUS (*PinKernelMemory)(void* address,
size_t size,
IO_DMA_DIRECTION direction,
MM_PINNED_MEMORY** outMemory);
// Stabilizes a process-owned user range for one or more mappings. The
// descriptor retains the process and range until the final unpin.
KSTATUS (*PinUserMemory)(struct PROCESS* process,
void* address,
size_t size,
IO_DMA_DIRECTION direction,
MM_PINNED_MEMORY** outMemory);
// Releases one pinned-memory reference after all mappings leave.
void (*UnpinMemory)(MM_PINNED_MEMORY* memory);
// Maps a pinned subrange and creates a constrained segment list. A new
// mapping begins CPU-owned and requires external operation serialization.
KSTATUS (*MapPinnedMemory)(IO_DMA_ADAPTER* adapter,
MM_PINNED_MEMORY* memory,
size_t offset,
size_t length,
IO_DMA_DIRECTION direction,
uint32_t flags,
IO_DMA_MAPPING** outMapping);
// Releases a mapping and performs a final receive-side bounce copy only
// when ownership was transferred to the device and not returned to the CPU.
void (*UnmapMemory)(IO_DMA_MAPPING* mapping);
// Transfers mapping ownership from the CPU to the device. Streaming DMA
// must not begin before this operation succeeds.
KSTATUS (*SynchronizeForDevice)(IO_DMA_MAPPING* mapping);
// Transfers mapping ownership from the device to the CPU. CPU readers must
// not consume receive data before this operation succeeds.
KSTATUS (*SynchronizeForCpu)(IO_DMA_MAPPING* mapping);
// Returns the immutable segment count owned by a mapping.
uint32_t (*GetSegmentCount)(const IO_DMA_MAPPING* mapping);
// Returns the immutable segment array owned by a mapping.
const IO_DMA_SEGMENT* (*GetSegments)(const IO_DMA_MAPPING* mapping);
// Copies current DMA counters into caller-owned storage.
void (*QueryStats)(IO_DMA_STATS* outStats);
} NTL_DDK_DMA;