147 lines
5.7 KiB
C
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;
|