mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
Complete reimplementation of HAL DMA routines.
The key changes are * Proper support for bus-master device adapters. * Real implementation of map registers. * Basic support for emulating scatter/gather DMA on devices that don't support it in hardware. * Support for transfers that aren't page aligned. * Proper detection and support of EISA DMA controllers. * Fixed prototype for HalFlushCommonBuffer. svn path=/trunk/; revision=17470
This commit is contained in:
parent
1fb85e029e
commit
a0b8ef87a8
8 changed files with 2239 additions and 1484 deletions
|
@ -211,10 +211,7 @@ HalFlushCommonBuffer(
|
||||||
ULONG Unknown2,
|
ULONG Unknown2,
|
||||||
ULONG Unknown3,
|
ULONG Unknown3,
|
||||||
ULONG Unknown4,
|
ULONG Unknown4,
|
||||||
ULONG Unknown5,
|
ULONG Unknown5)
|
||||||
ULONG Unknown6,
|
|
||||||
ULONG Unknown7,
|
|
||||||
ULONG Unknown8)
|
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ HalDisableSystemInterrupt@8
|
||||||
HalDisplayString@4
|
HalDisplayString@4
|
||||||
HalEnableSystemInterrupt@12
|
HalEnableSystemInterrupt@12
|
||||||
HalEndSystemInterrupt@8
|
HalEndSystemInterrupt@8
|
||||||
HalFlushCommonBuffer@32
|
HalFlushCommonBuffer@20
|
||||||
HalFreeCommonBuffer@24
|
HalFreeCommonBuffer@24
|
||||||
HalGetAdapter@8
|
HalGetAdapter@8
|
||||||
HalGetBusData@20
|
HalGetBusData@20
|
||||||
|
|
|
@ -1,717 +0,0 @@
|
||||||
/* $Id$
|
|
||||||
*
|
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
|
||||||
* PROJECT: ReactOS kernel
|
|
||||||
* FILE: hal/x86/adapter.c (from ntoskrnl/io/adapter.c)
|
|
||||||
* PURPOSE: DMA handling
|
|
||||||
* PROGRAMMERS: David Welch (welch@mcmail.com)
|
|
||||||
* Vizzini (vizzini@plasmic.com)
|
|
||||||
* UPDATE HISTORY:
|
|
||||||
* Created 22/05/98
|
|
||||||
* 18-Oct-2003 Vizzini DMA support modifications
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* INCLUDES *****************************************************************/
|
|
||||||
|
|
||||||
#include <hal.h>
|
|
||||||
#define NDEBUG
|
|
||||||
#include <debug.h>
|
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
|
||||||
|
|
||||||
/* NOTE: IoAllocateAdapterChannel in NTOSKRNL.EXE */
|
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
|
||||||
HalAllocateAdapterChannel(
|
|
||||||
PADAPTER_OBJECT AdapterObject,
|
|
||||||
PWAIT_CONTEXT_BLOCK WaitContextBlock,
|
|
||||||
ULONG NumberOfMapRegisters,
|
|
||||||
PDRIVER_CONTROL ExecutionRoutine)
|
|
||||||
/*
|
|
||||||
* FUNCTION: Sets up an ADAPTER_OBJECT with map registers
|
|
||||||
* ARGUMENTS:
|
|
||||||
* - AdapterObject: pointer to an ADAPTER_OBJECT to set up
|
|
||||||
* - WaitContextBlock: Context block to be used with ExecutionRoutine
|
|
||||||
* - NumberOfMapRegisters: number of map registers requested
|
|
||||||
* - ExecutionRoutine: callback to call when map registers are allocated
|
|
||||||
* RETURNS:
|
|
||||||
* STATUS_INSUFFICIENT_RESOURCES if map registers cannot be allocated
|
|
||||||
* STATUS_SUCCESS in all other cases, including if the callbacak had
|
|
||||||
* to be queued for later delivery
|
|
||||||
* NOTES:
|
|
||||||
* - the ADAPTER_OBJECT struct is undocumented; please make copious
|
|
||||||
* notes in hal.h if anything is changed or improved since there is
|
|
||||||
* no other documentation for this data structure
|
|
||||||
* BUGS:
|
|
||||||
* - it's possible that some of this code is in the wrong place
|
|
||||||
* - there are many unhandled cases
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
LARGE_INTEGER MinAddress;
|
|
||||||
LARGE_INTEGER MaxAddress;
|
|
||||||
LARGE_INTEGER BoundryAddressMultiple;
|
|
||||||
IO_ALLOCATION_ACTION Retval;
|
|
||||||
|
|
||||||
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
|
|
||||||
|
|
||||||
/*
|
|
||||||
FIXME: return STATUS_INSUFFICIENT_RESOURCES if the NumberOfMapRegisters
|
|
||||||
requested is larger than the value returned by IoGetDmaAdapter.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* set up the wait context block in case we can't run right away */
|
|
||||||
WaitContextBlock->DeviceRoutine = ExecutionRoutine;
|
|
||||||
WaitContextBlock->NumberOfMapRegisters = NumberOfMapRegisters;
|
|
||||||
|
|
||||||
/* returns true if queued, else returns false and sets the queue to busy */
|
|
||||||
if(KeInsertDeviceQueue(&AdapterObject->ChannelWaitQueue, &WaitContextBlock->WaitQueueEntry))
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
|
|
||||||
/* why 64K alignment? */
|
|
||||||
/*
|
|
||||||
* X86 lacks map registers, so for now, we allocate a contiguous
|
|
||||||
* block of physical memory <16MB and copy all DMA buffers into
|
|
||||||
* that. This can be optimized.
|
|
||||||
*
|
|
||||||
* FIXME: We propably shouldn't allocate the memory here for common
|
|
||||||
* buffer transfers. See a comment in IoMapTransfer about common buffer
|
|
||||||
* support.
|
|
||||||
*/
|
|
||||||
|
|
||||||
MinAddress.QuadPart = 0;
|
|
||||||
BoundryAddressMultiple.QuadPart = 0;
|
|
||||||
if ((AdapterObject->Dma64BitAddresses) && (AdapterObject->MasterDevice))
|
|
||||||
{
|
|
||||||
MaxAddress.QuadPart = 0xFFFFFFFFFFFFFFFFLL; /* 64Bit: >4GB address range */
|
|
||||||
}
|
|
||||||
else if ((AdapterObject->Dma32BitAddresses) && (AdapterObject->MasterDevice))
|
|
||||||
{
|
|
||||||
MaxAddress.QuadPart = 0xFFFFFFFF; /* 32Bit: 4GB address range */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MaxAddress.QuadPart = 0x00FFFFFF; /* 24Bit: 16MB address range */
|
|
||||||
if (AdapterObject->Width16Bits)
|
|
||||||
{
|
|
||||||
BoundryAddressMultiple.QuadPart = 0x20000; /* 128k boundary */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BoundryAddressMultiple.QuadPart = 0x10000; /* 64k boundary */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AdapterObject->MapRegisterBase = MmAllocateContiguousMemorySpecifyCache(
|
|
||||||
NumberOfMapRegisters * PAGE_SIZE,
|
|
||||||
MinAddress,
|
|
||||||
MaxAddress,
|
|
||||||
BoundryAddressMultiple,
|
|
||||||
MmCached);
|
|
||||||
|
|
||||||
if(!AdapterObject->MapRegisterBase)
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
|
|
||||||
AdapterObject->CommittedMapRegisters = NumberOfMapRegisters;
|
|
||||||
|
|
||||||
/* call the client's AdapterControl callback with its map registers and context */
|
|
||||||
Retval = ExecutionRoutine(WaitContextBlock->DeviceObject, WaitContextBlock->CurrentIrp,
|
|
||||||
AdapterObject->MapRegisterBase, WaitContextBlock->DeviceContext);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* KeepObject: don't free any resources; the ADAPTER_OBJECT is still in use
|
|
||||||
* and the caller will call IoFreeAdapterChannel later
|
|
||||||
*
|
|
||||||
* DeallocateObject: Deallocate the map registers and release the ADAPTER_OBJECT
|
|
||||||
* so someone else can use it
|
|
||||||
*
|
|
||||||
* DeallocateObjectKeepRegisters: release the ADAPTER_OBJECT but hang on to
|
|
||||||
* the map registers. The client will later call IoFreeMapRegisters.
|
|
||||||
*
|
|
||||||
* NOTE - IoFreeAdapterChannel runs the queue, so it must be called
|
|
||||||
* unless the adapter object is not to be freed.
|
|
||||||
*/
|
|
||||||
if( Retval == DeallocateObject )
|
|
||||||
IoFreeAdapterChannel(AdapterObject);
|
|
||||||
else if(Retval == DeallocateObjectKeepRegisters)
|
|
||||||
{
|
|
||||||
/* don't free the allocated map registers - this is what IoFreeAdapterChannel checks */
|
|
||||||
AdapterObject->CommittedMapRegisters = 0;
|
|
||||||
IoFreeAdapterChannel(AdapterObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* if we don't call IoFreeAdapterChannel, the next device won't get de-queued,
|
|
||||||
* which is what we want.
|
|
||||||
*/
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BOOLEAN
|
|
||||||
HalpGrowMapBuffers(
|
|
||||||
IN PADAPTER_OBJECT AdapterObject,
|
|
||||||
IN ULONG SizeOfMapBuffers)
|
|
||||||
/*
|
|
||||||
* FUNCTION: Allocate initial, or additional, map buffers for IO adapters.
|
|
||||||
* ARGUMENTS:
|
|
||||||
* AdapterObject: DMA adapter to allocate buffers for.
|
|
||||||
* SizeOfMapBuffers: Size of the map buffers to allocate
|
|
||||||
* NOTES:
|
|
||||||
* - Needs to be tested...
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
//ULONG PagesToAllocate = BYTES_TO_PAGES(SizeOfMapBuffers);
|
|
||||||
|
|
||||||
/* TODO: Allocation */
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PADAPTER_OBJECT STDCALL
|
|
||||||
HalpAllocateAdapterEx(
|
|
||||||
ULONG NumberOfMapRegisters,
|
|
||||||
BOOLEAN IsMaster,
|
|
||||||
BOOLEAN Dma32BitAddresses)
|
|
||||||
/*
|
|
||||||
* FUNCTION: Allocates an ADAPTER_OBJECT, optionally creates the Master Adapter.
|
|
||||||
* ARGUMENTS:
|
|
||||||
* - NumberOfMapRegisters: Number of map registers to allocate
|
|
||||||
* - IsMaster: Wether this is a Master Device or not
|
|
||||||
* - Dma32BitAddresses: Wether 32-bit Addresses are supported
|
|
||||||
* RETURNS:
|
|
||||||
* - Pointer to Adapter Object, or NULL if failure.
|
|
||||||
* BUGS:
|
|
||||||
* - Some stuff is unhandled/incomplete
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
||||||
ULONG ObjectSize;
|
|
||||||
ULONG BitmapSize;
|
|
||||||
NTSTATUS Status;
|
|
||||||
ULONG AllowedMapRegisters = 64;
|
|
||||||
PADAPTER_OBJECT AdapterObject;
|
|
||||||
HANDLE Handle;
|
|
||||||
|
|
||||||
/* Allocate the Master Adapter if we haven't already
|
|
||||||
but make sure we're not asked to do it now, and also check if we need it */
|
|
||||||
if ((MasterAdapter == NULL) && (!IsMaster) && (NumberOfMapRegisters)) {
|
|
||||||
|
|
||||||
/* Allocate and Save */
|
|
||||||
DPRINT("Allocating the Master Adapter Object\n");
|
|
||||||
MasterAdapter = HalpAllocateAdapterEx(NumberOfMapRegisters,
|
|
||||||
TRUE,
|
|
||||||
Dma32BitAddresses);
|
|
||||||
|
|
||||||
/* Cancel on Failure */
|
|
||||||
DPRINT("Checking if Master Adapter was allocated properly\n");
|
|
||||||
if (!MasterAdapter) return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize the Object Attributes for the Adapter Object */
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
|
||||||
NULL,
|
|
||||||
OBJ_PERMANENT,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
/* Check if this is the Master Adapter, in which case we need to allocate the bitmap */
|
|
||||||
if (IsMaster) {
|
|
||||||
/* Size due to the Bitmap + Bytes in the Bitmap Buffer (8 bytes, 64 bits)*/
|
|
||||||
BitmapSize = sizeof(RTL_BITMAP) + (AllowedMapRegisters + 7) / 8;
|
|
||||||
|
|
||||||
/* We will put the Bitmap Buffer after the Adapter Object for simplicity */
|
|
||||||
ObjectSize = sizeof(ADAPTER_OBJECT) + BitmapSize;
|
|
||||||
} else {
|
|
||||||
ObjectSize = sizeof(ADAPTER_OBJECT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create and Allocate the Object */
|
|
||||||
DPRINT("Creating the Object\n");
|
|
||||||
Status = ObCreateObject(KernelMode,
|
|
||||||
IoAdapterObjectType,
|
|
||||||
&ObjectAttributes,
|
|
||||||
KernelMode,
|
|
||||||
NULL,
|
|
||||||
ObjectSize,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
(PVOID)&AdapterObject);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status)) return NULL;
|
|
||||||
|
|
||||||
/* Add a Reference */
|
|
||||||
DPRINT("Referencing the Object\n");
|
|
||||||
Status = ObReferenceObjectByPointer(AdapterObject,
|
|
||||||
FILE_READ_DATA | FILE_WRITE_DATA,
|
|
||||||
IoAdapterObjectType,
|
|
||||||
KernelMode);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status)) return NULL;
|
|
||||||
|
|
||||||
/* It's a Valid Object, so now we can play with the memory */
|
|
||||||
RtlZeroMemory(AdapterObject, sizeof(ADAPTER_OBJECT));
|
|
||||||
|
|
||||||
/* Insert it into the Object Table */
|
|
||||||
DPRINT("Inserting the Object\n");
|
|
||||||
Status = ObInsertObject(AdapterObject,
|
|
||||||
NULL,
|
|
||||||
FILE_READ_DATA | FILE_WRITE_DATA,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
&Handle);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status)) return NULL;
|
|
||||||
|
|
||||||
/* We don't want the handle */
|
|
||||||
NtClose(Handle);
|
|
||||||
|
|
||||||
/* Set up the Adapter Object fields */
|
|
||||||
AdapterObject->MapRegistersPerChannel = 1;
|
|
||||||
|
|
||||||
/* Set the Master if needed (master only needed if we use Map Registers) */
|
|
||||||
if (NumberOfMapRegisters) AdapterObject->MasterAdapter = MasterAdapter;
|
|
||||||
|
|
||||||
/* Initalize the Channel Wait queue, which every adapter has */
|
|
||||||
DPRINT("Initializing the Device Queue of the Object\n");
|
|
||||||
KeInitializeDeviceQueue(&AdapterObject->ChannelWaitQueue);
|
|
||||||
|
|
||||||
/* Initialize the SpinLock, Queue and Bitmap, which are kept in the Master Adapter only */
|
|
||||||
if (IsMaster) {
|
|
||||||
|
|
||||||
DPRINT("Initializing the Master Adapter Stuff\n");
|
|
||||||
KeInitializeSpinLock(&AdapterObject->SpinLock);
|
|
||||||
InitializeListHead(&AdapterObject->AdapterQueue);
|
|
||||||
|
|
||||||
/* As said previously, we put them here for simplicity */
|
|
||||||
AdapterObject->MapRegisters = (PVOID)(AdapterObject + 1);
|
|
||||||
|
|
||||||
/* Set up Bitmap */
|
|
||||||
RtlInitializeBitMap(AdapterObject->MapRegisters,
|
|
||||||
(PULONG)(AdapterObject->MapRegisters + 1),
|
|
||||||
AllowedMapRegisters);
|
|
||||||
|
|
||||||
/* Reset the Bitmap */
|
|
||||||
RtlSetAllBits(AdapterObject->MapRegisters);
|
|
||||||
AdapterObject->NumberOfMapRegisters = 0;
|
|
||||||
AdapterObject->CommittedMapRegisters = 0;
|
|
||||||
|
|
||||||
/* Allocate Memory for the Map Registers */
|
|
||||||
AdapterObject->MapRegisterBase = ExAllocatePool(NonPagedPool,
|
|
||||||
AllowedMapRegisters * sizeof(DWORD));
|
|
||||||
|
|
||||||
/* Clear them */
|
|
||||||
RtlZeroMemory(AdapterObject->MapRegisterBase, AllowedMapRegisters * sizeof(DWORD));
|
|
||||||
|
|
||||||
/* Allocate the contigous memory */
|
|
||||||
DPRINT("Allocating Buffers\n");
|
|
||||||
HalpGrowMapBuffers(AdapterObject, 0x1000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("Adapter Object allocated\n");
|
|
||||||
return AdapterObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BOOLEAN STDCALL
|
|
||||||
IoFlushAdapterBuffers (
|
|
||||||
PADAPTER_OBJECT AdapterObject,
|
|
||||||
PMDL Mdl,
|
|
||||||
PVOID MapRegisterBase,
|
|
||||||
PVOID CurrentVa,
|
|
||||||
ULONG Length,
|
|
||||||
BOOLEAN WriteToDevice)
|
|
||||||
/*
|
|
||||||
* FUNCTION: flush any data remaining in the dma controller's memory into the host memory
|
|
||||||
* ARGUMENTS:
|
|
||||||
* AdapterObject: the adapter object to flush
|
|
||||||
* Mdl: original MDL to flush data into
|
|
||||||
* MapRegisterBase: map register base that was just used by IoMapTransfer, etc
|
|
||||||
* CurrentVa: offset into Mdl to be flushed into, same as was passed to IoMapTransfer
|
|
||||||
* Length: length of the buffer to be flushed into
|
|
||||||
* WriteToDevice: True if it's a write, False if it's a read
|
|
||||||
* RETURNS:
|
|
||||||
* TRUE in all cases
|
|
||||||
* NOTES:
|
|
||||||
* - This copies data from the map register-backed buffer to the user's target buffer.
|
|
||||||
* Data is not in the user buffer until this is called.
|
|
||||||
* - This is only meaningful on a read operation. Return immediately for a write.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
|
|
||||||
|
|
||||||
/* this can happen if the card supports scatter/gather */
|
|
||||||
if(!MapRegisterBase)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/* mask out (disable) the dma channel */
|
|
||||||
if (AdapterObject->AdapterNumber == 1) {
|
|
||||||
|
|
||||||
/* Set this for Ease */
|
|
||||||
PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
|
|
||||||
|
|
||||||
/* Set Channel */
|
|
||||||
WRITE_PORT_UCHAR(&DmaControl1->SingleMask, AdapterObject->ChannelNumber | DMA_SETMASK);
|
|
||||||
} else {
|
|
||||||
/* Set this for Ease */
|
|
||||||
PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
|
|
||||||
|
|
||||||
/* Set Channel */
|
|
||||||
WRITE_PORT_UCHAR(&DmaControl2->SingleMask, (AdapterObject->ChannelNumber - 4) | DMA_SETMASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(WriteToDevice)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
memcpy(
|
|
||||||
(PVOID)((DWORD)MmGetSystemAddressForMdl( Mdl ) + (DWORD)CurrentVa - (DWORD)MmGetMdlVirtualAddress( Mdl )),
|
|
||||||
MapRegisterBase, Length );
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VOID STDCALL
|
|
||||||
IoFreeAdapterChannel (PADAPTER_OBJECT AdapterObject)
|
|
||||||
/*
|
|
||||||
* FUNCTION: frees DMA resources allocated by IoAllocateAdapterChannel
|
|
||||||
* ARGUMENTS:
|
|
||||||
* AdapterObject: Adapter object with resources to free
|
|
||||||
* NOTES:
|
|
||||||
* - This function releases the DMA adapter and optionally the map registers
|
|
||||||
* - After releasing the adapter, it checks the adapter's queue and runs
|
|
||||||
* each queued device object in series until the queue is empty
|
|
||||||
* - This is the only way the device queue is emptied.
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
LARGE_INTEGER MaxAddress;
|
|
||||||
LARGE_INTEGER MinAddress;
|
|
||||||
LARGE_INTEGER BoundryAddressMultiple;
|
|
||||||
PWAIT_CONTEXT_BLOCK WaitContextBlock;
|
|
||||||
IO_ALLOCATION_ACTION Retval;
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
/* To keep map registers, call here with the following set to 0 */
|
|
||||||
if(AdapterObject->CommittedMapRegisters)
|
|
||||||
IoFreeMapRegisters(AdapterObject, AdapterObject->MapRegisterBase, AdapterObject->CommittedMapRegisters);
|
|
||||||
|
|
||||||
if(!(WaitContextBlock = (PWAIT_CONTEXT_BLOCK)KeRemoveDeviceQueue(&AdapterObject->ChannelWaitQueue)))
|
|
||||||
break;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* the following should really be done elsewhere since this
|
|
||||||
* function really can't return an error code. FIXME.
|
|
||||||
*/
|
|
||||||
|
|
||||||
MinAddress.QuadPart = 0;
|
|
||||||
BoundryAddressMultiple.QuadPart = 0;
|
|
||||||
if ((AdapterObject->Dma64BitAddresses) && (AdapterObject->MasterDevice))
|
|
||||||
{
|
|
||||||
MaxAddress.QuadPart = 0xFFFFFFFFFFFFFFFFLL; /* 64Bit: >4GB address range */
|
|
||||||
}
|
|
||||||
else if ((AdapterObject->Dma32BitAddresses) && (AdapterObject->MasterDevice))
|
|
||||||
{
|
|
||||||
MaxAddress.QuadPart = 0xFFFFFFFF; /* 32Bit: 4GB address range */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MaxAddress.QuadPart = 0x00FFFFFF; /* 24Bit: 16MB address range */
|
|
||||||
if (AdapterObject->Width16Bits)
|
|
||||||
{
|
|
||||||
BoundryAddressMultiple.QuadPart = 0x20000; /* 128k boundary */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BoundryAddressMultiple.QuadPart = 0x10000; /* 64k boundary */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AdapterObject->MapRegisterBase = MmAllocateContiguousMemorySpecifyCache(
|
|
||||||
WaitContextBlock->NumberOfMapRegisters * PAGE_SIZE,
|
|
||||||
MinAddress,
|
|
||||||
MaxAddress,
|
|
||||||
BoundryAddressMultiple,
|
|
||||||
MmCached);
|
|
||||||
|
|
||||||
if(!AdapterObject->MapRegisterBase)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* call the adapter control routine */
|
|
||||||
Retval = ((PDRIVER_CONTROL)WaitContextBlock->DeviceRoutine)(WaitContextBlock->DeviceObject, WaitContextBlock->CurrentIrp,
|
|
||||||
AdapterObject->MapRegisterBase, WaitContextBlock->DeviceContext);
|
|
||||||
|
|
||||||
if(Retval == KeepObject)
|
|
||||||
{
|
|
||||||
/* we're done until the caller manually calls IoFreeAdapterChannel */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if(Retval == DeallocateObjectKeepRegisters)
|
|
||||||
{
|
|
||||||
/* hide the map registers so they aren't deallocated next time around */
|
|
||||||
AdapterObject->CommittedMapRegisters = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VOID STDCALL
|
|
||||||
IoFreeMapRegisters (
|
|
||||||
IN PADAPTER_OBJECT AdapterObject,
|
|
||||||
IN PVOID MapRegisterBase,
|
|
||||||
IN ULONG NumberOfMapRegisters)
|
|
||||||
/*
|
|
||||||
* FUNCTION: free map registers reserved by the system for a DMA
|
|
||||||
* ARGUMENTS:
|
|
||||||
* AdapterObject: dma adapter to free map registers on
|
|
||||||
* MapRegisterBase: hadle to map registers to free
|
|
||||||
* NumberOfRegisters: number of map registers to be freed
|
|
||||||
* NOTES:
|
|
||||||
* - XXX real windows has a funky interdependence between IoFreeMapRegisters
|
|
||||||
* and IoFreeAdapterChannel
|
|
||||||
* BUGS:
|
|
||||||
* - needs to be improved to use a real map register implementation
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
if( AdapterObject->CommittedMapRegisters )
|
|
||||||
{
|
|
||||||
MmFreeContiguousMemory(AdapterObject->MapRegisterBase);
|
|
||||||
AdapterObject->MapRegisterBase = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PHYSICAL_ADDRESS STDCALL
|
|
||||||
IoMapTransfer (
|
|
||||||
IN PADAPTER_OBJECT AdapterObject,
|
|
||||||
IN PMDL Mdl,
|
|
||||||
IN PVOID MapRegisterBase,
|
|
||||||
IN PVOID CurrentVa,
|
|
||||||
IN OUT PULONG Length,
|
|
||||||
IN BOOLEAN WriteToDevice)
|
|
||||||
/*
|
|
||||||
* FUNCTION: map a dma for transfer and do the dma if it's a slave
|
|
||||||
* ARGUMENTS:
|
|
||||||
* AdapterObject: adapter object to do the dma on. busmaster may pass NULL.
|
|
||||||
* Mdl: locked-down user buffer to DMA in to or out of
|
|
||||||
* MapRegisterBase: handle to map registers to use for this dma. allways NULL
|
|
||||||
* when doing s/g.
|
|
||||||
* CurrentVa: index into Mdl to transfer into/out of
|
|
||||||
* Length: length of transfer in/out. Only modified on out when doing s/g.
|
|
||||||
* WriteToDevice: TRUE if it's an output dma, FALSE otherwise
|
|
||||||
* RETURNS:
|
|
||||||
* If a busmaster: A logical address that can be used to program a dma controller
|
|
||||||
* Otherwise: nothing meaningful
|
|
||||||
* NOTES:
|
|
||||||
* - This function does a copyover to contiguous memory <16MB
|
|
||||||
* - If it's a slave transfer, this function actually performs it.
|
|
||||||
* BUGS:
|
|
||||||
* - If the controller supports scatter/gather, the copyover should not happen
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
PHYSICAL_ADDRESS Address;
|
|
||||||
KIRQL OldIrql;
|
|
||||||
ULONG LengthShift = 0;
|
|
||||||
|
|
||||||
Address.QuadPart = 0;
|
|
||||||
|
|
||||||
/* Isa System (slave) DMA? */
|
|
||||||
if (MapRegisterBase && !AdapterObject->MasterDevice)
|
|
||||||
{
|
|
||||||
KeAcquireSpinLock(&AdapterObject->SpinLock, &OldIrql);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FIXME: Handle case when doing common-buffer System DMA. In this case,
|
|
||||||
* the buffer described by MDL is already phys. contiguous and below
|
|
||||||
* 16 mega. Driver makes a one-shot call to IoMapTransfer during init.
|
|
||||||
* to program controller with the common-buffer.
|
|
||||||
*
|
|
||||||
* UPDATE: Common buffer support is in place, but it's not done in a
|
|
||||||
* clean way. We use the buffer passed by the MDL in case that the
|
|
||||||
* adapter object is marked as auto initialize. I'm not sure if this
|
|
||||||
* is correct and if not, how to do it properly. Note that it's also
|
|
||||||
* possible to allocate the common buffer with different adapter object
|
|
||||||
* and IoMapTransfer must still work in this case. Eventually this should
|
|
||||||
* be cleaned up somehow or at least this comment modified to reflect
|
|
||||||
* the reality.
|
|
||||||
* -- Filip Navara, 19/07/2004
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* if it is a write to the device, copy the caller buffer to the low buffer */
|
|
||||||
if (WriteToDevice && !AdapterObject->AdapterMode.AutoInitialize)
|
|
||||||
{
|
|
||||||
memcpy(MapRegisterBase,
|
|
||||||
(char*)MmGetSystemAddressForMdl(Mdl) + ((ULONG)CurrentVa - (ULONG)MmGetMdlVirtualAddress(Mdl)),
|
|
||||||
*Length );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Writer Adapter Mode, transfer type */
|
|
||||||
AdapterObject->AdapterMode.TransferType = (WriteToDevice ? WRITE_TRANSFER : READ_TRANSFER);
|
|
||||||
|
|
||||||
/* program up the dma controller, and return */
|
|
||||||
if (!AdapterObject->AdapterMode.AutoInitialize) {
|
|
||||||
Address = MmGetPhysicalAddress( MapRegisterBase );
|
|
||||||
} else {
|
|
||||||
Address = MmGetPhysicalAddress( CurrentVa );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 16-bit DMA has a shifted length */
|
|
||||||
if (AdapterObject->Width16Bits) {
|
|
||||||
LengthShift = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make the Transfer */
|
|
||||||
if (AdapterObject->AdapterNumber == 1) {
|
|
||||||
|
|
||||||
PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa; /* For Writing Less Code */
|
|
||||||
|
|
||||||
/* Mask the Channel */
|
|
||||||
WRITE_PORT_UCHAR(&DmaControl1->SingleMask, AdapterObject->ChannelNumber | DMA_SETMASK);
|
|
||||||
|
|
||||||
/* Reset Register */
|
|
||||||
WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
|
|
||||||
|
|
||||||
/* Set the Mode */
|
|
||||||
WRITE_PORT_UCHAR(&DmaControl1->Mode, AdapterObject->AdapterModeByte);
|
|
||||||
|
|
||||||
/* Set the Page Register */
|
|
||||||
WRITE_PORT_UCHAR(AdapterObject->PagePort, (UCHAR)(Address.u.LowPart >> 16));
|
|
||||||
|
|
||||||
/* Set the Offset Register (apparently always 0 for us if I trust the previous comment) */
|
|
||||||
WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0);
|
|
||||||
WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0);
|
|
||||||
|
|
||||||
/* Set the Length */
|
|
||||||
WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
|
|
||||||
(UCHAR)((*Length >> LengthShift) - 1));
|
|
||||||
WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
|
|
||||||
(UCHAR)(((*Length >> LengthShift) - 1) >> 8));
|
|
||||||
|
|
||||||
/* Unmask the Channel */
|
|
||||||
WRITE_PORT_UCHAR(&DmaControl1->SingleMask, AdapterObject->ChannelNumber | DMA_CLEARMASK);
|
|
||||||
} else {
|
|
||||||
PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa; /* For Writing Less Code */
|
|
||||||
|
|
||||||
/* Mask the Channel */
|
|
||||||
WRITE_PORT_UCHAR(&DmaControl2->SingleMask, AdapterObject->ChannelNumber | DMA_SETMASK);
|
|
||||||
|
|
||||||
/* Reset Register */
|
|
||||||
WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
|
|
||||||
|
|
||||||
/* Set the Mode */
|
|
||||||
WRITE_PORT_UCHAR(&DmaControl2->Mode, AdapterObject->AdapterModeByte);
|
|
||||||
|
|
||||||
/* Set the Page Register */
|
|
||||||
WRITE_PORT_UCHAR(AdapterObject->PagePort, (UCHAR)(Address.u.LowPart >> 16));
|
|
||||||
|
|
||||||
/* Set the Offset Register (apparently always 0 for us if I trust the previous comment) */
|
|
||||||
WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0);
|
|
||||||
WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0);
|
|
||||||
|
|
||||||
/* Set the Length */
|
|
||||||
WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
|
|
||||||
(UCHAR)((*Length >> LengthShift) - 1));
|
|
||||||
WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
|
|
||||||
(UCHAR)(((*Length >> LengthShift) - 1) >> 8));
|
|
||||||
|
|
||||||
/* Unmask the Channel */
|
|
||||||
WRITE_PORT_UCHAR(&DmaControl2->SingleMask, AdapterObject->ChannelNumber | DMA_CLEARMASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Release Spinlock */
|
|
||||||
KeReleaseSpinLock(&AdapterObject->SpinLock, OldIrql);
|
|
||||||
|
|
||||||
/*
|
|
||||||
NOTE: Return value should be ignored when doing System DMA.
|
|
||||||
Maybe return some more obvious invalid address here (thou returning
|
|
||||||
MapRegisterBase is also wrong;-)to catch invalid use?
|
|
||||||
*/
|
|
||||||
Address.QuadPart = (ULONG)MapRegisterBase;
|
|
||||||
return Address;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Busmaster with s/g support?
|
|
||||||
NOTE: old docs allowed busmasters to pass a NULL Adapter. In this case, MapRegisterBase
|
|
||||||
being NULL is used to detect a s/g busmaster.
|
|
||||||
*/
|
|
||||||
if ((!AdapterObject && !MapRegisterBase) ||
|
|
||||||
(AdapterObject && AdapterObject->MasterDevice && AdapterObject->ScatterGather))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Just return the passed VA's corresponding phys. address.
|
|
||||||
Update length to the number of phys. contiguous bytes found.
|
|
||||||
*/
|
|
||||||
|
|
||||||
PULONG MdlPages;
|
|
||||||
ULONG MdlPageIndex, PhysContiguousLen;
|
|
||||||
ULONG PhysAddress;
|
|
||||||
|
|
||||||
MdlPages = (PULONG)(Mdl + 1);
|
|
||||||
|
|
||||||
/* Get VA's corresponding mdl phys. page index */
|
|
||||||
MdlPageIndex = ((ULONG)CurrentVa - (ULONG)Mdl->StartVa) / PAGE_SIZE;
|
|
||||||
|
|
||||||
/* Get phys. page containing the VA */
|
|
||||||
PhysAddress = MdlPages[MdlPageIndex];
|
|
||||||
|
|
||||||
PhysContiguousLen = PAGE_SIZE - BYTE_OFFSET(CurrentVa);
|
|
||||||
|
|
||||||
/* VA to map may span several contiguous phys. pages (unlikely) */
|
|
||||||
while (PhysContiguousLen < *Length &&
|
|
||||||
MdlPages[MdlPageIndex++] + PAGE_SIZE == MdlPages[MdlPageIndex])
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Note that allways adding PAGE_SIZE may make PhysContiguousLen greater
|
|
||||||
than Length if buffer doesn't end on page boundary. Take this
|
|
||||||
into consideration below.
|
|
||||||
*/
|
|
||||||
PhysContiguousLen += PAGE_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PhysContiguousLen < *Length)
|
|
||||||
{
|
|
||||||
*Length = PhysContiguousLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
//add offset to phys. page address
|
|
||||||
Address.QuadPart = PhysAddress + BYTE_OFFSET(CurrentVa);
|
|
||||||
return Address;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Busmaster without s/g support?
|
|
||||||
NOTE: old docs allowed busmasters to pass a NULL Adapter. In this case, MapRegisterBase
|
|
||||||
not being NULL is used to detect a non s/g busmaster.
|
|
||||||
*/
|
|
||||||
if ((!AdapterObject && MapRegisterBase) ||
|
|
||||||
(AdapterObject && AdapterObject->MasterDevice && !AdapterObject->ScatterGather))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
NOTE: Busmasters doing common-buffer DMA shouldn't call IoMapTransfer, but I don't
|
|
||||||
know if it's illegal... Maybe figure out what to do in this case...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if( WriteToDevice )
|
|
||||||
{
|
|
||||||
memcpy(MapRegisterBase,
|
|
||||||
(char*)MmGetSystemAddressForMdl(Mdl) + ((ULONG)CurrentVa - (ULONG)MmGetMdlVirtualAddress(Mdl)),
|
|
||||||
*Length );
|
|
||||||
}
|
|
||||||
|
|
||||||
return MmGetPhysicalAddress(MapRegisterBase);
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("IoMapTransfer: Unsupported operation\n");
|
|
||||||
KEBUGCHECK(0);
|
|
||||||
return Address;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* EOF */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -4,7 +4,6 @@
|
||||||
<define name="_DISABLE_TIDENTS" />
|
<define name="_DISABLE_TIDENTS" />
|
||||||
<define name="__USE_W32API" />
|
<define name="__USE_W32API" />
|
||||||
<define name="_NTHAL_" />
|
<define name="_NTHAL_" />
|
||||||
<file>adapter.c</file>
|
|
||||||
<file>beep.c</file>
|
<file>beep.c</file>
|
||||||
<file>bus.c</file>
|
<file>bus.c</file>
|
||||||
<file>dma.c</file>
|
<file>dma.c</file>
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "apic.h"
|
#include "apic.h"
|
||||||
#include "bus.h"
|
#include "bus.h"
|
||||||
#include "halirq.h"
|
#include "halirq.h"
|
||||||
|
#include "haldma.h"
|
||||||
#include "halp.h"
|
#include "halp.h"
|
||||||
#include "mps.h"
|
#include "mps.h"
|
||||||
#include "ioapic.h"
|
#include "ioapic.h"
|
||||||
|
|
389
reactos/hal/halx86/include/haldma.h
Normal file
389
reactos/hal/halx86/include/haldma.h
Normal file
|
@ -0,0 +1,389 @@
|
||||||
|
#ifndef HALDMA_H
|
||||||
|
#define HALDMA_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DMA Page Register Structure
|
||||||
|
* 080 DMA RESERVED
|
||||||
|
* 081 DMA Page Register (channel 2)
|
||||||
|
* 082 DMA Page Register (channel 3)
|
||||||
|
* 083 DMA Page Register (channel 1)
|
||||||
|
* 084 DMA RESERVED
|
||||||
|
* 085 DMA RESERVED
|
||||||
|
* 086 DMA RESERVED
|
||||||
|
* 087 DMA Page Register (channel 0)
|
||||||
|
* 088 DMA RESERVED
|
||||||
|
* 089 PS/2-DMA Page Register (channel 6)
|
||||||
|
* 08A PS/2-DMA Page Register (channel 7)
|
||||||
|
* 08B PS/2-DMA Page Register (channel 5)
|
||||||
|
* 08C PS/2-DMA RESERVED
|
||||||
|
* 08D PS/2-DMA RESERVED
|
||||||
|
* 08E PS/2-DMA RESERVED
|
||||||
|
* 08F PS/2-DMA Page Register (channel 4)
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct _DMA_PAGE
|
||||||
|
{
|
||||||
|
UCHAR Reserved1;
|
||||||
|
UCHAR Channel2;
|
||||||
|
UCHAR Channel3;
|
||||||
|
UCHAR Channel1;
|
||||||
|
UCHAR Reserved2[3];
|
||||||
|
UCHAR Channel0;
|
||||||
|
UCHAR Reserved3;
|
||||||
|
UCHAR Channel6;
|
||||||
|
UCHAR Channel7;
|
||||||
|
UCHAR Channel5;
|
||||||
|
UCHAR Reserved4[3];
|
||||||
|
UCHAR Channel4;
|
||||||
|
} DMA_PAGE, *PDMA_PAGE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DMA Channel Mask Register Structure
|
||||||
|
*
|
||||||
|
* MSB LSB
|
||||||
|
* x x x x x x x x
|
||||||
|
* ------------------- - -----
|
||||||
|
* | | | 00 - Select channel 0 mask bit
|
||||||
|
* | | \---- 01 - Select channel 1 mask bit
|
||||||
|
* | | 10 - Select channel 2 mask bit
|
||||||
|
* | | 11 - Select channel 3 mask bit
|
||||||
|
* | |
|
||||||
|
* | \---------- 0 - Clear mask bit
|
||||||
|
* | 1 - Set mask bit
|
||||||
|
* |
|
||||||
|
* \----------------------- xx - Reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct _DMA_CHANNEL_MASK
|
||||||
|
{
|
||||||
|
UCHAR Channel: 2;
|
||||||
|
UCHAR SetMask: 1;
|
||||||
|
UCHAR Reserved: 5;
|
||||||
|
} DMA_CHANNEL_MASK, *PDMA_CHANNEL_MASK;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DMA Mask Register Structure
|
||||||
|
*
|
||||||
|
* MSB LSB
|
||||||
|
* x x x x x x x x
|
||||||
|
* \---/ - - ----- -----
|
||||||
|
* | | | | | 00 - Channel 0 select
|
||||||
|
* | | | | \---- 01 - Channel 1 select
|
||||||
|
* | | | | 10 - Channel 2 select
|
||||||
|
* | | | | 11 - Channel 3 select
|
||||||
|
* | | | |
|
||||||
|
* | | | | 00 - Verify transfer
|
||||||
|
* | | | \------------ 01 - Write transfer
|
||||||
|
* | | | 10 - Read transfer
|
||||||
|
* | | |
|
||||||
|
* | | \-------------------- 0 - Autoinitialized
|
||||||
|
* | | 1 - Non-autoinitialized
|
||||||
|
* | |
|
||||||
|
* | \------------------------ 0 - Address increment select
|
||||||
|
* |
|
||||||
|
* | 00 - Demand mode
|
||||||
|
* \------------------------------ 01 - Single mode
|
||||||
|
* 10 - Block mode
|
||||||
|
* 11 - Cascade mode
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef union _DMA_MODE
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
UCHAR Channel: 2;
|
||||||
|
UCHAR TransferType: 2;
|
||||||
|
UCHAR AutoInitialize: 1;
|
||||||
|
UCHAR AddressDecrement: 1;
|
||||||
|
UCHAR RequestMode: 2;
|
||||||
|
};
|
||||||
|
UCHAR Byte;
|
||||||
|
} DMA_MODE, *PDMA_MODE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DMA Extended Mode Register Structure
|
||||||
|
*
|
||||||
|
* MSB LSB
|
||||||
|
* x x x x x x x x
|
||||||
|
* - - ----- ----- -----
|
||||||
|
* | | | | | 00 - Channel 0 select
|
||||||
|
* | | | | \---- 01 - Channel 1 select
|
||||||
|
* | | | | 10 - Channel 2 select
|
||||||
|
* | | | | 11 - Channel 3 select
|
||||||
|
* | | | |
|
||||||
|
* | | | | 00 - 8-bit I/O, by bytes
|
||||||
|
* | | | \------------ 01 - 16-bit I/O, by words, address shifted
|
||||||
|
* | | | 10 - 32-bit I/O, by bytes
|
||||||
|
* | | | 11 - 16-bit I/O, by bytes
|
||||||
|
* | | |
|
||||||
|
* | | \---------------------- 00 - Compatible
|
||||||
|
* | | 01 - Type A
|
||||||
|
* | | 10 - Type B
|
||||||
|
* | | 11 - Burst
|
||||||
|
* | |
|
||||||
|
* | \---------------------------- 0 - Terminal Count is Output
|
||||||
|
* |
|
||||||
|
* \---------------------------------0 - Disable Stop Register
|
||||||
|
* 1 - Enable Stop Register
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef union _DMA_EXTENDED_MODE
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
UCHAR ChannelNumber: 2;
|
||||||
|
UCHAR TransferSize: 2;
|
||||||
|
UCHAR TimingMode: 2;
|
||||||
|
UCHAR TerminalCountIsOutput: 1;
|
||||||
|
UCHAR EnableStopRegister: 1;
|
||||||
|
};
|
||||||
|
UCHAR Byte;
|
||||||
|
} DMA_EXTENDED_MODE, *PDMA_EXTENDED_MODE;
|
||||||
|
|
||||||
|
/* DMA Extended Mode Register Transfer Sizes */
|
||||||
|
#define B_8BITS 0
|
||||||
|
#define W_16BITS 1
|
||||||
|
#define B_32BITS 2
|
||||||
|
#define B_16BITS 3
|
||||||
|
|
||||||
|
/* DMA Extended Mode Register Timing */
|
||||||
|
#define COMPATIBLE_TIMING 0
|
||||||
|
#define TYPE_A_TIMING 1
|
||||||
|
#define TYPE_B_TIMING 2
|
||||||
|
#define BURST_TIMING 3
|
||||||
|
|
||||||
|
/* Channel Stop Registers for each Channel */
|
||||||
|
typedef struct _DMA_CHANNEL_STOP
|
||||||
|
{
|
||||||
|
UCHAR ChannelLow;
|
||||||
|
UCHAR ChannelMid;
|
||||||
|
UCHAR ChannelHigh;
|
||||||
|
UCHAR Reserved;
|
||||||
|
} DMA_CHANNEL_STOP, *PDMA_CHANNEL_STOP;
|
||||||
|
|
||||||
|
/* Transfer Types */
|
||||||
|
#define VERIFY_TRANSFER 0x00
|
||||||
|
#define READ_TRANSFER 0x01
|
||||||
|
#define WRITE_TRANSFER 0x02
|
||||||
|
|
||||||
|
/* Request Modes */
|
||||||
|
#define DEMAND_REQUEST_MODE 0x00
|
||||||
|
#define SINGLE_REQUEST_MODE 0x01
|
||||||
|
#define BLOCK_REQUEST_MODE 0x02
|
||||||
|
#define CASCADE_REQUEST_MODE 0x03
|
||||||
|
|
||||||
|
#define DMA_SETMASK 4
|
||||||
|
#define DMA_CLEARMASK 0
|
||||||
|
#define DMA_READ 4
|
||||||
|
#define DMA_WRITE 8
|
||||||
|
#define DMA_SINGLE_TRANSFER 0x40
|
||||||
|
#define DMA_AUTO_INIT 0x10
|
||||||
|
|
||||||
|
typedef struct _DMA1_ADDRESS_COUNT
|
||||||
|
{
|
||||||
|
UCHAR DmaBaseAddress;
|
||||||
|
UCHAR DmaBaseCount;
|
||||||
|
} DMA1_ADDRESS_COUNT, *PDMA1_ADDRESS_COUNT;
|
||||||
|
|
||||||
|
typedef struct _DMA2_ADDRESS_COUNT
|
||||||
|
{
|
||||||
|
UCHAR DmaBaseAddress;
|
||||||
|
UCHAR Reserved1;
|
||||||
|
UCHAR DmaBaseCount;
|
||||||
|
UCHAR Reserved2;
|
||||||
|
} DMA2_ADDRESS_COUNT, *PDMA2_ADDRESS_COUNT;
|
||||||
|
|
||||||
|
typedef struct _DMA1_CONTROL
|
||||||
|
{
|
||||||
|
DMA1_ADDRESS_COUNT DmaAddressCount[4];
|
||||||
|
UCHAR DmaStatus;
|
||||||
|
UCHAR DmaRequest;
|
||||||
|
UCHAR SingleMask;
|
||||||
|
UCHAR Mode;
|
||||||
|
UCHAR ClearBytePointer;
|
||||||
|
UCHAR MasterClear;
|
||||||
|
UCHAR ClearMask;
|
||||||
|
UCHAR AllMask;
|
||||||
|
} DMA1_CONTROL, *PDMA1_CONTROL;
|
||||||
|
|
||||||
|
typedef struct _DMA2_CONTROL
|
||||||
|
{
|
||||||
|
DMA2_ADDRESS_COUNT DmaAddressCount[4];
|
||||||
|
UCHAR DmaStatus;
|
||||||
|
UCHAR Reserved1;
|
||||||
|
UCHAR DmaRequest;
|
||||||
|
UCHAR Reserved2;
|
||||||
|
UCHAR SingleMask;
|
||||||
|
UCHAR Reserved3;
|
||||||
|
UCHAR Mode;
|
||||||
|
UCHAR Reserved4;
|
||||||
|
UCHAR ClearBytePointer;
|
||||||
|
UCHAR Reserved5;
|
||||||
|
UCHAR MasterClear;
|
||||||
|
UCHAR Reserved6;
|
||||||
|
UCHAR ClearMask;
|
||||||
|
UCHAR Reserved7;
|
||||||
|
UCHAR AllMask;
|
||||||
|
UCHAR Reserved8;
|
||||||
|
} DMA2_CONTROL, *PDMA2_CONTROL;
|
||||||
|
|
||||||
|
/* This structure defines the I/O Map of the 82537 controller. */
|
||||||
|
typedef struct _EISA_CONTROL
|
||||||
|
{
|
||||||
|
/* DMA Controller 1 */
|
||||||
|
DMA1_CONTROL DmaController1; /* 00h-0Fh */
|
||||||
|
UCHAR Reserved1[16]; /* 0Fh-1Fh */
|
||||||
|
|
||||||
|
/* Interrupt Controller 1 (PIC) */
|
||||||
|
UCHAR Pic1Operation; /* 20h */
|
||||||
|
UCHAR Pic1Interrupt; /* 21h */
|
||||||
|
UCHAR Reserved2[30]; /* 22h-3Fh */
|
||||||
|
|
||||||
|
/* Timer */
|
||||||
|
UCHAR TimerCounter; /* 40h */
|
||||||
|
UCHAR TimerMemoryRefresh; /* 41h */
|
||||||
|
UCHAR Speaker; /* 42h */
|
||||||
|
UCHAR TimerOperation; /* 43h */
|
||||||
|
UCHAR TimerMisc; /* 44h */
|
||||||
|
UCHAR Reserved3[2]; /* 45-46h */
|
||||||
|
UCHAR TimerCounterControl; /* 47h */
|
||||||
|
UCHAR TimerFailSafeCounter; /* 48h */
|
||||||
|
UCHAR Reserved4; /* 49h */
|
||||||
|
UCHAR TimerCounter2; /* 4Ah */
|
||||||
|
UCHAR TimerOperation2; /* 4Bh */
|
||||||
|
UCHAR Reserved5[20]; /* 4Ch-5Fh */
|
||||||
|
|
||||||
|
/* NMI / Keyboard / RTC */
|
||||||
|
UCHAR Keyboard; /* 60h */
|
||||||
|
UCHAR NmiStatus; /* 61h */
|
||||||
|
UCHAR Reserved6[14]; /* 62h-6Fh */
|
||||||
|
UCHAR NmiEnable; /* 70h */
|
||||||
|
UCHAR Reserved7[15]; /* 71h-7Fh */
|
||||||
|
|
||||||
|
/* DMA Page Registers Controller 1 */
|
||||||
|
DMA_PAGE DmaController1Pages; /* 80h-8Fh */
|
||||||
|
UCHAR Reserved8[16]; /* 90h-9Fh */
|
||||||
|
|
||||||
|
/* Interrupt Controller 2 (PIC) */
|
||||||
|
UCHAR Pic2Operation; /* 0A0h */
|
||||||
|
UCHAR Pic2Interrupt; /* 0A1h */
|
||||||
|
UCHAR Reserved9[30]; /* 0A2h-0BFh */
|
||||||
|
|
||||||
|
/* DMA Controller 2 */
|
||||||
|
DMA1_CONTROL DmaController2; /* 0C0h-0CFh */
|
||||||
|
|
||||||
|
/* System Reserved Ports */
|
||||||
|
UCHAR SystemReserved[816]; /* 0D0h-3FFh */
|
||||||
|
|
||||||
|
/* Extended DMA Registers, Controller 1 */
|
||||||
|
UCHAR DmaHighByteCount1[8]; /* 400h-407h */
|
||||||
|
UCHAR Reserved10[2]; /* 408h-409h */
|
||||||
|
UCHAR DmaChainMode1; /* 40Ah */
|
||||||
|
UCHAR DmaExtendedMode1; /* 40Bh */
|
||||||
|
UCHAR DmaBufferControl; /* 40Ch */
|
||||||
|
UCHAR Reserved11[84]; /* 40Dh-460h */
|
||||||
|
UCHAR ExtendedNmiControl; /* 461h */
|
||||||
|
UCHAR NmiCommand; /* 462h */
|
||||||
|
UCHAR Reserved12; /* 463h */
|
||||||
|
UCHAR BusMaster; /* 464h */
|
||||||
|
UCHAR Reserved13[27]; /* 465h-47Fh */
|
||||||
|
|
||||||
|
/* DMA Page Registers Controller 2 */
|
||||||
|
DMA_PAGE DmaController2Pages; /* 480h-48Fh */
|
||||||
|
UCHAR Reserved14[48]; /* 490h-4BFh */
|
||||||
|
|
||||||
|
/* Extended DMA Registers, Controller 2 */
|
||||||
|
UCHAR DmaHighByteCount2[16]; /* 4C0h-4CFh */
|
||||||
|
|
||||||
|
/* Edge/Level Control Registers */
|
||||||
|
UCHAR Pic1EdgeLevel; /* 4D0h */
|
||||||
|
UCHAR Pic2EdgeLevel; /* 4D1h */
|
||||||
|
UCHAR Reserved15[2]; /* 4D2h-4D3h */
|
||||||
|
|
||||||
|
/* Extended DMA Registers, Controller 2 */
|
||||||
|
UCHAR DmaChainMode2; /* 4D4h */
|
||||||
|
UCHAR Reserved16; /* 4D5h */
|
||||||
|
UCHAR DmaExtendedMode2; /* 4D6h */
|
||||||
|
UCHAR Reserved17[9]; /* 4D7h-4DFh */
|
||||||
|
|
||||||
|
/* DMA Stop Registers */
|
||||||
|
DMA_CHANNEL_STOP DmaChannelStop[8]; /* 4E0h-4FFh */
|
||||||
|
} EISA_CONTROL, *PEISA_CONTROL;
|
||||||
|
|
||||||
|
typedef struct _MAP_REGISTER_ENTRY
|
||||||
|
{
|
||||||
|
PVOID VirtualAddress;
|
||||||
|
PHYSICAL_ADDRESS PhysicalAddress;
|
||||||
|
ULONG Counter;
|
||||||
|
} MAP_REGISTER_ENTRY, *PMAP_REGISTER_ENTRY;
|
||||||
|
|
||||||
|
struct _ADAPTER_OBJECT {
|
||||||
|
/*
|
||||||
|
* New style DMA object definition. The fact that it is at the beginning
|
||||||
|
* of the ADAPTER_OBJECT structure allows us to easily implement the
|
||||||
|
* fallback implementation of IoGetDmaAdapter.
|
||||||
|
*/
|
||||||
|
DMA_ADAPTER DmaHeader;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For normal adapter objects pointer to master adapter that takes care
|
||||||
|
* of channel allocation. For master adapter set to NULL.
|
||||||
|
*/
|
||||||
|
struct _ADAPTER_OBJECT *MasterAdapter;
|
||||||
|
|
||||||
|
ULONG MapRegistersPerChannel;
|
||||||
|
PVOID AdapterBaseVa;
|
||||||
|
PMAP_REGISTER_ENTRY MapRegisterBase;
|
||||||
|
|
||||||
|
ULONG NumberOfMapRegisters;
|
||||||
|
ULONG CommittedMapRegisters;
|
||||||
|
|
||||||
|
PWAIT_CONTEXT_BLOCK CurrentWcb;
|
||||||
|
KDEVICE_QUEUE ChannelWaitQueue;
|
||||||
|
PKDEVICE_QUEUE RegisterWaitQueue;
|
||||||
|
LIST_ENTRY AdapterQueue;
|
||||||
|
KSPIN_LOCK SpinLock;
|
||||||
|
PRTL_BITMAP MapRegisters;
|
||||||
|
PUCHAR PagePort;
|
||||||
|
UCHAR ChannelNumber;
|
||||||
|
UCHAR AdapterNumber;
|
||||||
|
USHORT DmaPortAddress;
|
||||||
|
DMA_MODE AdapterMode;
|
||||||
|
BOOLEAN NeedsMapRegisters;
|
||||||
|
BOOLEAN MasterDevice;
|
||||||
|
BOOLEAN Width16Bits;
|
||||||
|
BOOLEAN ScatterGather;
|
||||||
|
BOOLEAN IgnoreCount;
|
||||||
|
BOOLEAN Dma32BitAddresses;
|
||||||
|
BOOLEAN Dma64BitAddresses;
|
||||||
|
LIST_ENTRY AdapterList;
|
||||||
|
} ADAPTER_OBJECT;
|
||||||
|
|
||||||
|
typedef struct _GROW_WORK_ITEM {
|
||||||
|
WORK_QUEUE_ITEM WorkQueueItem;
|
||||||
|
PADAPTER_OBJECT AdapterObject;
|
||||||
|
ULONG NumberOfMapRegisters;
|
||||||
|
} GROW_WORK_ITEM, *PGROW_WORK_ITEM;
|
||||||
|
|
||||||
|
#define MAP_BASE_SW_SG 1
|
||||||
|
|
||||||
|
PADAPTER_OBJECT STDCALL
|
||||||
|
HalpDmaAllocateMasterAdapter(VOID);
|
||||||
|
|
||||||
|
VOID STDCALL
|
||||||
|
HalPutDmaAdapter(
|
||||||
|
PADAPTER_OBJECT AdapterObject);
|
||||||
|
|
||||||
|
ULONG STDCALL
|
||||||
|
HalpDmaGetDmaAlignment(
|
||||||
|
PADAPTER_OBJECT AdapterObject);
|
||||||
|
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
IoAllocateAdapterChannel(
|
||||||
|
IN PADAPTER_OBJECT AdapterObject,
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN ULONG NumberOfMapRegisters,
|
||||||
|
IN PDRIVER_CONTROL ExecutionRoutine,
|
||||||
|
IN PVOID Context);
|
||||||
|
|
||||||
|
#endif /* HALDMA_H */
|
|
@ -40,358 +40,6 @@ PVOID HalpMapPhysMemory(ULONG PhysAddr, ULONG Size);
|
||||||
/* Non-generic initialization */
|
/* Non-generic initialization */
|
||||||
VOID HalpInitPhase0 (PLOADER_PARAMETER_BLOCK LoaderBlock);
|
VOID HalpInitPhase0 (PLOADER_PARAMETER_BLOCK LoaderBlock);
|
||||||
|
|
||||||
/* DMA Page Register Structure
|
|
||||||
080 DMA RESERVED
|
|
||||||
081 DMA Page Register (channel 2)
|
|
||||||
082 DMA Page Register (channel 3)
|
|
||||||
083 DMA Page Register (channel 1)
|
|
||||||
084 DMA RESERVED
|
|
||||||
085 DMA RESERVED
|
|
||||||
086 DMA RESERVED
|
|
||||||
087 DMA Page Register (channel 0)
|
|
||||||
088 DMA RESERVED
|
|
||||||
089 PS/2-DMA Page Register (channel 6)
|
|
||||||
08A PS/2-DMA Page Register (channel 7)
|
|
||||||
08B PS/2-DMA Page Register (channel 5)
|
|
||||||
08C PS/2-DMA RESERVED
|
|
||||||
08D PS/2-DMA RESERVED
|
|
||||||
08E PS/2-DMA RESERVED
|
|
||||||
08F PS/2-DMA Page Register (channel 4)
|
|
||||||
*/
|
|
||||||
typedef struct _DMA_PAGE{
|
|
||||||
UCHAR Reserved1;
|
|
||||||
UCHAR Channel2;
|
|
||||||
UCHAR Channel3;
|
|
||||||
UCHAR Channel1;
|
|
||||||
UCHAR Reserved2[3];
|
|
||||||
UCHAR Channel0;
|
|
||||||
UCHAR Reserved3;
|
|
||||||
UCHAR Channel6;
|
|
||||||
UCHAR Channel7;
|
|
||||||
UCHAR Channel5;
|
|
||||||
UCHAR Reserved4[3];
|
|
||||||
UCHAR Channel4;
|
|
||||||
} DMA_PAGE, *PDMA_PAGE;
|
|
||||||
|
|
||||||
/* DMA Channel Mask Register Structure
|
|
||||||
|
|
||||||
MSB LSB
|
|
||||||
x x x x x x x x
|
|
||||||
------------------- - -----
|
|
||||||
| | | 00 - Select channel 0 mask bit
|
|
||||||
| | \---- 01 - Select channel 1 mask bit
|
|
||||||
| | 10 - Select channel 2 mask bit
|
|
||||||
| | 11 - Select channel 3 mask bit
|
|
||||||
| |
|
|
||||||
| \---------- 0 - Clear mask bit
|
|
||||||
| 1 - Set mask bit
|
|
||||||
|
|
|
||||||
\----------------------- xx - Reserved
|
|
||||||
*/
|
|
||||||
typedef struct _DMA_CHANNEL_MASK {
|
|
||||||
UCHAR Channel : 2;
|
|
||||||
UCHAR SetMask : 1;
|
|
||||||
UCHAR Reserved : 5;
|
|
||||||
} DMA_CHANNEL_MASK, *PDMA_CHANNEL_MASK;
|
|
||||||
|
|
||||||
/* DMA Mask Register Structure
|
|
||||||
|
|
||||||
MSB LSB
|
|
||||||
x x x x x x x x
|
|
||||||
\---/ - - ----- -----
|
|
||||||
| | | | | 00 - Channel 0 select
|
|
||||||
| | | | \---- 01 - Channel 1 select
|
|
||||||
| | | | 10 - Channel 2 select
|
|
||||||
| | | | 11 - Channel 3 select
|
|
||||||
| | | |
|
|
||||||
| | | | 00 - Verify transfer
|
|
||||||
| | | \------------ 01 - Write transfer
|
|
||||||
| | | 10 - Read transfer
|
|
||||||
| | |
|
|
||||||
| | \-------------------- 0 - Autoinitialized
|
|
||||||
| | 1 - Non-autoinitialized
|
|
||||||
| |
|
|
||||||
| \------------------------ 0 - Address increment select
|
|
||||||
|
|
|
||||||
| 00 - Demand mode
|
|
||||||
\------------------------------ 01 - Single mode
|
|
||||||
10 - Block mode
|
|
||||||
11 - Cascade mode
|
|
||||||
*/
|
|
||||||
typedef struct _DMA_MODE {
|
|
||||||
UCHAR Channel : 2;
|
|
||||||
UCHAR TransferType : 2;
|
|
||||||
UCHAR AutoInitialize : 1;
|
|
||||||
UCHAR AddressDecrement : 1;
|
|
||||||
UCHAR RequestMode : 2;
|
|
||||||
} DMA_MODE, *PDMA_MODE;
|
|
||||||
|
|
||||||
|
|
||||||
/* DMA Extended Mode Register Structure
|
|
||||||
|
|
||||||
MSB LSB
|
|
||||||
x x x x x x x x
|
|
||||||
- - ----- ----- -----
|
|
||||||
| | | | | 00 - Channel 0 select
|
|
||||||
| | | | \---- 01 - Channel 1 select
|
|
||||||
| | | | 10 - Channel 2 select
|
|
||||||
| | | | 11 - Channel 3 select
|
|
||||||
| | | |
|
|
||||||
| | | | 00 - 8-bit I/O, by bytes
|
|
||||||
| | | \------------ 01 - 16-bit I/O, by words, address shifted
|
|
||||||
| | | 10 - 32-bit I/O, by bytes
|
|
||||||
| | | 11 - 16-bit I/O, by bytes
|
|
||||||
| | |
|
|
||||||
| | \---------------------- 00 - Compatible
|
|
||||||
| | 01 - Type A
|
|
||||||
| | 10 - Type B
|
|
||||||
| | 11 - Burst
|
|
||||||
| |
|
|
||||||
| \---------------------------- 0 - Terminal Count is Output
|
|
||||||
|
|
|
||||||
\---------------------------------0 - Disable Stop Register
|
|
||||||
1 - Enable Stop Register
|
|
||||||
*/
|
|
||||||
typedef struct _DMA_EXTENDED_MODE {
|
|
||||||
UCHAR ChannelNumber : 2;
|
|
||||||
UCHAR TransferSize : 2;
|
|
||||||
UCHAR TimingMode : 2;
|
|
||||||
UCHAR TerminalCountIsOutput : 1;
|
|
||||||
UCHAR EnableStopRegister : 1;
|
|
||||||
}DMA_EXTENDED_MODE, *PDMA_EXTENDED_MODE;
|
|
||||||
|
|
||||||
/* DMA Extended Mode Register Transfer Sizes */
|
|
||||||
#define B_8BITS 0
|
|
||||||
#define W_16BITS 1
|
|
||||||
#define B_32BITS 2
|
|
||||||
#define B_16BITS 3
|
|
||||||
|
|
||||||
/* DMA Extended Mode Register Timing */
|
|
||||||
#define COMPATIBLE_TIMING 0
|
|
||||||
#define TYPE_A_TIMING 1
|
|
||||||
#define TYPE_B_TIMING 2
|
|
||||||
#define BURST_TIMING 3
|
|
||||||
|
|
||||||
/* Channel Stop Registers for each Channel */
|
|
||||||
typedef struct _DMA_CHANNEL_STOP {
|
|
||||||
UCHAR ChannelLow;
|
|
||||||
UCHAR ChannelMid;
|
|
||||||
UCHAR ChannelHigh;
|
|
||||||
UCHAR Reserved;
|
|
||||||
} DMA_CHANNEL_STOP, *PDMA_CHANNEL_STOP;
|
|
||||||
|
|
||||||
/* Transfer Types */
|
|
||||||
#define VERIFY_TRANSFER 0x00
|
|
||||||
#define READ_TRANSFER 0x01
|
|
||||||
#define WRITE_TRANSFER 0x02
|
|
||||||
|
|
||||||
/* Request Modes */
|
|
||||||
#define DEMAND_REQUEST_MODE 0x00
|
|
||||||
#define SINGLE_REQUEST_MODE 0x01
|
|
||||||
#define BLOCK_REQUEST_MODE 0x02
|
|
||||||
#define CASCADE_REQUEST_MODE 0x03
|
|
||||||
|
|
||||||
#define DMA_SETMASK 4
|
|
||||||
#define DMA_CLEARMASK 0
|
|
||||||
#define DMA_READ 4
|
|
||||||
#define DMA_WRITE 8
|
|
||||||
#define DMA_SINGLE_TRANSFER 0x40
|
|
||||||
#define DMA_AUTO_INIT 0x10
|
|
||||||
|
|
||||||
typedef struct _DMA1_ADDRESS_COUNT {
|
|
||||||
UCHAR DmaBaseAddress;
|
|
||||||
UCHAR DmaBaseCount;
|
|
||||||
} DMA1_ADDRESS_COUNT, *PDMA1_ADDRESS_COUNT;
|
|
||||||
|
|
||||||
typedef struct _DMA2_ADDRESS_COUNT {
|
|
||||||
UCHAR DmaBaseAddress;
|
|
||||||
UCHAR Reserved1;
|
|
||||||
UCHAR DmaBaseCount;
|
|
||||||
UCHAR Reserved2;
|
|
||||||
} DMA2_ADDRESS_COUNT, *PDMA2_ADDRESS_COUNT;
|
|
||||||
|
|
||||||
typedef struct _DMA1_CONTROL {
|
|
||||||
DMA1_ADDRESS_COUNT DmaAddressCount[4];
|
|
||||||
UCHAR DmaStatus;
|
|
||||||
UCHAR DmaRequest;
|
|
||||||
UCHAR SingleMask;
|
|
||||||
UCHAR Mode;
|
|
||||||
UCHAR ClearBytePointer;
|
|
||||||
UCHAR MasterClear;
|
|
||||||
UCHAR ClearMask;
|
|
||||||
UCHAR AllMask;
|
|
||||||
} DMA1_CONTROL, *PDMA1_CONTROL;
|
|
||||||
|
|
||||||
typedef struct _DMA2_CONTROL {
|
|
||||||
DMA2_ADDRESS_COUNT DmaAddressCount[4];
|
|
||||||
UCHAR DmaStatus;
|
|
||||||
UCHAR Reserved1;
|
|
||||||
UCHAR DmaRequest;
|
|
||||||
UCHAR Reserved2;
|
|
||||||
UCHAR SingleMask;
|
|
||||||
UCHAR Reserved3;
|
|
||||||
UCHAR Mode;
|
|
||||||
UCHAR Reserved4;
|
|
||||||
UCHAR ClearBytePointer;
|
|
||||||
UCHAR Reserved5;
|
|
||||||
UCHAR MasterClear;
|
|
||||||
UCHAR Reserved6;
|
|
||||||
UCHAR ClearMask;
|
|
||||||
UCHAR Reserved7;
|
|
||||||
UCHAR AllMask;
|
|
||||||
UCHAR Reserved8;
|
|
||||||
} DMA2_CONTROL, *PDMA2_CONTROL;
|
|
||||||
|
|
||||||
/* This Structure Defines the I/O Map of the 82537 Controller
|
|
||||||
I've only defined the registers which are likely to be useful to us */
|
|
||||||
typedef struct _EISA_CONTROL {
|
|
||||||
/* DMA Controller 1 */
|
|
||||||
DMA1_CONTROL DmaController1; /* 00h-0Fh */
|
|
||||||
UCHAR Reserved1[16]; /* 0Fh-1Fh */
|
|
||||||
|
|
||||||
/* Interrupt Controller 1 (PIC) */
|
|
||||||
UCHAR Pic1Operation; /* 20h */
|
|
||||||
UCHAR Pic1Interrupt; /* 21h */
|
|
||||||
UCHAR Reserved2[30]; /* 22h-3Fh */
|
|
||||||
|
|
||||||
/* Timer */
|
|
||||||
UCHAR TimerCounter; /* 40h */
|
|
||||||
UCHAR TimerMemoryRefresh; /* 41h */
|
|
||||||
UCHAR Speaker; /* 42h */
|
|
||||||
UCHAR TimerOperation; /* 43h */
|
|
||||||
UCHAR TimerMisc; /* 44h */
|
|
||||||
UCHAR Reserved3[2]; /* 45-46h */
|
|
||||||
UCHAR TimerCounterControl; /* 47h */
|
|
||||||
UCHAR TimerFailSafeCounter; /* 48h */
|
|
||||||
UCHAR Reserved4; /* 49h */
|
|
||||||
UCHAR TimerCounter2; /* 4Ah */
|
|
||||||
UCHAR TimerOperation2; /* 4Bh */
|
|
||||||
UCHAR Reserved5[20]; /* 4Ch-5Fh */
|
|
||||||
|
|
||||||
/* NMI / Keyboard / RTC */
|
|
||||||
UCHAR Keyboard; /* 60h */
|
|
||||||
UCHAR NmiStatus; /* 61h */
|
|
||||||
UCHAR Reserved6[14]; /* 62h-6Fh */
|
|
||||||
UCHAR NmiEnable; /* 70h */
|
|
||||||
UCHAR Reserved7[15]; /* 71h-7Fh */
|
|
||||||
|
|
||||||
/* DMA Page Registers Controller 1 */
|
|
||||||
DMA_PAGE DmaController1Pages; /* 80h-8Fh */
|
|
||||||
UCHAR Reserved8[16]; /* 90h-9Fh */
|
|
||||||
|
|
||||||
/* Interrupt Controller 2 (PIC) */
|
|
||||||
UCHAR Pic2Operation; /* 0A0h */
|
|
||||||
UCHAR Pic2Interrupt; /* 0A1h */
|
|
||||||
UCHAR Reserved9[30]; /* 0A2h-0BFh */
|
|
||||||
|
|
||||||
/* DMA Controller 2 */
|
|
||||||
DMA1_CONTROL DmaController2; /* 0C0h-0CFh */
|
|
||||||
|
|
||||||
/* System Reserved Ports */
|
|
||||||
UCHAR SystemReserved[816]; /* 0D0h-3FFh */
|
|
||||||
|
|
||||||
/* Extended DMA Registers, Controller 1 */
|
|
||||||
UCHAR DmaHighByteCount1[8]; /* 400h-407h */
|
|
||||||
UCHAR Reserved10[2]; /* 408h-409h */
|
|
||||||
UCHAR DmaChainMode1; /* 40Ah */
|
|
||||||
UCHAR DmaExtendedMode1; /* 40Bh */
|
|
||||||
UCHAR DmaBufferControl; /* 40Ch */
|
|
||||||
UCHAR Reserved11[84]; /* 40Dh-460h */
|
|
||||||
UCHAR ExtendedNmiControl; /* 461h */
|
|
||||||
UCHAR NmiCommand; /* 462h */
|
|
||||||
UCHAR Reserved12; /* 463h */
|
|
||||||
UCHAR BusMaster; /* 464h */
|
|
||||||
UCHAR Reserved13[27]; /* 465h-47Fh */
|
|
||||||
|
|
||||||
/* DMA Page Registers Controller 2 */
|
|
||||||
DMA_PAGE DmaController2Pages; /* 480h-48Fh */
|
|
||||||
UCHAR Reserved14[48]; /* 490h-4BFh */
|
|
||||||
|
|
||||||
/* Extended DMA Registers, Controller 2 */
|
|
||||||
UCHAR DmaHighByteCount2[16]; /* 4C0h-4CFh */
|
|
||||||
|
|
||||||
/* Edge/Level Control Registers */
|
|
||||||
UCHAR Pic1EdgeLevel; /* 4D0h */
|
|
||||||
UCHAR Pic2EdgeLevel; /* 4D1h */
|
|
||||||
UCHAR Reserved15[2]; /* 4D2h-4D3h */
|
|
||||||
|
|
||||||
/* Extended DMA Registers, Controller 2 */
|
|
||||||
UCHAR DmaChainMode2; /* 4D4h */
|
|
||||||
UCHAR Reserved16; /* 4D5h */
|
|
||||||
UCHAR DmaExtendedMode2; /* 4D6h */
|
|
||||||
UCHAR Reserved17[9]; /* 4D7h-4DFh */
|
|
||||||
|
|
||||||
/* DMA Stop Registers */
|
|
||||||
DMA_CHANNEL_STOP DmaChannelStop[8]; /* 4E0h-4FFh */
|
|
||||||
} EISA_CONTROL, *PEISA_CONTROL;
|
|
||||||
|
|
||||||
extern ULONG HalpEisaDma;
|
|
||||||
extern PADAPTER_OBJECT MasterAdapter;
|
|
||||||
|
|
||||||
ULONG HalpEisaDma;
|
|
||||||
PADAPTER_OBJECT MasterAdapter;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ADAPTER_OBJECT - Track a busmaster DMA adapter and its associated resources
|
|
||||||
*
|
|
||||||
* NOTES:
|
|
||||||
* - I've updated this to the Windows Object Defintion.
|
|
||||||
*/
|
|
||||||
struct _ADAPTER_OBJECT {
|
|
||||||
DMA_ADAPTER DmaHeader;
|
|
||||||
struct _ADAPTER_OBJECT *MasterAdapter;
|
|
||||||
ULONG MapRegistersPerChannel;
|
|
||||||
PVOID AdapterBaseVa;
|
|
||||||
PVOID MapRegisterBase;
|
|
||||||
ULONG NumberOfMapRegisters;
|
|
||||||
ULONG CommittedMapRegisters;
|
|
||||||
PWAIT_CONTEXT_BLOCK CurrentWcb;
|
|
||||||
KDEVICE_QUEUE ChannelWaitQueue;
|
|
||||||
PKDEVICE_QUEUE RegisterWaitQueue;
|
|
||||||
LIST_ENTRY AdapterQueue;
|
|
||||||
ULONG SpinLock;
|
|
||||||
PRTL_BITMAP MapRegisters;
|
|
||||||
PUCHAR PagePort;
|
|
||||||
UCHAR ChannelNumber;
|
|
||||||
UCHAR AdapterNumber;
|
|
||||||
USHORT DmaPortAddress;
|
|
||||||
union {
|
|
||||||
DMA_MODE AdapterMode;
|
|
||||||
UCHAR AdapterModeByte;
|
|
||||||
};
|
|
||||||
BOOLEAN NeedsMapRegisters;
|
|
||||||
BOOLEAN MasterDevice;
|
|
||||||
UCHAR Width16Bits;
|
|
||||||
UCHAR ScatterGather;
|
|
||||||
UCHAR IgnoreCount;
|
|
||||||
UCHAR Dma32BitAddresses;
|
|
||||||
UCHAR Dma64BitAddresses;
|
|
||||||
BOOLEAN LegacyAdapter;
|
|
||||||
LIST_ENTRY AdapterList;
|
|
||||||
} ADAPTER_OBJECT;
|
|
||||||
|
|
||||||
/*
|
|
||||||
struct _ADAPTER_OBJECT {
|
|
||||||
INTERFACE_TYPE InterfaceType;
|
|
||||||
BOOLEAN Master;
|
|
||||||
int Channel;
|
|
||||||
PVOID PagePort;
|
|
||||||
PVOID CountPort;
|
|
||||||
PVOID OffsetPort;
|
|
||||||
KSPIN_LOCK SpinLock;
|
|
||||||
PVOID Buffer;
|
|
||||||
BOOLEAN Inuse;
|
|
||||||
ULONG AvailableMapRegisters;
|
|
||||||
PVOID MapRegisterBase;
|
|
||||||
ULONG AllocatedMapRegisters;
|
|
||||||
PWAIT_CONTEXT_BLOCK WaitContextBlock;
|
|
||||||
KDEVICE_QUEUE DeviceQueue;
|
|
||||||
BOOLEAN ScatterGather;
|
|
||||||
BOOLEAN DemandMode;
|
|
||||||
BOOLEAN AutoInitialize;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* sysinfo.c */
|
/* sysinfo.c */
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
HalpQuerySystemInformation(IN HAL_QUERY_INFORMATION_CLASS InformationClass,
|
HalpQuerySystemInformation(IN HAL_QUERY_INFORMATION_CLASS InformationClass,
|
||||||
|
@ -399,7 +47,6 @@ HalpQuerySystemInformation(IN HAL_QUERY_INFORMATION_CLASS InformationClass,
|
||||||
IN OUT PVOID Buffer,
|
IN OUT PVOID Buffer,
|
||||||
OUT PULONG ReturnedLength);
|
OUT PULONG ReturnedLength);
|
||||||
|
|
||||||
|
|
||||||
/* Non-standard functions */
|
/* Non-standard functions */
|
||||||
VOID STDCALL
|
VOID STDCALL
|
||||||
HalReleaseDisplayOwnership();
|
HalReleaseDisplayOwnership();
|
||||||
|
|
Loading…
Reference in a new issue