diff options
Diffstat (limited to 'private/ntos/nthals/halraw/alpha/iousage.c')
-rw-r--r-- | private/ntos/nthals/halraw/alpha/iousage.c | 647 |
1 files changed, 647 insertions, 0 deletions
diff --git a/private/ntos/nthals/halraw/alpha/iousage.c b/private/ntos/nthals/halraw/alpha/iousage.c new file mode 100644 index 000000000..6ac8f6f4e --- /dev/null +++ b/private/ntos/nthals/halraw/alpha/iousage.c @@ -0,0 +1,647 @@ +/*++ + +Copyright (c) 1991 Microsoft Corporation + +Module Name: + + iousage.c + +Abstract: + +Author: + + Ken Reneris (kenr) + +Environment: + + Kernel mode only. + +Revision History: + + Chao Chen 1-25-1995 + +--*/ + +#include "halp.h" +#include "iousage.h" + +// +// Externals. +// + +extern KAFFINITY HalpActiveProcessors; + +// +// Private resource list. +// + +static PBUS_USAGE HalpBusUsageList = NULL; +static PRESOURCE_USAGE HalpResourceUsageList = NULL; + +// +// Default HAL name. +// + +#define MAX_NAME_LENGTH 256 +UCHAR HalRegisteredName[MAX_NAME_LENGTH] = "Alpha Compatible PCI/EISA/ISA HAL"; + +// +// Function prototype. +// + +VOID +HalpReportResourceUsage ( + IN PUNICODE_STRING HalName + ); + +VOID +HalpGetResourceSortValue ( + IN PCM_PARTIAL_RESOURCE_DESCRIPTOR pRCurLoc, + OUT PULONG sortscale, + OUT PLARGE_INTEGER sortvalue + ); + +// +// Pragma stuff. +// + +#ifdef ALLOC_PRAGMA +#pragma alloc_text(INIT,HalpRegisterHalName) +#pragma alloc_text(INIT,HalpRegisterBusUsage) +#pragma alloc_text(INIT,HalpRegisterResourceUsage) +#pragma alloc_text(INIT,HalReportResourceUsage) +#pragma alloc_text(INIT,HalpReportResourceUsage) +#pragma alloc_text(INIT,HalpGetResourceSortValue) +#endif + +// +// Function definitions. +// + + +VOID +HalpRegisterHalName( + IN PUCHAR NewHalName + ) +/*++ + +Routine Description: + + Allow the HAL to register a name string. + +Arguments: + + HalName - Supplies a pointer to the HAL name to register. + +Return Value: + + None. + +--*/ +{ + + strncpy( HalRegisteredName, NewHalName, MAX_NAME_LENGTH ); + return; +} + + + +VOID +HalpRegisterBusUsage ( + IN INTERFACE_TYPE BusType + ) +/*++ + +Routine Description: + + Register the different bus types in the system. + +Arguments: + + BusType - bus type that requires registering. + +Return Value: + + None. + +--*/ +{ + PBUS_USAGE Temp; + + // + // Allocate the buffer to store the bus information. + // + + Temp = (PBUS_USAGE)ExAllocatePool(NonPagedPool, sizeof(BUS_USAGE)); + + // + // Save the bus type. + // + + Temp->BusType = BusType; + + // + // Add the bus type to the head of the list. + // + + Temp->Next = HalpBusUsageList; + HalpBusUsageList = Temp; +} + + + +VOID +HalpRegisterResourceUsage ( + IN PRESOURCE_USAGE Resource + ) +/*++ + +Routine Description: + + Register the resources used internally by the HAL to the I/O system. + +Arguments: + + Resource - resource that requires registering. + +Return Value: + + None. + +--*/ +{ + PRESOURCE_USAGE Temp; + + // + // Allocate the buffer to store the resource information. + // + + Temp = (PRESOURCE_USAGE)ExAllocatePool(NonPagedPool, sizeof(RESOURCE_USAGE)); + + // + // Copy the resource to the buffer we allocated. + // + + RtlCopyMemory(Temp, Resource, sizeof(RESOURCE_USAGE)); + + // + // Add the resource to the head of the resource list. + // + + Temp->Next = HalpResourceUsageList; + HalpResourceUsageList = Temp; +} + + + +VOID +HalReportResourceUsage ( + VOID + ) +/*++ + +Routine Description: + + Report the resources used internally by the HAL to the I/O system. + +Arguments: + + None. + +Return Value: + + None. + +--*/ +{ + ANSI_STRING AHalName; + UNICODE_STRING UHalName; + + // + // Convert the string. + // + + RtlInitAnsiString (&AHalName, HalRegisteredName); + RtlAnsiStringToUnicodeString (&UHalName, &AHalName, TRUE); + + // + // Report the resources registered as in use by the HAL. + // + + HalpReportResourceUsage(&UHalName); + + RtlFreeUnicodeString(&UHalName); +} + + + +VOID +HalpGetResourceSortValue ( + IN PCM_PARTIAL_RESOURCE_DESCRIPTOR pRCurLoc, + OUT PULONG sortscale, + OUT PLARGE_INTEGER sortvalue + ) +/*++ + +Routine Description: + + Used by HalpReportResourceUsage in order to properly sort + partial_resource_descriptors. + +Arguments: + + pRCurLoc - resource descriptor + +Return Value: + + sortscale - scaling of resource descriptor for sorting + sortvalue - value to sort on + + +--*/ +{ + + switch (pRCurLoc->Type) { + case CmResourceTypeInterrupt: + *sortscale = 0; + sortvalue->QuadPart = pRCurLoc->u.Interrupt.Level; + break; + + case CmResourceTypePort: + *sortscale = 1; + *sortvalue = pRCurLoc->u.Port.Start; + break; + + case CmResourceTypeMemory: + *sortscale = 2; + *sortvalue = pRCurLoc->u.Memory.Start; + break; + + case CmResourceTypeDma: + *sortscale = 3; + sortvalue->QuadPart = pRCurLoc->u.Dma.Channel; + break; + + default: + *sortscale = 4; + sortvalue->QuadPart = 0; + break; + } +} + + + +VOID +HalpReportResourceUsage ( + IN PUNICODE_STRING HalName + ) +/*++ + +Routine Description: + + This routine registers the resources for the hal. + +Arguments: + + HalName - the name of the hal to be registered. + +Return Value: + + None. + +--*/ +{ + PCM_RESOURCE_LIST RawResourceList, TranslatedResourceList; + PCM_FULL_RESOURCE_DESCRIPTOR pRFullDesc, pTFullDesc; + PCM_PARTIAL_RESOURCE_LIST pRPartList, pTPartList; + PCM_PARTIAL_RESOURCE_DESCRIPTOR pRCurLoc, pTCurLoc; + PCM_PARTIAL_RESOURCE_DESCRIPTOR pRSortLoc, pTSortLoc; + CM_PARTIAL_RESOURCE_DESCRIPTOR RPartialDesc, TPartialDesc; + ULONG i, j, k, ListSize, Count; + ULONG curscale, sortscale; + LARGE_INTEGER curvalue, sortvalue; + PHYSICAL_ADDRESS PhyAddress; + PBUS_USAGE CurrentBus; + PRESOURCE_USAGE CurrentResource; + + // + // Allocate some space to build the resource structure. + // + + RawResourceList= + (PCM_RESOURCE_LIST)ExAllocatePool(NonPagedPool, PAGE_SIZE*2); + TranslatedResourceList= + (PCM_RESOURCE_LIST)ExAllocatePool(NonPagedPool, PAGE_SIZE*2); + + // + // This functions assumes unset fields are zero. + // + + RtlZeroMemory (RawResourceList, PAGE_SIZE*2); + RtlZeroMemory (TranslatedResourceList, PAGE_SIZE*2); + + // + // Initialize the lists + // + + RawResourceList->List[0].InterfaceType = (INTERFACE_TYPE) -1; + pRFullDesc = RawResourceList->List; + pRCurLoc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) RawResourceList->List; + pTCurLoc = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) TranslatedResourceList->List; + + // + // Report all the HAL resources. + // + + CurrentBus = HalpBusUsageList; + + while (CurrentBus) { + + // + // Start at the head of the resource list for each bus type. + // + + CurrentResource = HalpResourceUsageList; + + while (CurrentResource) { + + // + // Register the resources for a particular bus. + // + + if (CurrentBus->BusType == CurrentResource->BusType) { + + switch (CurrentResource->ResourceType) { + + case CmResourceTypeInterrupt: + + // + // Process interrupt resources. + // + + RPartialDesc.Type = CmResourceTypeInterrupt; + RPartialDesc.ShareDisposition = CmResourceShareDriverExclusive; + + if (CurrentResource->u.InterruptMode == Latched) + RPartialDesc.Flags = CM_RESOURCE_INTERRUPT_LATCHED; + else + RPartialDesc.Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE; + + RPartialDesc.u.Interrupt.Vector = + CurrentResource->u.BusInterruptVector; + RPartialDesc.u.Interrupt.Level = + CurrentResource->u.BusInterruptVector; + RPartialDesc.u.Interrupt.Affinity = HalpActiveProcessors; + + RtlCopyMemory(&TPartialDesc, &RPartialDesc, sizeof(TPartialDesc)); + TPartialDesc.u.Interrupt.Vector = + CurrentResource->u.SystemInterruptVector; + TPartialDesc.u.Interrupt.Level = + CurrentResource->u.SystemIrql; + + break; + + case CmResourceTypePort: + case CmResourceTypeMemory: + + // + // Process port and memory resources. + // + + RPartialDesc.Type = CurrentResource->ResourceType; + RPartialDesc.ShareDisposition = CmResourceShareDriverExclusive; + + if (RPartialDesc.Type == CmResourceTypePort) { + + // + // In IO space. + // + + i = 1; + RPartialDesc.Flags = CM_RESOURCE_PORT_IO; + + } else { + + // + // In memory space. + // + + i = 0; + RPartialDesc.Flags = CM_RESOURCE_MEMORY_READ_WRITE; + } + + // + // Notice: assume u.Memory and u.Port have the same layout. + // + + RPartialDesc.u.Memory.Start.HighPart = 0; + RPartialDesc.u.Memory.Start.LowPart = CurrentResource->u.Start; + RPartialDesc.u.Memory.Length = CurrentResource->u.Length; + + RtlCopyMemory(&TPartialDesc, &RPartialDesc, sizeof(TPartialDesc)); + + // + // Translate the address. + // + + HalTranslateBusAddress(CurrentResource->BusType, + CurrentResource->BusNumber, + RPartialDesc.u.Memory.Start, + &i, + &PhyAddress ); + + TPartialDesc.u.Memory.Start = PhyAddress; + + if ((RPartialDesc.Type == CmResourceTypePort) && (i == 0)) + TPartialDesc.Flags = CM_RESOURCE_PORT_MEMORY; + + break; + + case CmResourceTypeDma: + + // + // Process dma resources. + // + + RPartialDesc.Type = CmResourceTypeDma; + RPartialDesc.ShareDisposition = CmResourceShareDriverExclusive; + + RPartialDesc.u.Dma.Channel = CurrentResource->u.DmaChannel; + RPartialDesc.u.Dma.Port = CurrentResource->u.DmaPort; + + RtlCopyMemory(&TPartialDesc, &RPartialDesc, sizeof(TPartialDesc)); + TPartialDesc.u.Dma.Channel = CurrentResource->u.DmaChannel; + TPartialDesc.u.Dma.Port = CurrentResource->u.DmaPort; + + break; + + default: + + // + // Got a resource we don't know. Bail out! + // + + goto NextResource; + } + + // + // Include the current resource in the HAL list. + // + + if (pRFullDesc->InterfaceType != CurrentBus->BusType) { + + // + // Interface type changed, add another full section + // + + RawResourceList->Count++; + TranslatedResourceList->Count++; + + pRFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)pRCurLoc; + pTFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR)pTCurLoc; + + pRFullDesc->InterfaceType = CurrentBus->BusType; + pTFullDesc->InterfaceType = CurrentBus->BusType; + + pRPartList = &pRFullDesc->PartialResourceList; + pTPartList = &pTFullDesc->PartialResourceList; + + // + // Bump current location pointers up + // + + pRCurLoc = pRFullDesc->PartialResourceList.PartialDescriptors; + pTCurLoc = pTFullDesc->PartialResourceList.PartialDescriptors; + } + + // + // Add current resource in. + // + + pRPartList->Count++; + pTPartList->Count++; + RtlCopyMemory(pRCurLoc, &RPartialDesc, sizeof(RPartialDesc)); + RtlCopyMemory(pTCurLoc, &TPartialDesc, sizeof(TPartialDesc)); + + pRCurLoc++; + pTCurLoc++; + } + + // + // Finished with this resource, move to the next one. + // + + NextResource: + CurrentResource = CurrentResource->Next; + } + + // + // Finished with this bus, move to the next one. + // + + CurrentBus = CurrentBus->Next; + } + + // + // Do the actual reporting. + // + + ListSize = (ULONG)(((PUCHAR)pRCurLoc) - ((PUCHAR)RawResourceList)); + + // + // The HAL's resource usage structures have been built + // Sort the partial lists based on the Raw resource values. + // + + pRFullDesc = RawResourceList->List; + pTFullDesc = TranslatedResourceList->List; + + for (i=0; i < RawResourceList->Count; i++) { + + pRCurLoc = pRFullDesc->PartialResourceList.PartialDescriptors; + pTCurLoc = pTFullDesc->PartialResourceList.PartialDescriptors; + Count = pRFullDesc->PartialResourceList.Count; + + for (j=0; j < Count; j++) { + HalpGetResourceSortValue (pRCurLoc, &curscale, &curvalue); + + pRSortLoc = pRCurLoc; + pTSortLoc = pTCurLoc; + + for (k=j; k < Count; k++) { + HalpGetResourceSortValue (pRSortLoc, &sortscale, &sortvalue); + + if (sortscale < curscale || + (sortscale == curscale && + (sortvalue.QuadPart < curvalue.QuadPart)) ){ + + // + // Swap the elements. + // + + RtlCopyMemory (&RPartialDesc, pRCurLoc, sizeof RPartialDesc); + RtlCopyMemory (pRCurLoc, pRSortLoc, sizeof RPartialDesc); + RtlCopyMemory (pRSortLoc, &RPartialDesc, sizeof RPartialDesc); + + // + // Swap translated descriptor as well. + // + + RtlCopyMemory (&TPartialDesc, pTCurLoc, sizeof TPartialDesc); + RtlCopyMemory (pTCurLoc, pTSortLoc, sizeof TPartialDesc); + RtlCopyMemory (pTSortLoc, &TPartialDesc, sizeof TPartialDesc); + + // + // Get new curscale & curvalue. + // + + HalpGetResourceSortValue (pRCurLoc, &curscale, &curvalue); + } + + pRSortLoc++; + pTSortLoc++; + } + + pRCurLoc++; + pTCurLoc++; + } + + pRFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) pRCurLoc; + pTFullDesc = (PCM_FULL_RESOURCE_DESCRIPTOR) pTCurLoc; + } + + // + // Inform the IO system of our resources. + // + + IoReportHalResourceUsage(HalName, + RawResourceList, + TranslatedResourceList, + ListSize); + + ExFreePool (RawResourceList); + ExFreePool (TranslatedResourceList); + + // + // Free all registered buses. + // + + while (HalpBusUsageList) { + + CurrentBus = HalpBusUsageList; + HalpBusUsageList = HalpBusUsageList->Next; + ExFreePool(CurrentBus); + } + + // + // Free all registered resources. + // + + while (HalpResourceUsageList) { + + CurrentResource = HalpResourceUsageList; + HalpResourceUsageList = HalpResourceUsageList->Next; + ExFreePool(CurrentResource); + } +} + |