mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 06:12:59 +00:00
Hal DMA Patch: Implemented correct AdapterObject, updated some AdapterFunctions, which are much more complete and correct now. Implemented EISA structure for port access instead of hard-coded offsets.
svn path=/trunk/; revision=11771
This commit is contained in:
parent
ac33643ce2
commit
1fe3441f75
8 changed files with 967 additions and 208 deletions
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: hal.c,v 1.7 2004/10/23 23:43:23 ion Exp $
|
/* $Id: hal.c,v 1.8 2004/11/21 21:53:06 ion Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -141,8 +141,7 @@ HalAssignSlotResources(
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
STDCALL
|
STDCALL
|
||||||
HalBeginSystemInterrupt(
|
HalBeginSystemInterrupt (ULONG Vector,
|
||||||
ULONG Vector,
|
|
||||||
KIRQL Irql,
|
KIRQL Irql,
|
||||||
PKIRQL OldIrql)
|
PKIRQL OldIrql)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: adapter.c,v 1.12 2004/10/22 20:08:21 ekohl Exp $
|
/* $Id: adapter.c,v 1.13 2004/11/21 21:53:06 ion Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
#include <ddk/iotypes.h>
|
#include <ddk/iotypes.h>
|
||||||
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
#include <hal.h>
|
#include <hal.h>
|
||||||
|
|
||||||
|
@ -66,7 +67,7 @@ HalAllocateAdapterChannel(
|
||||||
WaitContextBlock->NumberOfMapRegisters = NumberOfMapRegisters;
|
WaitContextBlock->NumberOfMapRegisters = NumberOfMapRegisters;
|
||||||
|
|
||||||
/* returns true if queued, else returns false and sets the queue to busy */
|
/* returns true if queued, else returns false and sets the queue to busy */
|
||||||
if(KeInsertDeviceQueue(&AdapterObject->DeviceQueue, &WaitContextBlock->WaitQueueEntry))
|
if(KeInsertDeviceQueue(&AdapterObject->ChannelWaitQueue, &WaitContextBlock->WaitQueueEntry))
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
/* 24-bit max address due to 16-bit dma controllers */
|
/* 24-bit max address due to 16-bit dma controllers */
|
||||||
|
@ -95,7 +96,7 @@ HalAllocateAdapterChannel(
|
||||||
if(!AdapterObject->MapRegisterBase)
|
if(!AdapterObject->MapRegisterBase)
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
AdapterObject->AllocatedMapRegisters = NumberOfMapRegisters;
|
AdapterObject->CommittedMapRegisters = NumberOfMapRegisters;
|
||||||
|
|
||||||
/* call the client's AdapterControl callback with its map registers and context */
|
/* call the client's AdapterControl callback with its map registers and context */
|
||||||
Retval = ExecutionRoutine(WaitContextBlock->DeviceObject, WaitContextBlock->CurrentIrp,
|
Retval = ExecutionRoutine(WaitContextBlock->DeviceObject, WaitContextBlock->CurrentIrp,
|
||||||
|
@ -119,7 +120,7 @@ HalAllocateAdapterChannel(
|
||||||
else if(Retval == DeallocateObjectKeepRegisters)
|
else if(Retval == DeallocateObjectKeepRegisters)
|
||||||
{
|
{
|
||||||
/* don't free the allocated map registers - this is what IoFreeAdapterChannel checks */
|
/* don't free the allocated map registers - this is what IoFreeAdapterChannel checks */
|
||||||
AdapterObject->AllocatedMapRegisters = 0;
|
AdapterObject->CommittedMapRegisters = 0;
|
||||||
IoFreeAdapterChannel(AdapterObject);
|
IoFreeAdapterChannel(AdapterObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,6 +132,171 @@ HalAllocateAdapterChannel(
|
||||||
return STATUS_SUCCESS;
|
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 / 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 + sizeof(RTL_BITMAP)),
|
||||||
|
64);
|
||||||
|
|
||||||
|
/* 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
|
BOOLEAN STDCALL
|
||||||
IoFlushAdapterBuffers (
|
IoFlushAdapterBuffers (
|
||||||
|
@ -164,10 +330,20 @@ IoFlushAdapterBuffers (
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* mask out (disable) the dma channel */
|
/* mask out (disable) the dma channel */
|
||||||
if (AdapterObject->Channel < 4)
|
if (AdapterObject->AdapterNumber == 1) {
|
||||||
WRITE_PORT_UCHAR( (PVOID)0x0A, (UCHAR)(AdapterObject->Channel | 0x4) );
|
|
||||||
else
|
/* Set this for Ease */
|
||||||
WRITE_PORT_UCHAR( (PVOID)0xD4, (UCHAR)((AdapterObject->Channel - 4) | 0x4) );
|
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)
|
if(WriteToDevice)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -202,10 +378,10 @@ IoFreeAdapterChannel (PADAPTER_OBJECT AdapterObject)
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
/* To keep map registers, call here with the following set to 0 */
|
/* To keep map registers, call here with the following set to 0 */
|
||||||
if(AdapterObject->AllocatedMapRegisters)
|
if(AdapterObject->CommittedMapRegisters)
|
||||||
IoFreeMapRegisters(AdapterObject, AdapterObject->MapRegisterBase, AdapterObject->AllocatedMapRegisters);
|
IoFreeMapRegisters(AdapterObject, AdapterObject->MapRegisterBase, AdapterObject->CommittedMapRegisters);
|
||||||
|
|
||||||
if(!(WaitContextBlock = (PWAIT_CONTEXT_BLOCK)KeRemoveDeviceQueue(&AdapterObject->DeviceQueue)))
|
if(!(WaitContextBlock = (PWAIT_CONTEXT_BLOCK)KeRemoveDeviceQueue(&AdapterObject->ChannelWaitQueue)))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -241,7 +417,7 @@ IoFreeAdapterChannel (PADAPTER_OBJECT AdapterObject)
|
||||||
else if(Retval == DeallocateObjectKeepRegisters)
|
else if(Retval == DeallocateObjectKeepRegisters)
|
||||||
{
|
{
|
||||||
/* hide the map registers so they aren't deallocated next time around */
|
/* hide the map registers so they aren't deallocated next time around */
|
||||||
AdapterObject->AllocatedMapRegisters = 0;
|
AdapterObject->CommittedMapRegisters = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -265,7 +441,7 @@ IoFreeMapRegisters (
|
||||||
* - needs to be improved to use a real map register implementation
|
* - needs to be improved to use a real map register implementation
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
if( AdapterObject->AllocatedMapRegisters )
|
if( AdapterObject->CommittedMapRegisters )
|
||||||
{
|
{
|
||||||
MmFreeContiguousMemory(AdapterObject->MapRegisterBase);
|
MmFreeContiguousMemory(AdapterObject->MapRegisterBase);
|
||||||
AdapterObject->MapRegisterBase = 0;
|
AdapterObject->MapRegisterBase = 0;
|
||||||
|
@ -302,9 +478,8 @@ IoMapTransfer (
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PHYSICAL_ADDRESS Address;
|
PHYSICAL_ADDRESS Address;
|
||||||
PVOID MaskReg, ClearReg, ModeReg;
|
|
||||||
UCHAR ModeMask, LengthShift;
|
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
|
UCHAR Mode;
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
Address.QuadPart = 0ULL;
|
Address.QuadPart = 0ULL;
|
||||||
|
@ -313,14 +488,8 @@ IoMapTransfer (
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Isa System (slave) DMA? */
|
/* Isa System (slave) DMA? */
|
||||||
if (AdapterObject && AdapterObject->InterfaceType == Isa && !AdapterObject->Master)
|
if (MapRegisterBase && !AdapterObject->MasterDevice)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
/* channel 0 is reserved for DRAM refresh */
|
|
||||||
ASSERT(AdapterObject->Channel != 0);
|
|
||||||
/* channel 4 is reserved for cascade */
|
|
||||||
ASSERT(AdapterObject->Channel != 4);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
KeAcquireSpinLock(&AdapterObject->SpinLock, &OldIrql);
|
KeAcquireSpinLock(&AdapterObject->SpinLock, &OldIrql);
|
||||||
|
|
||||||
|
@ -341,56 +510,77 @@ IoMapTransfer (
|
||||||
* -- Filip Navara, 19/07/2004
|
* -- Filip Navara, 19/07/2004
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Get the mode for easier coding */
|
||||||
|
Mode = AdapterObject->AdapterMode;
|
||||||
|
|
||||||
/* if it is a write to the device, copy the caller buffer to the low buffer */
|
/* if it is a write to the device, copy the caller buffer to the low buffer */
|
||||||
if( WriteToDevice && !AdapterObject->AutoInitialize )
|
if ((WriteToDevice) && !((PDMA_MODE)&Mode)->AutoInitialize)
|
||||||
{
|
{
|
||||||
memcpy(MapRegisterBase,
|
memcpy(MapRegisterBase,
|
||||||
(char*)MmGetSystemAddressForMdl(Mdl) + ((ULONG)CurrentVa - (ULONG)MmGetMdlVirtualAddress(Mdl)),
|
(char*)MmGetSystemAddressForMdl(Mdl) + ((ULONG)CurrentVa - (ULONG)MmGetMdlVirtualAddress(Mdl)),
|
||||||
*Length );
|
*Length );
|
||||||
}
|
}
|
||||||
|
|
||||||
// 16-bit DMA
|
/* Writer Adapter Mode, transfer type */
|
||||||
if( AdapterObject->Channel >= 4 )
|
((PDMA_MODE)&Mode)->TransferType = (WriteToDevice ? WRITE_TRANSFER : READ_TRANSFER);
|
||||||
{
|
|
||||||
MaskReg = (PVOID)0xD4; ClearReg = (PVOID)0xD8; ModeReg = (PVOID)0xD6;
|
|
||||||
LengthShift = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MaskReg = (PVOID)0x0A; ClearReg = (PVOID)0x0C; ModeReg = (PVOID)0x0B;
|
|
||||||
LengthShift = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate the mask we will later set to the mode register
|
|
||||||
ModeMask = (AdapterObject->Channel & 3) | ( WriteToDevice ? 0x8 : 0x4 );
|
|
||||||
// FIXME: if not demand mode, which mode to use? 0x40 for single mode
|
|
||||||
if (!AdapterObject->DemandMode)
|
|
||||||
ModeMask |= 0x40;
|
|
||||||
if (AdapterObject->AutoInitialize)
|
|
||||||
ModeMask |= 0x10;
|
|
||||||
|
|
||||||
// program up the dma controller, and return
|
// program up the dma controller, and return
|
||||||
if (!AdapterObject->AutoInitialize)
|
if (!((PDMA_MODE)&Mode)->AutoInitialize) {
|
||||||
Address = MmGetPhysicalAddress( MapRegisterBase );
|
Address = MmGetPhysicalAddress( MapRegisterBase );
|
||||||
else
|
} else {
|
||||||
Address = MmGetPhysicalAddress( CurrentVa );
|
Address = MmGetPhysicalAddress( CurrentVa );
|
||||||
// disable and select the channel number
|
}
|
||||||
WRITE_PORT_UCHAR( MaskReg, (UCHAR)((AdapterObject->Channel & 3) | 0x4) );
|
|
||||||
// write zero to the reset register
|
|
||||||
WRITE_PORT_UCHAR( ClearReg, 0 );
|
|
||||||
// mode register, or channel with 0x4 for write memory, 0x8 for read memory, 0x10 for auto initialize
|
|
||||||
WRITE_PORT_UCHAR( ModeReg, ModeMask);
|
|
||||||
// set the 64k page register for the channel
|
|
||||||
WRITE_PORT_UCHAR( AdapterObject->PagePort, (UCHAR)(Address.u.LowPart >> 16) );
|
|
||||||
// low, then high address byte, which is always 0 for us, because we have a 64k alligned address
|
|
||||||
WRITE_PORT_UCHAR( AdapterObject->OffsetPort, 0 );
|
|
||||||
WRITE_PORT_UCHAR( AdapterObject->OffsetPort, 0 );
|
|
||||||
// count is 1 less than length, low then high
|
|
||||||
WRITE_PORT_UCHAR( AdapterObject->CountPort, (UCHAR)((*Length >> LengthShift) - 1) );
|
|
||||||
WRITE_PORT_UCHAR( AdapterObject->CountPort, (UCHAR)(((*Length >> LengthShift) - 1)>>8) );
|
|
||||||
// unmask the channel to let it rip
|
|
||||||
WRITE_PORT_UCHAR( MaskReg, AdapterObject->Channel & 3 );
|
|
||||||
|
|
||||||
|
/* 16-bit DMA has a shifted length */
|
||||||
|
if (AdapterObject->Width16Bits) *Length = (*Length >> 1);
|
||||||
|
|
||||||
|
/* Make the Transfer */
|
||||||
|
if (AdapterObject->AdapterNumber == 1) {
|
||||||
|
|
||||||
|
PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa; /* For Writing Less Code */
|
||||||
|
|
||||||
|
/* Reset Register */
|
||||||
|
WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
|
||||||
|
|
||||||
|
/* Set the Mode */
|
||||||
|
WRITE_PORT_UCHAR(&DmaControl1->Mode, (UCHAR)(Mode));
|
||||||
|
|
||||||
|
/* Set the Page 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) - 1));
|
||||||
|
WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
|
||||||
|
(UCHAR)((*Length) - 1) >> 8);
|
||||||
|
|
||||||
|
/* Unmask the Channel */
|
||||||
|
WRITE_PORT_UCHAR(&DmaControl1->SingleMask, AdapterObject->ChannelNumber | DMA_CLEARMASK);
|
||||||
|
} else {
|
||||||
|
PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa; /* For Writing Less Code */
|
||||||
|
|
||||||
|
/* Reset Register */
|
||||||
|
WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
|
||||||
|
|
||||||
|
/* Set the Mode */
|
||||||
|
WRITE_PORT_UCHAR(&DmaControl2->Mode, (UCHAR)(Mode));
|
||||||
|
|
||||||
|
/* Set the Page 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) - 1));
|
||||||
|
WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
|
||||||
|
(UCHAR)((*Length) - 1) >> 8);
|
||||||
|
|
||||||
|
/* Unmask the Channel */
|
||||||
|
WRITE_PORT_UCHAR(&DmaControl2->SingleMask, AdapterObject->ChannelNumber | DMA_CLEARMASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release Spinlock */
|
||||||
KeReleaseSpinLock(&AdapterObject->SpinLock, OldIrql);
|
KeReleaseSpinLock(&AdapterObject->SpinLock, OldIrql);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -409,7 +599,7 @@ IoMapTransfer (
|
||||||
being NULL is used to detect a s/g busmaster.
|
being NULL is used to detect a s/g busmaster.
|
||||||
*/
|
*/
|
||||||
if ((!AdapterObject && !MapRegisterBase) ||
|
if ((!AdapterObject && !MapRegisterBase) ||
|
||||||
(AdapterObject && AdapterObject->Master && AdapterObject->ScatterGather))
|
(AdapterObject && AdapterObject->MasterDevice && AdapterObject->ScatterGather))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Just return the passed VA's corresponding phys. address.
|
Just return the passed VA's corresponding phys. address.
|
||||||
|
@ -459,7 +649,7 @@ IoMapTransfer (
|
||||||
not being NULL is used to detect a non s/g busmaster.
|
not being NULL is used to detect a non s/g busmaster.
|
||||||
*/
|
*/
|
||||||
if ((!AdapterObject && MapRegisterBase) ||
|
if ((!AdapterObject && MapRegisterBase) ||
|
||||||
(AdapterObject && AdapterObject->Master && !AdapterObject->ScatterGather))
|
(AdapterObject && AdapterObject->MasterDevice && !AdapterObject->ScatterGather))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
NOTE: Busmasters doing common-buffer DMA shouldn't call IoMapTransfer, but I don't
|
NOTE: Busmasters doing common-buffer DMA shouldn't call IoMapTransfer, but I don't
|
||||||
|
@ -476,7 +666,7 @@ IoMapTransfer (
|
||||||
return MmGetPhysicalAddress(MapRegisterBase);
|
return MmGetPhysicalAddress(MapRegisterBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT1("IoMapTransfer: Unsupported operation\n");
|
DPRINT("IoMapTransfer: Unsupported operation\n");
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
return Address;
|
return Address;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: dma.c,v 1.9 2004/07/22 18:49:18 navaraf Exp $
|
/* $Id: dma.c,v 1.10 2004/11/21 21:53:06 ion Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -12,42 +12,19 @@
|
||||||
/* INCLUDES *****************************************************************/
|
/* INCLUDES *****************************************************************/
|
||||||
|
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
#include <hal.h>
|
#include <hal.h>
|
||||||
|
|
||||||
/* XXX This initialization is out of date - ADAPTER_OBJECT has changed */
|
/* Adapters for each channel */
|
||||||
/* NOTE: The following initializations have to be kept in synch with ADAPTER_OBJECT in hal.h */
|
PADAPTER_OBJECT HalpEisaAdapter[8];
|
||||||
ADAPTER_OBJECT IsaSlaveAdapterObjects[] = {
|
|
||||||
{ Isa, FALSE, 0, (PVOID)0x87, (PVOID)0x1, (PVOID)0x0, 0, NULL },
|
|
||||||
{ Isa, FALSE, 1, (PVOID)0x83, (PVOID)0x3, (PVOID)0x2, 0, NULL },
|
|
||||||
{ Isa, FALSE, 2, (PVOID)0x81, (PVOID)0x5, (PVOID)0x4, 0, NULL },
|
|
||||||
{ Isa, FALSE, 3, (PVOID)0x82, (PVOID)0x7, (PVOID)0x6, 0, NULL },
|
|
||||||
/* 16-bit DMA */
|
|
||||||
{ Isa, FALSE, 4, (PVOID)0x8F, (PVOID)0xC2, (PVOID)0xC0, 0, NULL },
|
|
||||||
{ Isa, FALSE, 5, (PVOID)0x8B, (PVOID)0xC6, (PVOID)0xC4, 0, NULL },
|
|
||||||
{ Isa, FALSE, 6, (PVOID)0x89, (PVOID)0xCA, (PVOID)0xC8, 0, NULL },
|
|
||||||
{ Isa, FALSE, 7, (PVOID)0x8A, (PVOID)0xCE, (PVOID)0xCC, 0, NULL } };
|
|
||||||
|
|
||||||
ADAPTER_OBJECT PciBusMasterAdapterObjects[] = {
|
|
||||||
{ PCIBus, TRUE, 0, (PVOID)0, (PVOID)0, (PVOID)0x0, 0, NULL } };
|
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
HalpInitDma (VOID)
|
HalpInitDma (VOID)
|
||||||
{
|
{
|
||||||
ULONG Index;
|
/* TODO: Initialize the first Map Buffer */
|
||||||
|
|
||||||
KeInitializeDeviceQueue(&PciBusMasterAdapterObjects[0].DeviceQueue);
|
|
||||||
KeInitializeSpinLock(&PciBusMasterAdapterObjects[0].SpinLock);
|
|
||||||
PciBusMasterAdapterObjects[0].Inuse = FALSE;
|
|
||||||
for (Index = 0; Index < 8; Index++)
|
|
||||||
{
|
|
||||||
KeInitializeDeviceQueue(&IsaSlaveAdapterObjects[Index].DeviceQueue);
|
|
||||||
KeInitializeSpinLock(&IsaSlaveAdapterObjects[Index].SpinLock);
|
|
||||||
IsaSlaveAdapterObjects[Index].Inuse = FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PVOID STDCALL
|
PVOID STDCALL
|
||||||
|
@ -79,14 +56,10 @@ HalAllocateCommonBuffer (PADAPTER_OBJECT AdapterObject,
|
||||||
LowestAddress.QuadPart = 0;
|
LowestAddress.QuadPart = 0;
|
||||||
BoundryAddressMultiple.QuadPart = 0;
|
BoundryAddressMultiple.QuadPart = 0;
|
||||||
HighestAddress.u.HighPart = 0;
|
HighestAddress.u.HighPart = 0;
|
||||||
if (AdapterObject->InterfaceType == Isa ||
|
if ((AdapterObject->Dma32BitAddresses) && (AdapterObject->MasterDevice)) {
|
||||||
(AdapterObject->InterfaceType == MicroChannel && AdapterObject->Master == FALSE))
|
|
||||||
{
|
|
||||||
HighestAddress.u.LowPart = 0x00FFFFFF; /* 24Bit: 16MB address range */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HighestAddress.u.LowPart = 0xFFFFFFFF; /* 32Bit: 4GB address range */
|
HighestAddress.u.LowPart = 0xFFFFFFFF; /* 32Bit: 4GB address range */
|
||||||
|
} else {
|
||||||
|
HighestAddress.u.LowPart = 0x00FFFFFF; /* 24Bit: 16MB address range */
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseAddress = MmAllocateContiguousAlignedMemory(
|
BaseAddress = MmAllocateContiguousAlignedMemory(
|
||||||
|
@ -141,49 +114,284 @@ HalGetAdapter (PDEVICE_DESCRIPTION DeviceDescription,
|
||||||
* RETURNS: The allocated adapter object on success
|
* RETURNS: The allocated adapter object on success
|
||||||
* NULL on failure
|
* NULL on failure
|
||||||
* TODO:
|
* TODO:
|
||||||
* Honour all the fields in DeviceDescription structure.
|
* Testing
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PADAPTER_OBJECT AdapterObject;
|
PADAPTER_OBJECT AdapterObject;
|
||||||
|
DWORD ChannelSelect;
|
||||||
|
DWORD Controller;
|
||||||
|
ULONG MaximumLength;
|
||||||
|
BOOLEAN ChannelSetup;
|
||||||
|
|
||||||
|
DPRINT("Entered Function\n");
|
||||||
|
|
||||||
/* Validate parameters in device description, and return a pointer to
|
/* Validate parameters in device description, and return a pointer to
|
||||||
the adapter object for the requested dma channel */
|
the adapter object for the requested dma channel */
|
||||||
if( DeviceDescription->Version != DEVICE_DESCRIPTION_VERSION )
|
if(DeviceDescription->Version != DEVICE_DESCRIPTION_VERSION) {
|
||||||
return NULL;
|
DPRINT("Invalid Adapter version!\n");
|
||||||
|
|
||||||
switch (DeviceDescription->InterfaceType)
|
|
||||||
{
|
|
||||||
case PCIBus:
|
|
||||||
if (DeviceDescription->Master == FALSE)
|
|
||||||
return NULL;
|
|
||||||
return &PciBusMasterAdapterObjects[0];
|
|
||||||
|
|
||||||
case Isa:
|
|
||||||
/* There are only 8 DMA channels on ISA. */
|
|
||||||
if (DeviceDescription->DmaChannel >= 8)
|
|
||||||
return NULL;
|
|
||||||
/* Channels 1-4 are for 8-bit transfers... */
|
|
||||||
if (DeviceDescription->DmaWidth != Width8Bits &&
|
|
||||||
DeviceDescription->DmaChannel < 4)
|
|
||||||
return NULL;
|
|
||||||
/* ...and the rest is for 16-bit transfers. */
|
|
||||||
if (DeviceDescription->DmaWidth != Width16Bits &&
|
|
||||||
DeviceDescription->DmaChannel >= 4)
|
|
||||||
return NULL;
|
|
||||||
AdapterObject = &IsaSlaveAdapterObjects[DeviceDescription->DmaChannel];
|
|
||||||
AdapterObject->Master = DeviceDescription->Master;
|
|
||||||
AdapterObject->ScatterGather = DeviceDescription->ScatterGather;
|
|
||||||
AdapterObject->AutoInitialize = DeviceDescription->AutoInitialize;
|
|
||||||
AdapterObject->DemandMode = DeviceDescription->DemandMode;
|
|
||||||
AdapterObject->Buffer = 0;
|
|
||||||
/* FIXME: Is this correct? */
|
|
||||||
*NumberOfMapRegisters = 16;
|
|
||||||
return AdapterObject;
|
|
||||||
|
|
||||||
default:
|
|
||||||
/* Unsupported bus. */
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPRINT("Checking Interface Type: %x \n", DeviceDescription->InterfaceType);
|
||||||
|
if (DeviceDescription->InterfaceType == PCIBus) {
|
||||||
|
if (DeviceDescription->Master == FALSE) {
|
||||||
|
DPRINT("Invalid request!\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ChannelSetup = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* There are only 8 DMA channels on ISA, so any request above this
|
||||||
|
should not get any channel setup */
|
||||||
|
if (DeviceDescription->DmaChannel >= 8) {
|
||||||
|
ChannelSetup = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Channel 4 is Reserved for Chaining, so you cant use it */
|
||||||
|
if (DeviceDescription->DmaChannel == 4 && ChannelSetup) {
|
||||||
|
DPRINT("Invalid request!\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Devices that support Scatter/Gather do not need Map Registers */
|
||||||
|
if (DeviceDescription->ScatterGather &&
|
||||||
|
(DeviceDescription->InterfaceType == Eisa ||
|
||||||
|
DeviceDescription->InterfaceType == PCIBus)) {
|
||||||
|
*NumberOfMapRegisters = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if Extended DMA is available (we're just going to do a random read/write
|
||||||
|
I picked Channel 2 because it's the first Channel in the Register */
|
||||||
|
WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaController1Pages.Channel2), 0x2A);
|
||||||
|
if (READ_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaController1Pages.Channel2)) == 0x2A) {
|
||||||
|
HalpEisaDma = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find out how many Map Registers we need */
|
||||||
|
DPRINT("Setting up Adapter Settings!\n");
|
||||||
|
MaximumLength = DeviceDescription->MaximumLength & 0x7FFFFFFF;
|
||||||
|
*NumberOfMapRegisters = BYTES_TO_PAGES(MaximumLength) + 1;
|
||||||
|
|
||||||
|
/* Set the Channel Selection */
|
||||||
|
ChannelSelect = DeviceDescription->DmaChannel & 0x03;
|
||||||
|
|
||||||
|
/* Get the Controller Setup */
|
||||||
|
Controller = (DeviceDescription->DmaChannel & 0x04) ? 1 : 2;
|
||||||
|
|
||||||
|
/* Get the Adapter Object */
|
||||||
|
if (HalpEisaAdapter[DeviceDescription->DmaChannel] != NULL) {
|
||||||
|
|
||||||
|
/* Already allocated, return it */
|
||||||
|
DPRINT("Getting an Adapter Object from the Cache\n");
|
||||||
|
AdapterObject = HalpEisaAdapter[DeviceDescription->DmaChannel];
|
||||||
|
|
||||||
|
/* Do we need more Map Registers this time? */
|
||||||
|
if ((AdapterObject->NeedsMapRegisters) &&
|
||||||
|
(*NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel)) {
|
||||||
|
AdapterObject->MapRegistersPerChannel = *NumberOfMapRegisters;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* We have to allocate a new object! How exciting! */
|
||||||
|
DPRINT("Allocating a new Adapter Object\n");
|
||||||
|
AdapterObject = HalpAllocateAdapterEx(*NumberOfMapRegisters,
|
||||||
|
FALSE,
|
||||||
|
DeviceDescription->Dma32BitAddresses);
|
||||||
|
|
||||||
|
if (AdapterObject == NULL) return NULL;
|
||||||
|
|
||||||
|
HalpEisaAdapter[DeviceDescription->DmaChannel] = AdapterObject;
|
||||||
|
|
||||||
|
if (!*NumberOfMapRegisters) {
|
||||||
|
/* Easy case, no Map Registers needed */
|
||||||
|
AdapterObject->NeedsMapRegisters = FALSE;
|
||||||
|
|
||||||
|
/* If you're the master, you get all you want */
|
||||||
|
if (DeviceDescription->Master) {
|
||||||
|
AdapterObject->MapRegistersPerChannel= *NumberOfMapRegisters;
|
||||||
|
} else {
|
||||||
|
AdapterObject->MapRegistersPerChannel = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* We Desire Registers */
|
||||||
|
AdapterObject->NeedsMapRegisters = TRUE;
|
||||||
|
|
||||||
|
/* The registers you want */
|
||||||
|
AdapterObject->MapRegistersPerChannel = *NumberOfMapRegisters;
|
||||||
|
|
||||||
|
/* Increase commitment */
|
||||||
|
MasterAdapter->CommittedMapRegisters += *NumberOfMapRegisters;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set up DMA Structure */
|
||||||
|
if (Controller == 1) {
|
||||||
|
AdapterObject->AdapterBaseVa = (PVOID)FIELD_OFFSET(EISA_CONTROL, DmaController1);
|
||||||
|
} else {
|
||||||
|
AdapterObject->AdapterBaseVa = (PVOID)FIELD_OFFSET(EISA_CONTROL, DmaController2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set up Some Adapter Data */
|
||||||
|
DPRINT("Setting up an Adapter Object\n");
|
||||||
|
AdapterObject->IgnoreCount = DeviceDescription->IgnoreCount;
|
||||||
|
AdapterObject->Dma32BitAddresses = DeviceDescription->Dma32BitAddresses;
|
||||||
|
AdapterObject->Dma64BitAddresses = DeviceDescription->Dma64BitAddresses;
|
||||||
|
AdapterObject->ScatterGather = DeviceDescription->ScatterGather;
|
||||||
|
AdapterObject->MasterDevice = DeviceDescription->Master;
|
||||||
|
if (DeviceDescription->InterfaceType != PCIBus) AdapterObject->LegacyAdapter = TRUE;
|
||||||
|
|
||||||
|
/* Everything below is not required if we don't need a channel */
|
||||||
|
if (!ChannelSetup) {
|
||||||
|
DPRINT("Retuning Adapter Object without Channel Setup\n");
|
||||||
|
return AdapterObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
AdapterObject->ChannelNumber = ChannelSelect;
|
||||||
|
|
||||||
|
|
||||||
|
/* Set up the Page Port */
|
||||||
|
if (Controller == 1) {
|
||||||
|
switch (ChannelSelect) {
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel0));
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel1));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel2));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel3));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set Controller Number */
|
||||||
|
AdapterObject->AdapterNumber = 1;
|
||||||
|
} else {
|
||||||
|
switch (ChannelSelect) {
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel5));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel6));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel7));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set Controller Number */
|
||||||
|
AdapterObject->AdapterNumber = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set up the Extended Register */
|
||||||
|
if (HalpEisaDma) {
|
||||||
|
DMA_EXTENDED_MODE ExtendedMode;
|
||||||
|
|
||||||
|
ExtendedMode.ChannelNumber = ChannelSelect;
|
||||||
|
|
||||||
|
switch (DeviceDescription->DmaSpeed) {
|
||||||
|
|
||||||
|
case Compatible:
|
||||||
|
ExtendedMode.TimingMode = COMPATIBLE_TIMING;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeA:
|
||||||
|
ExtendedMode.TimingMode = TYPE_A_TIMING;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeB:
|
||||||
|
ExtendedMode.TimingMode = TYPE_B_TIMING;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeC:
|
||||||
|
ExtendedMode.TimingMode = BURST_TIMING;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (DeviceDescription->DmaWidth) {
|
||||||
|
|
||||||
|
case Width8Bits:
|
||||||
|
ExtendedMode.TransferSize = B_8BITS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Width16Bits:
|
||||||
|
ExtendedMode.TransferSize = B_16BITS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Width32Bits:
|
||||||
|
ExtendedMode.TransferSize = B_32BITS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Controller == 1) {
|
||||||
|
WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaExtendedMode1),
|
||||||
|
*((PUCHAR)&ExtendedMode));
|
||||||
|
} else {
|
||||||
|
WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaExtendedMode2),
|
||||||
|
*((PUCHAR)&ExtendedMode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Do 8/16-bit validation */
|
||||||
|
DPRINT("Validating an Adapter Object\n");
|
||||||
|
if (!DeviceDescription->Master) {
|
||||||
|
if ((DeviceDescription->DmaWidth == Width8Bits) && (Controller != 1)) {
|
||||||
|
return NULL; /* 8-bit is only avalable on Controller 1 */
|
||||||
|
} else if (DeviceDescription->DmaWidth == Width16Bits) {
|
||||||
|
if (Controller != 2) {
|
||||||
|
return NULL; /* 16-bit is only avalable on Controller 2 */
|
||||||
|
} else {
|
||||||
|
AdapterObject->Width16Bits = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UCHAR DmaMode;
|
||||||
|
DPRINT("Final DMA Request Mode Setting of the Adapter Object\n");
|
||||||
|
/* Set the DMA Request Modes */
|
||||||
|
if (DeviceDescription->Master) {
|
||||||
|
/* This is a cascade request */
|
||||||
|
((PDMA_MODE)&DmaMode)->RequestMode = CASCADE_REQUEST_MODE;
|
||||||
|
|
||||||
|
/* Send the request */
|
||||||
|
if (AdapterObject->AdapterNumber == 1) {
|
||||||
|
/* Set the Request Data */
|
||||||
|
WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterObject->AdapterBaseVa)->Mode,
|
||||||
|
AdapterObject->AdapterMode);
|
||||||
|
|
||||||
|
/* Unmask DMA Channel */
|
||||||
|
WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterObject->AdapterBaseVa)->SingleMask,
|
||||||
|
AdapterObject->ChannelNumber | DMA_CLEARMASK);
|
||||||
|
} else {
|
||||||
|
/* Set the Request Data */
|
||||||
|
WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterObject->AdapterBaseVa)->Mode,
|
||||||
|
AdapterObject->AdapterMode);
|
||||||
|
|
||||||
|
/* Unmask DMA Channel */
|
||||||
|
WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterObject->AdapterBaseVa)->SingleMask,
|
||||||
|
AdapterObject->ChannelNumber | DMA_CLEARMASK);
|
||||||
|
}
|
||||||
|
} else if (DeviceDescription->DemandMode) {
|
||||||
|
/* This is a Demand request */
|
||||||
|
((PDMA_MODE)&DmaMode)->RequestMode = DEMAND_REQUEST_MODE;
|
||||||
|
} else {
|
||||||
|
/* Normal Request */
|
||||||
|
((PDMA_MODE)&DmaMode)->RequestMode = SINGLE_REQUEST_MODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Auto Initialize Enabled or Not*/
|
||||||
|
((PDMA_MODE)&DmaMode)->AutoInitialize = DeviceDescription->AutoInitialize;
|
||||||
|
AdapterObject->AdapterMode = DmaMode;
|
||||||
|
return AdapterObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG STDCALL
|
ULONG STDCALL
|
||||||
|
@ -192,29 +400,46 @@ HalReadDmaCounter (PADAPTER_OBJECT AdapterObject)
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
ULONG Count;
|
ULONG Count;
|
||||||
|
|
||||||
if (AdapterObject && AdapterObject->InterfaceType == Isa && !AdapterObject->Master)
|
KeAcquireSpinLock(&AdapterObject->MasterAdapter->SpinLock, &OldIrql);
|
||||||
{
|
|
||||||
KeAcquireSpinLock(&AdapterObject->SpinLock, &OldIrql);
|
|
||||||
|
|
||||||
/* Clear the flip/flop register */
|
/* Send the Request to the specific controller */
|
||||||
WRITE_PORT_UCHAR( AdapterObject->Channel < 4 ? (PVOID)0x0C : (PVOID)0xD8, 0 );
|
if (AdapterObject->AdapterNumber == 1) {
|
||||||
/* Read the offset */
|
|
||||||
Count = READ_PORT_UCHAR( AdapterObject->CountPort );
|
|
||||||
Count |= READ_PORT_UCHAR( AdapterObject->CountPort ) << 8;
|
|
||||||
|
|
||||||
KeReleaseSpinLock(&AdapterObject->SpinLock, OldIrql);
|
/* Set this for Ease */
|
||||||
|
PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
|
||||||
|
|
||||||
/*
|
/* Send Reset */
|
||||||
* We must return twice the sound for channel >= 4 because it's the size
|
WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
|
||||||
* of words (16-bit) and not bytes.
|
|
||||||
*/
|
/* Read Count */
|
||||||
if (AdapterObject->Channel < 4)
|
Count = READ_PORT_UCHAR(&DmaControl1->DmaAddressCount
|
||||||
return Count;
|
[AdapterObject->ChannelNumber].DmaBaseCount);
|
||||||
else
|
Count |= READ_PORT_UCHAR(&DmaControl1->DmaAddressCount
|
||||||
return Count << 1;
|
[AdapterObject->ChannelNumber].DmaBaseCount) << 8;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* Set this for Ease */
|
||||||
|
PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
|
||||||
|
|
||||||
|
/* Send Reset */
|
||||||
|
WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
|
||||||
|
|
||||||
|
/* Read Count */
|
||||||
|
Count = READ_PORT_UCHAR(&DmaControl2->DmaAddressCount
|
||||||
|
[AdapterObject->ChannelNumber].DmaBaseCount);
|
||||||
|
Count |= READ_PORT_UCHAR(&DmaControl2->DmaAddressCount
|
||||||
|
[AdapterObject->ChannelNumber].DmaBaseCount) << 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
/* Play around with the count (add bias and multiply by 2 if 16-bit DMA) */
|
||||||
|
Count ++;
|
||||||
|
if (AdapterObject->Width16Bits) Count *=2 ;
|
||||||
|
|
||||||
|
KeReleaseSpinLock(&AdapterObject->MasterAdapter->SpinLock, OldIrql);
|
||||||
|
|
||||||
|
/* Return it */
|
||||||
|
return Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
VOID FASTCALL HalInitializeDisplay (PLOADER_PARAMETER_BLOCK LoaderBlock);
|
VOID FASTCALL HalInitializeDisplay (PLOADER_PARAMETER_BLOCK LoaderBlock);
|
||||||
VOID FASTCALL HalClearDisplay (UCHAR CharAttribute);
|
VOID FASTCALL HalClearDisplay (UCHAR CharAttribute);
|
||||||
|
|
||||||
|
/* adapter.c */
|
||||||
|
PADAPTER_OBJECT STDCALL HalpAllocateAdapterEx(ULONG NumberOfMapRegisters,BOOLEAN IsMaster, BOOLEAN Dma32BitAddresses);
|
||||||
|
|
||||||
/* bus.c */
|
/* bus.c */
|
||||||
VOID HalpInitBusHandlers (VOID);
|
VOID HalpInitBusHandlers (VOID);
|
||||||
|
|
||||||
|
@ -30,16 +33,334 @@ VOID HalpStartEnumerator (VOID);
|
||||||
/* dma.c */
|
/* dma.c */
|
||||||
VOID HalpInitDma (VOID);
|
VOID HalpInitDma (VOID);
|
||||||
|
|
||||||
|
/* 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-0DFh */
|
||||||
|
|
||||||
|
/* System Reserved Ports */
|
||||||
|
UCHAR SystemReserved[800]; /* 0E0h-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;
|
||||||
|
|
||||||
|
EXPORTED ULONG HalpEisaDma;
|
||||||
|
EXPORTED PADAPTER_OBJECT MasterAdapter;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ADAPTER_OBJECT - Track a busmaster DMA adapter and its associated resources
|
* ADAPTER_OBJECT - Track a busmaster DMA adapter and its associated resources
|
||||||
*
|
*
|
||||||
* NOTES:
|
* NOTES:
|
||||||
* - I have not found any documentation on this; if you have any, please
|
* - I've updated this to the Windows Object Defintion.
|
||||||
* fix this struct definition
|
|
||||||
* - Some of this is right and some of this is wrong; many of these fields
|
|
||||||
* are unused at this point because X86 doesn't have map registers and
|
|
||||||
* currently that's all ROS supports
|
|
||||||
*/
|
*/
|
||||||
|
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;
|
||||||
|
UCHAR AdapterMode;
|
||||||
|
BOOLEAN NeedsMapRegisters;
|
||||||
|
BOOLEAN MasterDevice;
|
||||||
|
UCHAR Width16Bits;
|
||||||
|
UCHAR ScatterGather;
|
||||||
|
UCHAR IgnoreCount;
|
||||||
|
UCHAR Dma32BitAddresses;
|
||||||
|
UCHAR Dma64BitAddresses;
|
||||||
|
BOOLEAN LegacyAdapter;
|
||||||
|
LIST_ENTRY AdapterList;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
struct _ADAPTER_OBJECT {
|
struct _ADAPTER_OBJECT {
|
||||||
INTERFACE_TYPE InterfaceType;
|
INTERFACE_TYPE InterfaceType;
|
||||||
BOOLEAN Master;
|
BOOLEAN Master;
|
||||||
|
@ -56,16 +377,10 @@ struct _ADAPTER_OBJECT {
|
||||||
PWAIT_CONTEXT_BLOCK WaitContextBlock;
|
PWAIT_CONTEXT_BLOCK WaitContextBlock;
|
||||||
KDEVICE_QUEUE DeviceQueue;
|
KDEVICE_QUEUE DeviceQueue;
|
||||||
BOOLEAN ScatterGather;
|
BOOLEAN ScatterGather;
|
||||||
|
|
||||||
/*
|
|
||||||
* 18/07/04: Added these members. It's propably not the exact place where
|
|
||||||
* this should be stored, but I can't find better one. I haven't checked
|
|
||||||
* how Windows handles this.
|
|
||||||
* -- Filip Navara
|
|
||||||
*/
|
|
||||||
BOOLEAN DemandMode;
|
BOOLEAN DemandMode;
|
||||||
BOOLEAN AutoInitialize;
|
BOOLEAN AutoInitialize;
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
/* sysinfo.c */
|
/* sysinfo.c */
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
|
|
|
@ -5,8 +5,10 @@
|
||||||
* FIXME: This does not work if we have more than 24 IRQs (ie. more than one
|
* FIXME: This does not work if we have more than 24 IRQs (ie. more than one
|
||||||
* I/O APIC)
|
* I/O APIC)
|
||||||
*/
|
*/
|
||||||
#define IRQL2VECTOR(irql) IRQ2VECTOR(PROFILE_LEVEL - (irql))
|
#define VECTOR2IRQ(vector) (((vector) - FIRST_DEVICE_VECTOR) / 8)
|
||||||
#define IRQL2TPR(irql) (((irql) == PASSIVE_LEVEL) ? 0 : ((irql) >= CLOCK1_LEVEL ? 0xff : IRQL2VECTOR(irql)))
|
#define IRQ2VECTOR(vector) ((vector * 8) + FIRST_DEVICE_VECTOR)
|
||||||
|
#define VECTOR2IRQL(vector) (DISPATCH_LEVEL /* 2 */ + 1 + VECTOR2IRQ(vector))
|
||||||
|
#define IRQL2VECTOR(irql) (IRQ2VECTOR(irql - DISPATCH_LEVEL /* 2 */ - 1))
|
||||||
|
|
||||||
|
|
||||||
#define APIC_DEFAULT_BASE 0xFEE00000 /* Default Local APIC Base Register Address */
|
#define APIC_DEFAULT_BASE 0xFEE00000 /* Default Local APIC Base Register Address */
|
||||||
|
@ -39,7 +41,6 @@
|
||||||
|
|
||||||
#define APIC_ID_MASK (0xF << 24)
|
#define APIC_ID_MASK (0xF << 24)
|
||||||
#define GET_APIC_ID(x) (((x) & APIC_ID_MASK) >> 24)
|
#define GET_APIC_ID(x) (((x) & APIC_ID_MASK) >> 24)
|
||||||
#define GET_APIC_LOGICAL_ID(x) (((x)>>24)&0xFF)
|
|
||||||
#define APIC_VER_MASK 0xFF00FF
|
#define APIC_VER_MASK 0xFF00FF
|
||||||
#define GET_APIC_VERSION(x)((x) & 0xFF)
|
#define GET_APIC_VERSION(x)((x) & 0xFF)
|
||||||
#define GET_APIC_MAXLVT(x) (((x) >> 16) & 0xFF)
|
#define GET_APIC_MAXLVT(x) (((x) >> 16) & 0xFF)
|
||||||
|
@ -214,12 +215,13 @@ typedef struct _IOAPIC_INFO
|
||||||
#define ERROR_VECTOR 0xFE
|
#define ERROR_VECTOR 0xFE
|
||||||
#define SPURIOUS_VECTOR 0xFF /* Must be 0xXF */
|
#define SPURIOUS_VECTOR 0xFF /* Must be 0xXF */
|
||||||
|
|
||||||
#if 0
|
/*
|
||||||
/* This values are defined in halirql.h */
|
* First APIC vector available to drivers: (vectors 0x30-0xEE)
|
||||||
#define FIRST_DEVICE_VECTOR 0x30
|
* we start at 0x31 to spread out vectors evenly between priority
|
||||||
|
* levels.
|
||||||
|
*/
|
||||||
|
#define FIRST_DEVICE_VECTOR 0x31
|
||||||
#define FIRST_SYSTEM_VECTOR 0xEF
|
#define FIRST_SYSTEM_VECTOR 0xEF
|
||||||
#endif
|
|
||||||
|
|
||||||
#define NUMBER_DEVICE_VECTORS (FIRST_SYSTEM_VECTOR - FIRST_DEVICE_VECTOR)
|
#define NUMBER_DEVICE_VECTORS (FIRST_SYSTEM_VECTOR - FIRST_DEVICE_VECTOR)
|
||||||
|
|
||||||
|
|
||||||
|
@ -428,8 +430,8 @@ typedef enum {
|
||||||
VOID HalpInitMPS(VOID);
|
VOID HalpInitMPS(VOID);
|
||||||
volatile ULONG IOAPICRead(ULONG Apic, ULONG Offset);
|
volatile ULONG IOAPICRead(ULONG Apic, ULONG Offset);
|
||||||
VOID IOAPICWrite(ULONG Apic, ULONG Offset, ULONG Value);
|
VOID IOAPICWrite(ULONG Apic, ULONG Offset, ULONG Value);
|
||||||
VOID IOAPICMaskIrq(ULONG Irq);
|
VOID IOAPICMaskIrq(ULONG Apic, ULONG Irq);
|
||||||
VOID IOAPICUnmaskIrq(ULONG Irq);
|
VOID IOAPICUnmaskIrq(ULONG Apic, ULONG Irq);
|
||||||
volatile inline ULONG APICRead(ULONG Offset);
|
volatile inline ULONG APICRead(ULONG Offset);
|
||||||
inline VOID APICWrite(ULONG Offset, ULONG Value);
|
inline VOID APICWrite(ULONG Offset, ULONG Value);
|
||||||
inline VOID APICSendEOI(VOID);
|
inline VOID APICSendEOI(VOID);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: irql.c,v 1.21 2004/11/14 19:04:42 hbirr Exp $
|
/* $Id: irql.c,v 1.22 2004/11/21 21:53:06 ion Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -21,6 +21,10 @@
|
||||||
|
|
||||||
/* GLOBALS ******************************************************************/
|
/* GLOBALS ******************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: Use EISA_CONTROL STRUCTURE INSTEAD OF HARD-CODED OFFSETS
|
||||||
|
*/
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
{
|
{
|
||||||
USHORT both;
|
USHORT both;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: iomgr.c,v 1.53 2004/11/06 04:12:59 ion Exp $
|
/* $Id: iomgr.c,v 1.54 2004/11/21 21:53:07 ion Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#define TAG_DEVICE_TYPE TAG('D', 'E', 'V', 'T')
|
#define TAG_DEVICE_TYPE TAG('D', 'E', 'V', 'T')
|
||||||
#define TAG_FILE_TYPE TAG('F', 'I', 'L', 'E')
|
#define TAG_FILE_TYPE TAG('F', 'I', 'L', 'E')
|
||||||
|
#define TAG_ADAPTER_TYPE TAG('A', 'D', 'P', 'T')
|
||||||
|
|
||||||
/* DATA ********************************************************************/
|
/* DATA ********************************************************************/
|
||||||
|
|
||||||
|
@ -443,6 +444,19 @@ IoInit (VOID)
|
||||||
|
|
||||||
ObpCreateTypeObject(IoFileObjectType);
|
ObpCreateTypeObject(IoFileObjectType);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Register iomgr types: AdapterObjectType
|
||||||
|
*/
|
||||||
|
IoAdapterObjectType = ExAllocatePool (NonPagedPool,
|
||||||
|
sizeof (OBJECT_TYPE));
|
||||||
|
RtlZeroMemory(IoAdapterObjectType, sizeof(OBJECT_TYPE));
|
||||||
|
IoAdapterObjectType->Tag = TAG_ADAPTER_TYPE;
|
||||||
|
IoAdapterObjectType->MaxObjects = ULONG_MAX;
|
||||||
|
IoAdapterObjectType->MaxHandles = ULONG_MAX;
|
||||||
|
IoDeviceObjectType->Mapping = &IopFileMapping;
|
||||||
|
RtlRosInitUnicodeStringFromLiteral(&IoAdapterObjectType->TypeName, L"Adapter");
|
||||||
|
ObpCreateTypeObject(IoAdapterObjectType);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create the '\Driver' object directory
|
* Create the '\Driver' object directory
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: object.c,v 1.84 2004/10/22 20:43:58 ekohl Exp $
|
/* $Id: object.c,v 1.85 2004/11/21 21:53:07 ion Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -364,7 +364,7 @@ ObCreateObject (IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("ObFindObject() failed! (Status 0x%x)\n", Status);
|
DPRINT1("ObFindObject() failed! (Status 0x%x)\n", Status);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -376,11 +376,15 @@ ObCreateObject (IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
|
||||||
Header = (POBJECT_HEADER)ExAllocatePoolWithTag(NonPagedPool,
|
Header = (POBJECT_HEADER)ExAllocatePoolWithTag(NonPagedPool,
|
||||||
OBJECT_ALLOC_SIZE(ObjectSize),
|
OBJECT_ALLOC_SIZE(ObjectSize),
|
||||||
Type->Tag);
|
Type->Tag);
|
||||||
if (Header == NULL)
|
if (Header == NULL) {
|
||||||
|
DPRINT1("Not enough memory!\n");
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
RtlZeroMemory(Header, OBJECT_ALLOC_SIZE(ObjectSize));
|
RtlZeroMemory(Header, OBJECT_ALLOC_SIZE(ObjectSize));
|
||||||
|
|
||||||
/* Initialize the object header */
|
/* Initialize the object header */
|
||||||
|
DPRINT("Initalizing header\n");
|
||||||
Header->HandleCount = 0;
|
Header->HandleCount = 0;
|
||||||
Header->RefCount = 1;
|
Header->RefCount = 1;
|
||||||
Header->ObjectType = Type;
|
Header->ObjectType = Type;
|
||||||
|
@ -406,6 +410,7 @@ ObCreateObject (IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
|
||||||
|
|
||||||
RtlInitUnicodeString(&(Header->Name),NULL);
|
RtlInitUnicodeString(&(Header->Name),NULL);
|
||||||
|
|
||||||
|
DPRINT("Getting Parent and adding entry\n");
|
||||||
if (Parent != NULL)
|
if (Parent != NULL)
|
||||||
{
|
{
|
||||||
ParentHeader = BODY_TO_HEADER(Parent);
|
ParentHeader = BODY_TO_HEADER(Parent);
|
||||||
|
@ -426,6 +431,7 @@ ObCreateObject (IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
|
||||||
ObjectAttached = TRUE;
|
ObjectAttached = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPRINT("About to call Create Routine\n");
|
||||||
if (Header->ObjectType->Create != NULL)
|
if (Header->ObjectType->Create != NULL)
|
||||||
{
|
{
|
||||||
DPRINT("Calling %x\n", Header->ObjectType->Create);
|
DPRINT("Calling %x\n", Header->ObjectType->Create);
|
||||||
|
@ -446,6 +452,7 @@ ObCreateObject (IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
|
||||||
RtlFreeUnicodeString(&Header->Name);
|
RtlFreeUnicodeString(&Header->Name);
|
||||||
RtlFreeUnicodeString(&RemainingPath);
|
RtlFreeUnicodeString(&RemainingPath);
|
||||||
ExFreePool(Header);
|
ExFreePool(Header);
|
||||||
|
DPRINT("Create Failed\n");
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -453,6 +460,7 @@ ObCreateObject (IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
|
||||||
|
|
||||||
SeCaptureSubjectContext(&SubjectContext);
|
SeCaptureSubjectContext(&SubjectContext);
|
||||||
|
|
||||||
|
DPRINT("Security Assignment in progress\n");
|
||||||
/* Build the new security descriptor */
|
/* Build the new security descriptor */
|
||||||
Status = SeAssignSecurity((ParentHeader != NULL) ? ParentHeader->SecurityDescriptor : NULL,
|
Status = SeAssignSecurity((ParentHeader != NULL) ? ParentHeader->SecurityDescriptor : NULL,
|
||||||
(ObjectAttributes != NULL) ? ObjectAttributes->SecurityDescriptor : NULL,
|
(ObjectAttributes != NULL) ? ObjectAttributes->SecurityDescriptor : NULL,
|
||||||
|
@ -486,6 +494,7 @@ ObCreateObject (IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
|
||||||
SeDeassignSecurity(&NewSecurityDescriptor);
|
SeDeassignSecurity(&NewSecurityDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPRINT("Security Complete\n");
|
||||||
SeReleaseSubjectContext(&SubjectContext);
|
SeReleaseSubjectContext(&SubjectContext);
|
||||||
|
|
||||||
if (Object != NULL)
|
if (Object != NULL)
|
||||||
|
@ -493,6 +502,7 @@ ObCreateObject (IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
|
||||||
*Object = HEADER_TO_BODY(Header);
|
*Object = HEADER_TO_BODY(Header);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPRINT("Sucess!\n");
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue