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:
Alex Ionescu 2004-11-21 21:53:07 +00:00
parent ac33643ce2
commit 1fe3441f75
8 changed files with 967 additions and 208 deletions

View file

@ -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
* PROJECT: ReactOS kernel
@ -139,12 +139,11 @@ HalAssignSlotResources(
}
BOOLEAN
BOOLEAN
STDCALL
HalBeginSystemInterrupt(
ULONG Vector,
KIRQL Irql,
PKIRQL OldIrql)
HalBeginSystemInterrupt (ULONG Vector,
KIRQL Irql,
PKIRQL OldIrql)
{
UNIMPLEMENTED;

View file

@ -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
* PROJECT: ReactOS kernel
@ -15,6 +15,7 @@
#include <ddk/ntddk.h>
#include <ddk/iotypes.h>
#define NDEBUG
#include <internal/debug.h>
#include <hal.h>
@ -66,7 +67,7 @@ HalAllocateAdapterChannel(
WaitContextBlock->NumberOfMapRegisters = NumberOfMapRegisters;
/* 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;
/* 24-bit max address due to 16-bit dma controllers */
@ -95,7 +96,7 @@ HalAllocateAdapterChannel(
if(!AdapterObject->MapRegisterBase)
return STATUS_INSUFFICIENT_RESOURCES;
AdapterObject->AllocatedMapRegisters = NumberOfMapRegisters;
AdapterObject->CommittedMapRegisters = NumberOfMapRegisters;
/* call the client's AdapterControl callback with its map registers and context */
Retval = ExecutionRoutine(WaitContextBlock->DeviceObject, WaitContextBlock->CurrentIrp,
@ -119,7 +120,7 @@ HalAllocateAdapterChannel(
else if(Retval == DeallocateObjectKeepRegisters)
{
/* don't free the allocated map registers - this is what IoFreeAdapterChannel checks */
AdapterObject->AllocatedMapRegisters = 0;
AdapterObject->CommittedMapRegisters = 0;
IoFreeAdapterChannel(AdapterObject);
}
@ -131,6 +132,171 @@ HalAllocateAdapterChannel(
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
IoFlushAdapterBuffers (
@ -164,11 +330,21 @@ IoFlushAdapterBuffers (
return TRUE;
/* mask out (disable) the dma channel */
if (AdapterObject->Channel < 4)
WRITE_PORT_UCHAR( (PVOID)0x0A, (UCHAR)(AdapterObject->Channel | 0x4) );
else
WRITE_PORT_UCHAR( (PVOID)0xD4, (UCHAR)((AdapterObject->Channel - 4) | 0x4) );
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;
@ -202,10 +378,10 @@ IoFreeAdapterChannel (PADAPTER_OBJECT AdapterObject)
while(1)
{
/* To keep map registers, call here with the following set to 0 */
if(AdapterObject->AllocatedMapRegisters)
IoFreeMapRegisters(AdapterObject, AdapterObject->MapRegisterBase, AdapterObject->AllocatedMapRegisters);
if(AdapterObject->CommittedMapRegisters)
IoFreeMapRegisters(AdapterObject, AdapterObject->MapRegisterBase, AdapterObject->CommittedMapRegisters);
if(!(WaitContextBlock = (PWAIT_CONTEXT_BLOCK)KeRemoveDeviceQueue(&AdapterObject->DeviceQueue)))
if(!(WaitContextBlock = (PWAIT_CONTEXT_BLOCK)KeRemoveDeviceQueue(&AdapterObject->ChannelWaitQueue)))
break;
/*
@ -241,7 +417,7 @@ IoFreeAdapterChannel (PADAPTER_OBJECT AdapterObject)
else if(Retval == DeallocateObjectKeepRegisters)
{
/* 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
*/
{
if( AdapterObject->AllocatedMapRegisters )
if( AdapterObject->CommittedMapRegisters )
{
MmFreeContiguousMemory(AdapterObject->MapRegisterBase);
AdapterObject->MapRegisterBase = 0;
@ -302,9 +478,8 @@ IoMapTransfer (
*/
{
PHYSICAL_ADDRESS Address;
PVOID MaskReg, ClearReg, ModeReg;
UCHAR ModeMask, LengthShift;
KIRQL OldIrql;
UCHAR Mode;
#if defined(__GNUC__)
Address.QuadPart = 0ULL;
@ -313,14 +488,8 @@ IoMapTransfer (
#endif
/* 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);
@ -341,56 +510,77 @@ IoMapTransfer (
* -- 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( WriteToDevice && !AdapterObject->AutoInitialize )
if ((WriteToDevice) && !((PDMA_MODE)&Mode)->AutoInitialize)
{
memcpy(MapRegisterBase,
(char*)MmGetSystemAddressForMdl(Mdl) + ((ULONG)CurrentVa - (ULONG)MmGetMdlVirtualAddress(Mdl)),
*Length );
}
// 16-bit DMA
if( AdapterObject->Channel >= 4 )
{
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;
/* Writer Adapter Mode, transfer type */
((PDMA_MODE)&Mode)->TransferType = (WriteToDevice ? WRITE_TRANSFER : READ_TRANSFER);
// program up the dma controller, and return
if (!AdapterObject->AutoInitialize)
if (!((PDMA_MODE)&Mode)->AutoInitialize) {
Address = MmGetPhysicalAddress( MapRegisterBase );
else
} else {
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);
/*
@ -409,7 +599,7 @@ IoMapTransfer (
being NULL is used to detect a s/g busmaster.
*/
if ((!AdapterObject && !MapRegisterBase) ||
(AdapterObject && AdapterObject->Master && AdapterObject->ScatterGather))
(AdapterObject && AdapterObject->MasterDevice && AdapterObject->ScatterGather))
{
/*
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.
*/
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
@ -476,7 +666,7 @@ IoMapTransfer (
return MmGetPhysicalAddress(MapRegisterBase);
}
DPRINT1("IoMapTransfer: Unsupported operation\n");
DPRINT("IoMapTransfer: Unsupported operation\n");
KEBUGCHECK(0);
return Address;
}

View file

@ -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
* PROJECT: ReactOS kernel
@ -12,42 +12,19 @@
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#define NDEBUG
#include <internal/debug.h>
#include <hal.h>
/* XXX This initialization is out of date - ADAPTER_OBJECT has changed */
/* NOTE: The following initializations have to be kept in synch with ADAPTER_OBJECT in hal.h */
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 } };
/* Adapters for each channel */
PADAPTER_OBJECT HalpEisaAdapter[8];
/* FUNCTIONS *****************************************************************/
VOID
HalpInitDma (VOID)
{
ULONG Index;
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;
}
/* TODO: Initialize the first Map Buffer */
}
PVOID STDCALL
@ -79,15 +56,11 @@ HalAllocateCommonBuffer (PADAPTER_OBJECT AdapterObject,
LowestAddress.QuadPart = 0;
BoundryAddressMultiple.QuadPart = 0;
HighestAddress.u.HighPart = 0;
if (AdapterObject->InterfaceType == Isa ||
(AdapterObject->InterfaceType == MicroChannel && AdapterObject->Master == FALSE))
{
HighestAddress.u.LowPart = 0x00FFFFFF; /* 24Bit: 16MB address range */
}
else
{
if ((AdapterObject->Dma32BitAddresses) && (AdapterObject->MasterDevice)) {
HighestAddress.u.LowPart = 0xFFFFFFFF; /* 32Bit: 4GB address range */
}
} else {
HighestAddress.u.LowPart = 0x00FFFFFF; /* 24Bit: 16MB address range */
}
BaseAddress = MmAllocateContiguousAlignedMemory(
Length,
@ -141,49 +114,284 @@ HalGetAdapter (PDEVICE_DESCRIPTION DeviceDescription,
* RETURNS: The allocated adapter object on success
* NULL on failure
* TODO:
* Honour all the fields in DeviceDescription structure.
* Testing
*/
{
PADAPTER_OBJECT AdapterObject;
PADAPTER_OBJECT AdapterObject;
DWORD ChannelSelect;
DWORD Controller;
ULONG MaximumLength;
BOOLEAN ChannelSetup;
/* Validate parameters in device description, and return a pointer to
the adapter object for the requested dma channel */
if( DeviceDescription->Version != DEVICE_DESCRIPTION_VERSION )
return NULL;
DPRINT("Entered Function\n");
/* Validate parameters in device description, and return a pointer to
the adapter object for the requested dma channel */
if(DeviceDescription->Version != DEVICE_DESCRIPTION_VERSION) {
DPRINT("Invalid Adapter version!\n");
return NULL;
}
switch (DeviceDescription->InterfaceType)
{
case PCIBus:
if (DeviceDescription->Master == FALSE)
return NULL;
return &PciBusMasterAdapterObjects[0];
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);
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;
}
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
@ -192,29 +400,46 @@ HalReadDmaCounter (PADAPTER_OBJECT AdapterObject)
KIRQL OldIrql;
ULONG Count;
if (AdapterObject && AdapterObject->InterfaceType == Isa && !AdapterObject->Master)
{
KeAcquireSpinLock(&AdapterObject->SpinLock, &OldIrql);
KeAcquireSpinLock(&AdapterObject->MasterAdapter->SpinLock, &OldIrql);
/* Send the Request to the specific controller */
if (AdapterObject->AdapterNumber == 1) {
/* Set this for Ease */
PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
/* Send Reset */
WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
/* Read Count */
Count = READ_PORT_UCHAR(&DmaControl1->DmaAddressCount
[AdapterObject->ChannelNumber].DmaBaseCount);
Count |= READ_PORT_UCHAR(&DmaControl1->DmaAddressCount
[AdapterObject->ChannelNumber].DmaBaseCount) << 8;
} else {
/* Clear the flip/flop register */
WRITE_PORT_UCHAR( AdapterObject->Channel < 4 ? (PVOID)0x0C : (PVOID)0xD8, 0 );
/* Read the offset */
Count = READ_PORT_UCHAR( AdapterObject->CountPort );
Count |= READ_PORT_UCHAR( AdapterObject->CountPort ) << 8;
KeReleaseSpinLock(&AdapterObject->SpinLock, OldIrql);
/*
* We must return twice the sound for channel >= 4 because it's the size
* of words (16-bit) and not bytes.
*/
if (AdapterObject->Channel < 4)
return Count;
else
return Count << 1;
}
return 0;
/* 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;
}
/* 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 */

View file

@ -12,6 +12,9 @@
VOID FASTCALL HalInitializeDisplay (PLOADER_PARAMETER_BLOCK LoaderBlock);
VOID FASTCALL HalClearDisplay (UCHAR CharAttribute);
/* adapter.c */
PADAPTER_OBJECT STDCALL HalpAllocateAdapterEx(ULONG NumberOfMapRegisters,BOOLEAN IsMaster, BOOLEAN Dma32BitAddresses);
/* bus.c */
VOID HalpInitBusHandlers (VOID);
@ -30,16 +33,334 @@ VOID HalpStartEnumerator (VOID);
/* dma.c */
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
*
* NOTES:
* - I have not found any documentation on this; if you have any, please
* 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
* - 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;
UCHAR AdapterMode;
BOOLEAN NeedsMapRegisters;
BOOLEAN MasterDevice;
UCHAR Width16Bits;
UCHAR ScatterGather;
UCHAR IgnoreCount;
UCHAR Dma32BitAddresses;
UCHAR Dma64BitAddresses;
BOOLEAN LegacyAdapter;
LIST_ENTRY AdapterList;
};
/*
struct _ADAPTER_OBJECT {
INTERFACE_TYPE InterfaceType;
BOOLEAN Master;
@ -56,16 +377,10 @@ struct _ADAPTER_OBJECT {
PWAIT_CONTEXT_BLOCK WaitContextBlock;
KDEVICE_QUEUE DeviceQueue;
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 AutoInitialize;
};
*/
/* sysinfo.c */
NTSTATUS STDCALL

View file

@ -5,8 +5,10 @@
* FIXME: This does not work if we have more than 24 IRQs (ie. more than one
* I/O APIC)
*/
#define IRQL2VECTOR(irql) IRQ2VECTOR(PROFILE_LEVEL - (irql))
#define IRQL2TPR(irql) (((irql) == PASSIVE_LEVEL) ? 0 : ((irql) >= CLOCK1_LEVEL ? 0xff : IRQL2VECTOR(irql)))
#define VECTOR2IRQ(vector) (((vector) - FIRST_DEVICE_VECTOR) / 8)
#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 */
@ -37,12 +39,11 @@
#define APIC_CCRT 0x0390 /* Current Count Register for Timer (R) */
#define APIC_TDCR 0x03E0 /* Timer Divide Configuration Register (R/W) */
#define APIC_ID_MASK (0xF << 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 GET_APIC_VERSION(x) ((x) & 0xFF)
#define GET_APIC_MAXLVT(x) (((x) >> 16) & 0xFF)
#define APIC_ID_MASK (0xF << 24)
#define GET_APIC_ID(x) (((x) & APIC_ID_MASK) >> 24)
#define APIC_VER_MASK 0xFF00FF
#define GET_APIC_VERSION(x)((x) & 0xFF)
#define GET_APIC_MAXLVT(x) (((x) >> 16) & 0xFF)
#define APIC_TPR_PRI 0xFF
#define APIC_TPR_INT 0xF0
@ -206,21 +207,22 @@ typedef struct _IOAPIC_INFO
* to work around the 'lost local interrupt if more than 2 IRQ
* sources per level' errata.
*/
#define LOCAL_TIMER_VECTOR 0xEF
#define LOCAL_TIMER_VECTOR 0xEF
#define CALL_FUNCTION_VECTOR 0xFB
#define RESCHEDULE_VECTOR 0xFC
#define INVALIDATE_TLB_VECTOR 0xFD
#define ERROR_VECTOR 0xFE
#define SPURIOUS_VECTOR 0xFF /* Must be 0xXF */
#define CALL_FUNCTION_VECTOR 0xFB
#define RESCHEDULE_VECTOR 0xFC
#define INVALIDATE_TLB_VECTOR 0xFD
#define ERROR_VECTOR 0xFE
#define SPURIOUS_VECTOR 0xFF /* Must be 0xXF */
#if 0
/* This values are defined in halirql.h */
#define FIRST_DEVICE_VECTOR 0x30
#define FIRST_SYSTEM_VECTOR 0xEF
#endif
#define NUMBER_DEVICE_VECTORS (FIRST_SYSTEM_VECTOR - FIRST_DEVICE_VECTOR)
/*
* First APIC vector available to drivers: (vectors 0x30-0xEE)
* we start at 0x31 to spread out vectors evenly between priority
* levels.
*/
#define FIRST_DEVICE_VECTOR 0x31
#define FIRST_SYSTEM_VECTOR 0xEF
#define NUMBER_DEVICE_VECTORS (FIRST_SYSTEM_VECTOR - FIRST_DEVICE_VECTOR)
/* MP Floating Pointer Structure */
@ -428,8 +430,8 @@ typedef enum {
VOID HalpInitMPS(VOID);
volatile ULONG IOAPICRead(ULONG Apic, ULONG Offset);
VOID IOAPICWrite(ULONG Apic, ULONG Offset, ULONG Value);
VOID IOAPICMaskIrq(ULONG Irq);
VOID IOAPICUnmaskIrq(ULONG Irq);
VOID IOAPICMaskIrq(ULONG Apic, ULONG Irq);
VOID IOAPICUnmaskIrq(ULONG Apic, ULONG Irq);
volatile inline ULONG APICRead(ULONG Offset);
inline VOID APICWrite(ULONG Offset, ULONG Value);
inline VOID APICSendEOI(VOID);

View file

@ -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
* PROJECT: ReactOS kernel
@ -21,6 +21,10 @@
/* GLOBALS ******************************************************************/
/*
* FIXME: Use EISA_CONTROL STRUCTURE INSTEAD OF HARD-CODED OFFSETS
*/
typedef union
{
USHORT both;

View file

@ -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
* PROJECT: ReactOS kernel
@ -19,6 +19,7 @@
#define TAG_DEVICE_TYPE TAG('D', 'E', 'V', 'T')
#define TAG_FILE_TYPE TAG('F', 'I', 'L', 'E')
#define TAG_ADAPTER_TYPE TAG('A', 'D', 'P', 'T')
/* DATA ********************************************************************/
@ -442,6 +443,19 @@ IoInit (VOID)
RtlRosInitUnicodeStringFromLiteral(&IoFileObjectType->TypeName, L"File");
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

View file

@ -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
* PROJECT: ReactOS kernel
@ -364,7 +364,7 @@ ObCreateObject (IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT("ObFindObject() failed! (Status 0x%x)\n", Status);
DPRINT1("ObFindObject() failed! (Status 0x%x)\n", Status);
return Status;
}
}
@ -376,11 +376,15 @@ ObCreateObject (IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
Header = (POBJECT_HEADER)ExAllocatePoolWithTag(NonPagedPool,
OBJECT_ALLOC_SIZE(ObjectSize),
Type->Tag);
if (Header == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
if (Header == NULL) {
DPRINT1("Not enough memory!\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(Header, OBJECT_ALLOC_SIZE(ObjectSize));
/* Initialize the object header */
DPRINT("Initalizing header\n");
Header->HandleCount = 0;
Header->RefCount = 1;
Header->ObjectType = Type;
@ -406,6 +410,7 @@ ObCreateObject (IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
RtlInitUnicodeString(&(Header->Name),NULL);
DPRINT("Getting Parent and adding entry\n");
if (Parent != NULL)
{
ParentHeader = BODY_TO_HEADER(Parent);
@ -426,6 +431,7 @@ ObCreateObject (IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
ObjectAttached = TRUE;
}
DPRINT("About to call Create Routine\n");
if (Header->ObjectType->Create != NULL)
{
DPRINT("Calling %x\n", Header->ObjectType->Create);
@ -446,6 +452,7 @@ ObCreateObject (IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
RtlFreeUnicodeString(&Header->Name);
RtlFreeUnicodeString(&RemainingPath);
ExFreePool(Header);
DPRINT("Create Failed\n");
return Status;
}
}
@ -453,6 +460,7 @@ ObCreateObject (IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
SeCaptureSubjectContext(&SubjectContext);
DPRINT("Security Assignment in progress\n");
/* Build the new security descriptor */
Status = SeAssignSecurity((ParentHeader != NULL) ? ParentHeader->SecurityDescriptor : NULL,
(ObjectAttributes != NULL) ? ObjectAttributes->SecurityDescriptor : NULL,
@ -486,6 +494,7 @@ ObCreateObject (IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
SeDeassignSecurity(&NewSecurityDescriptor);
}
DPRINT("Security Complete\n");
SeReleaseSubjectContext(&SubjectContext);
if (Object != NULL)
@ -493,6 +502,7 @@ ObCreateObject (IN KPROCESSOR_MODE ObjectAttributesAccessMode OPTIONAL,
*Object = HEADER_TO_BODY(Header);
}
DPRINT("Sucess!\n");
return STATUS_SUCCESS;
}