diff options
Diffstat (limited to 'private/ntos/nthals/halr98mp/mips/r98busdt.c')
-rw-r--r-- | private/ntos/nthals/halr98mp/mips/r98busdt.c | 1181 |
1 files changed, 1181 insertions, 0 deletions
diff --git a/private/ntos/nthals/halr98mp/mips/r98busdt.c b/private/ntos/nthals/halr98mp/mips/r98busdt.c new file mode 100644 index 000000000..a14d3cf4c --- /dev/null +++ b/private/ntos/nthals/halr98mp/mips/r98busdt.c @@ -0,0 +1,1181 @@ +#ident "@(#) NEC r98busdt.c 1.16 95/06/19 11:30:31" +/*++ + + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + ixhwsup.c + +Abstract: + + This module contains the IoXxx routines for the NT I/O system that + are hardware dependent. Were these routines not hardware dependent, + they would reside in the iosubs.c module. + +Author: + + Darryl E. Havens (darrylh) 11-Apr-1990 + +Environment: + + Kernel mode + +Revision History: + + +--*/ + +/*++ + + Modification History + + N- NEW + D- Only For Debug + B- Bug Fix + +B001 ataka@oa2.kb.nec.co.jp Mon Oct 24 21:40:10 JST 1994 + - add DbgPrints + +B002 samezima@oa2.kb.nec.co.jp MON Nov 21 + - chg Mask translate address + +N005 samezima@oa2.kb.nec.co.jp MON Mar 13 + - change PIO interrupt vector from internal to eisa. +A002 ataka@oa2.kb.nec.co.jp 1995/6/17 + - Marge 1050 halx86 many sources to 807 r98busdat.c + and named r98busdt.c + +--*/ + +#include "halp.h" +#include "string.h" // CMP001 + + +UCHAR HalName[] = "NEC MIPS HAL"; // N003 + +VOID HalpInitializePciBus (VOID); // CMP001 +VOID HalpInitOtherBuses (VOID); + + +// +// Prototype for system bus handlers +// + +ULONG +HalpNoBusData ( + IN PVOID BusHandler, + IN PVOID RootHandler, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length + ); + +ULONG +HalpGetSystemInterruptVector ( + IN PVOID BusHandler, + IN PVOID RootHandler, + IN ULONG BusInterruptLevel, + IN ULONG BusInterruptVector, + OUT PKIRQL Irql, + OUT PKAFFINITY Affinity + ); + +ULONG +HalpGetEisaInterruptVector ( + IN PVOID BusHandler, + IN PVOID RootHandler, + IN ULONG BusInterruptLevel, + IN ULONG BusInterruptVector, + OUT PKIRQL Irql, + OUT PKAFFINITY Affinity + ); + +BOOLEAN +HalpTranslateSystemBusAddress ( + IN PVOID BusHandler, + IN PVOID RootHandler, + IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress + ); + +BOOLEAN +HalpTranslatePCIBusAddress ( + IN PVOID BusHandler, + IN PVOID RootHandler, + IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress + ); + +BOOLEAN +HalpTranslateIsaBusAddress ( + IN PVOID BusHandler, + IN PVOID RootHandler, + IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress + ); + + +BOOLEAN +HalpTranslateEisaBusAddress ( + IN PVOID BusHandler, + IN PVOID RootHandler, + IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress + ); + + +HalpGetEisaData ( + IN PVOID BusHandler, + IN PVOID RootHandler, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length + ); + +NTSTATUS +HalpAdjustEisaResourceList ( + IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *pResourceList + ); + +#if DBG // A002 +VOID +HalpDisplayAllBusRanges ( + VOID + ); +VOID +HalpDisplayAddressRange ( + PSUPPORTED_RANGE Address, + PUCHAR String +); +#endif + +#ifdef ALLOC_PRAGMA +#pragma alloc_text(INIT,HalpAllocateBusHandler) +#pragma alloc_text(PAGE,HalGetInterruptVector) +/* B001 */ +#pragma alloc_text(INIT,HalReportResourceUsage) +#pragma alloc_text(PAGE,HalpGetEisaInterruptVector) +#pragma alloc_text(PAGE,HalpAdjustEisaResourceList) +#pragma alloc_text(PAGE,HalpGetEisaData) +#pragma alloc_text(PAGE,HalpGetSystemInterruptVector) +#endif + + +#ifdef ALLOC_PRAGMA +#pragma alloc_text(INIT,HalpRegisterInternalBusHandlers) +#pragma alloc_text(INIT,HalpAllocateBusHandler) +#endif + + +VOID +HalpRegisterInternalBusHandlers ( + VOID + ) +{ + PBUS_HANDLER Bus; + + if (KeGetCurrentPrcb()->Number) { + // only need to do this once + return ; + } + + // + // Initalize BusHandler data before registering any handlers + // + + HalpInitBusHandler (); + + // + // Build internal-bus 0, or system level bus + // + + Bus = HalpAllocateBusHandler ( + Internal, + ConfigurationSpaceUndefined, + 0, // Internal BusNumber 0 + InterfaceTypeUndefined, // no parent bus + 0, + 0 // no bus specfic data + ); + + Bus->GetInterruptVector = HalpGetSystemInterruptVector; + Bus->TranslateBusAddress = HalpTranslateSystemBusAddress; + + // + // Build internal-bus 0, or system level bus + // + // B003 kugi Internal Bus was called with bus-no. 2, We have no idea. + + Bus = HalpAllocateBusHandler ( + Internal, + ConfigurationSpaceUndefined, + 1, // Internal BusNumber 1 + InterfaceTypeUndefined, // no parent bus + 0, + 0 // no bus specfic data + ); + + Bus->GetInterruptVector = HalpGetSystemInterruptVector; + Bus->TranslateBusAddress = HalpTranslateSystemBusAddress; + + // + // Build Isa/Eisa bus #0 + // + + Bus = HalpAllocateBusHandler (Eisa, EisaConfiguration, 0, Internal, 0, 0); + Bus->GetBusData = HalpGetEisaData; + Bus->GetInterruptVector = HalpGetEisaInterruptVector; + Bus->AdjustResourceList = HalpAdjustEisaResourceList; +#if defined(_R98_) // A001 + Bus->TranslateBusAddress = HalpTranslateEisaBusAddress; +#endif // _R98_ + Bus = HalpAllocateBusHandler (Isa, ConfigurationSpaceUndefined, 0, Eisa, 0, 0); + Bus->GetBusData = HalpNoBusData; + Bus->BusAddresses->Memory.Limit = 0xFFFFFF; + Bus->TranslateBusAddress = HalpTranslateIsaBusAddress; + + HalpInitOtherBuses (); +#if DBG // A002 + HalpDisplayAllBusRanges (); +#endif +} + + +PBUS_HANDLER +HalpAllocateBusHandler ( + IN INTERFACE_TYPE InterfaceType, + IN BUS_DATA_TYPE BusDataType, + IN ULONG BusNumber, + IN INTERFACE_TYPE ParentBusInterfaceType, + IN ULONG ParentBusNumber, + IN ULONG BusSpecificData + ) +/*++ + +Routine Description: + + Stub function to map old style code into new HalRegisterBusHandler code. + + Note we can add our specific bus handler functions after this bus + handler structure has been added since this is being done during + hal initialization. + +--*/ +{ + PBUS_HANDLER Bus; + + + // + // Create bus handler - new style + // + + HaliRegisterBusHandler ( + InterfaceType, + BusDataType, + BusNumber, + ParentBusInterfaceType, + ParentBusNumber, + BusSpecificData, + NULL, + &Bus + ); + + // A001 + if (InterfaceType != InterfaceTypeUndefined) { + Bus->BusAddresses = ExAllocatePool (SPRANGEPOOL, sizeof (SUPPORTED_RANGES)); + RtlZeroMemory (Bus->BusAddresses, sizeof (SUPPORTED_RANGES)); + Bus->BusAddresses->Version = BUS_SUPPORTED_RANGE_VERSION; + Bus->BusAddresses->Dma.Limit = 7; + Bus->BusAddresses->IO.Base = 0; + Bus->BusAddresses->IO.SystemAddressSpace = 0; + Bus->BusAddresses->PrefetchMemory.Base = 1; + + switch(InterfaceType) { + case Internal: + Bus->BusAddresses->Memory.Base + = 0x00000000; + ((PLARGE_INTEGER)(&Bus->BusAddresses->Memory.Limit))->LowPart + = 0xFFFFFFFF; + Bus->BusAddresses->Memory.SystemBase + = 0x00000000; + Bus->BusAddresses->IO.Base + = 0x00000000; + ((PLARGE_INTEGER)(&Bus->BusAddresses->IO.Limit))->LowPart + = 0xFFFFFFFF; + Bus->BusAddresses->IO.SystemBase + = 0x00000000; + break; + case Eisa: + Bus->BusAddresses->Memory.Base + = 0x00000000; +// = 0x01000000; + Bus->BusAddresses->Memory.Limit + = 0x03FFFFFF; + ((PLARGE_INTEGER)(&Bus->BusAddresses->Memory.SystemBase))->LowPart + = EISA_MEMORY_PHYSICAL_BASE; + Bus->BusAddresses->IO.Base + = 0x00000000; + Bus->BusAddresses->IO.Limit + = 0x0000FFFF; + ((PLARGE_INTEGER)(&Bus->BusAddresses->IO.SystemBase))->LowPart + = EISA_CONTROL_PHYSICAL_BASE; + break; + case Isa: + Bus->BusAddresses->Memory.Base + = 0x00000000; + Bus->BusAddresses->Memory.Limit + = 0x00FFFFFF; + ((PLARGE_INTEGER)(&Bus->BusAddresses->Memory.SystemBase))->LowPart + = EISA_MEMORY_PHYSICAL_BASE; + Bus->BusAddresses->IO.Base + = 0x00000000; + Bus->BusAddresses->IO.Limit + = 0x0000FFFF; + ((PLARGE_INTEGER)(&Bus->BusAddresses->IO.SystemBase))->LowPart + = EISA_CONTROL_PHYSICAL_BASE; + break; + case PCIBus: + Bus->BusAddresses->Memory.Base + = 0x04000000; // from 64MB + Bus->BusAddresses->Memory.Limit + = 0x0FFFFFFF; // up to 256MB + ((PLARGE_INTEGER)(&Bus->BusAddresses->Memory.SystemBase))->LowPart + = PCI_MEMORY_PHYSICAL_BASE; + Bus->BusAddresses->IO.Base + = 0x00000000; + Bus->BusAddresses->IO.Limit + = 0x0000FFFF; + ((PLARGE_INTEGER)(&Bus->BusAddresses->IO.SystemBase))->LowPart + = PCI_CONTROL_SLOT1_PHYSICAL_BASE; + break; + } + } + + return Bus; +} + +// N003 +VOID +HalReportResourceUsage ( + VOID + ) +{ + ANSI_STRING AHalName; + UNICODE_STRING UHalName; + + + // N004 +#if 0 // support next version + HalpRegisterAddressUsage (&HalpDefaultPcIoSpace); + HalpRegisterAddressUsage (&HalpEisaIoSpace); + HalpRegisterAddressUsage (&HalpMapRegisterMemorySpace); +#endif + + RtlInitAnsiString (&AHalName, HalName); + RtlAnsiStringToUnicodeString (&UHalName, &AHalName, TRUE); + HalpReportResourceUsage ( + &UHalName, // descriptive name + Internal // device space interface type + ); + + RtlFreeUnicodeString (&UHalName); + + // + // Registry is now intialized, see if there are any PCI buses + // + + HalpInitializePciBus (); +} + +VOID +HalpInitOtherBuses ( + VOID + ) +{ + // no other internal buses supported +} + + + + +ULONG +HalpGetEisaInterruptVector( + IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN ULONG BusInterruptLevel, + IN ULONG BusInterruptVector, + OUT PKIRQL Irql, + OUT PKAFFINITY Affinity + ) + +/*++ + +Routine Description: + + This function returns the system interrupt vector and IRQL level + corresponding to the specified bus interrupt level and/or vector. The + system interrupt vector and IRQL are suitable for use in a subsequent call + to KeInitializeInterrupt. + +Arguments: + + BusHandle - Per bus specific structure + + Irql - Returns the system request priority. + + Affinity - Returns the system wide irq affinity. + +Return Value: + + Returns the system interrupt vector corresponding to the specified device. + +--*/ +{ + // + // Jazz and Duo only have one I/O bus which is an EISA, so the bus + // number and the bus interrupt vector are unused. + // + // The IRQL level is always equal to the EISA level. + // + + *Affinity = HalpEisaBusAffinity; // N003 + + *Irql = INT1_LEVEL; + + // + // Bus interrupt level 2 is actually mapped to bus level 9 in the Eisa + // hardware. + // + + if (BusInterruptLevel == 2) { + BusInterruptLevel = 9; + } + + // + // The vector is equal to the specified bus level plus the EISA_VECTOR. + // + + return(BusInterruptLevel + EISA_VECTORS); +} + +HalpGetEisaData ( + IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN ULONG SlotNumber, + IN PVOID Buffer, + IN ULONG Offset, + IN ULONG Length + ) +/*++ + +Routine Description: + + The function returns the Eisa bus data for a slot or address. + +Arguments: + + Buffer - Supplies the space to store the data. + + Length - Supplies a count in bytes of the maximum amount to return. + +Return Value: + + Returns the amount of data stored into the buffer. + +--*/ + +{ + OBJECT_ATTRIBUTES ObjectAttributes; + OBJECT_ATTRIBUTES BusObjectAttributes; + PWSTR EisaPath = L"\\Registry\\Machine\\Hardware\\Description\\System\\EisaAdapter"; + PWSTR ConfigData = L"Configuration Data"; + ANSI_STRING TmpString; + ULONG BusNumber; + UCHAR BusString[] = "00"; + UNICODE_STRING RootName, BusName; + UNICODE_STRING ConfigDataName; + NTSTATUS NtStatus; + PKEY_VALUE_FULL_INFORMATION ValueInformation; + PCM_FULL_RESOURCE_DESCRIPTOR Descriptor; + PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResource; + PCM_EISA_SLOT_INFORMATION SlotInformation; + ULONG PartialCount; + ULONG TotalDataSize, SlotDataSize; + HANDLE EisaHandle, BusHandle; + ULONG BytesWritten, BytesNeeded; + PUCHAR KeyValueBuffer; + ULONG i; + ULONG DataLength = 0; + PUCHAR DataBuffer = Buffer; + BOOLEAN Found = FALSE; + + PAGED_CODE (); // A001 + + + RtlInitUnicodeString( + &RootName, + EisaPath + ); + + InitializeObjectAttributes( + &ObjectAttributes, + &RootName, + OBJ_CASE_INSENSITIVE, + (HANDLE)NULL, + NULL + ); + + // + // Open the EISA root + // + + NtStatus = ZwOpenKey( + &EisaHandle, + KEY_READ, + &ObjectAttributes + ); + + if (!NT_SUCCESS(NtStatus)) { + DbgPrint("HAL: Open Status = %x\n",NtStatus); + return(0); + } + + // + // Init bus number path + // + + BusNumber = BusHandler->BusNumber; + if (BusNumber > 99) { + return (0); + } + + if (BusNumber > 9) { + BusString[0] += (UCHAR) (BusNumber/10); + BusString[1] += (UCHAR) (BusNumber % 10); + } else { + BusString[0] += (UCHAR) BusNumber; + BusString[1] = '\0'; + } + + RtlInitAnsiString( + &TmpString, + BusString + ); + + RtlAnsiStringToUnicodeString( + &BusName, + &TmpString, + TRUE + ); + + + InitializeObjectAttributes( + &BusObjectAttributes, + &BusName, + OBJ_CASE_INSENSITIVE, + (HANDLE)EisaHandle, + NULL + ); + + // + // Open the EISA root + Bus Number + // + + NtStatus = ZwOpenKey( + &BusHandle, + KEY_READ, + &BusObjectAttributes + ); + + if (!NT_SUCCESS(NtStatus)) { + DbgPrint("HAL: Opening Bus Number: Status = %x\n",NtStatus); + return(0); + } + + // + // opening the configuration data. This first call tells us how + // much memory we need to allocate + // + + RtlInitUnicodeString( + &ConfigDataName, + ConfigData + ); + + // + // This should fail. We need to make this call so we can + // get the actual size of the buffer to allocate. + // + + ValueInformation = (PKEY_VALUE_FULL_INFORMATION) &i; + NtStatus = ZwQueryValueKey( + BusHandle, + &ConfigDataName, + KeyValueFullInformation, + ValueInformation, + 0, + &BytesNeeded + ); + + KeyValueBuffer = ExAllocatePool( + NonPagedPool, + BytesNeeded + ); + + if (KeyValueBuffer == NULL) { +#if DBG + DbgPrint("HAL: Cannot allocate Key Value Buffer\n"); +#endif + ZwClose(BusHandle); + return(0); + } + + ValueInformation = (PKEY_VALUE_FULL_INFORMATION)KeyValueBuffer; + + NtStatus = ZwQueryValueKey( + BusHandle, + &ConfigDataName, + KeyValueFullInformation, + ValueInformation, + BytesNeeded, + &BytesWritten + ); + + + ZwClose(BusHandle); + + if (!NT_SUCCESS(NtStatus)) { +#if DBG + DbgPrint("HAL: Query Config Data: Status = %x\n",NtStatus); +#endif + ExFreePool(KeyValueBuffer); + return(0); + } + + + // + // We get back a Full Resource Descriptor List + // + + Descriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)((PUCHAR)ValueInformation + + ValueInformation->DataOffset); + + PartialResource = (PCM_PARTIAL_RESOURCE_DESCRIPTOR) + &(Descriptor->PartialResourceList.PartialDescriptors); + PartialCount = Descriptor->PartialResourceList.Count; + + for (i = 0; i < PartialCount; i++) { + + // + // Do each partial Resource + // + + switch (PartialResource->Type) { + case CmResourceTypeNull: + case CmResourceTypePort: + case CmResourceTypeInterrupt: + case CmResourceTypeMemory: + case CmResourceTypeDma: + + // + // We dont care about these. + // + + PartialResource++; + + break; + + case CmResourceTypeDeviceSpecific: + + // + // Bingo! + // + + TotalDataSize = PartialResource->u.DeviceSpecificData.DataSize; + + SlotInformation = (PCM_EISA_SLOT_INFORMATION) + ((PUCHAR)PartialResource + + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)); + + while (((LONG)TotalDataSize) > 0) { + + if (SlotInformation->ReturnCode == EISA_EMPTY_SLOT) { + + SlotDataSize = sizeof(CM_EISA_SLOT_INFORMATION); + + } else { + + SlotDataSize = sizeof(CM_EISA_SLOT_INFORMATION) + + SlotInformation->NumberFunctions * + sizeof(CM_EISA_FUNCTION_INFORMATION); + } + + if (SlotDataSize > TotalDataSize) { + + // + // Something is wrong again + // + + ExFreePool(KeyValueBuffer); + return(0); + + } + + if (SlotNumber != 0) { + + SlotNumber--; + + SlotInformation = (PCM_EISA_SLOT_INFORMATION) + ((PUCHAR)SlotInformation + SlotDataSize); + + TotalDataSize -= SlotDataSize; + + continue; + + } + + // + // This is our slot + // + + Found = TRUE; + break; + + } + + // + // End loop + // + + i = PartialCount; + + break; + + default: + +#if DBG + DbgPrint("Bad Data in registry!\n"); +#endif + + ExFreePool(KeyValueBuffer); + return(0); + + } + + } + + if (Found) { + i = Length + Offset; + if (i > SlotDataSize) { + i = SlotDataSize; + } + + DataLength = i - Offset; + RtlMoveMemory (Buffer, ((PUCHAR)SlotInformation + Offset), DataLength); + } + + ExFreePool(KeyValueBuffer); + return DataLength; +} + + + +// N001 +ULONG +HalpGetSystemInterruptVector( + IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN ULONG BusInterruptLevel, + IN ULONG BusInterruptVector, + OUT PKIRQL Irql, + OUT PKAFFINITY Affinity + ) + +/*++ + +Routine Description: + +Arguments: + + BusInterruptLevel - Supplies the bus specific interrupt level. + + BusInterruptVector - Supplies the bus specific interrupt vector. + + Irql - Returns the system request priority. + + Affinity - Returns the system wide irq affinity. + +Return Value: + + Returns the system interrupt vector corresponding to the specified device. + +--*/ +{ + /* N003 vvv */ + ULONG vector; + + *Irql = (KIRQL)BusInterruptLevel; + vector = BusInterruptVector + DEVICE_VECTORS; + + switch(vector) { + case SCSI1_VECTOR: + case SCSI0_VECTOR: + case ETHER_VECTOR: + *Affinity = HalpInt1Affinity; + break; + + // N005 vvv + case PIO_VECTOR: + return HalpGetEisaInterruptVector( (PBUS_HANDLER)NULL, + (PBUS_HANDLER)NULL, + 1, + 1, + Irql, + Affinity + ); + // N005 ^^^ + + default: + *Affinity = 1; + } + + return vector; + /* N003 ^^^ */ +} + + +// A001 +NTSTATUS +HalpAdjustEisaResourceList ( + IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *pResourceList + ) +{ + SUPPORTED_RANGE InterruptRange; + + RtlZeroMemory (&InterruptRange, sizeof InterruptRange); + InterruptRange.Base = 0; + InterruptRange.Limit = 15; + + return HaliAdjustResourceListRange ( + BusHandler->BusAddresses, + &InterruptRange, + pResourceList + ); +} + +// A001 +BOOLEAN +HalpTranslateSystemBusAddress( + IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress + ) + +/*++ + +Routine Description: + + This function translates a bus-relative address space and address into + a system physical address. + +Arguments: + + BusAddress - Supplies the bus-relative address + + AddressSpace - Supplies the address space number. + Returns the host address space number. + + AddressSpace == 0 => memory space + AddressSpace == 1 => I/O space + + TranslatedAddress - Supplies a pointer to return the translated address + +Return Value: + + A return value of TRUE indicates that a system physical address + corresponding to the supplied bus relative address and bus address + number has been returned in TranslatedAddress. + + A return value of FALSE occurs if the translation for the address was + not possible + +--*/ + +{ + PSUPPORTED_RANGE pRange; + + pRange = NULL; + switch (*AddressSpace) { + case 0: + // verify memory address is within buses memory limits +#if DBG +// DbgPrint("\nHalpTranslateSystemBusAddress-searching(Mem)...."); +#endif + for (pRange = &BusHandler->BusAddresses->PrefetchMemory; pRange; pRange = pRange->Next) { +#if DBG +// HalpDisplayAddressRange (pRange, "\n PrefetchMemory:"); +#endif // DBG + if (BusAddress.QuadPart >= pRange->Base && + BusAddress.QuadPart <= pRange->Limit) { + break; + } + } + + if (!pRange) { + for (pRange = &BusHandler->BusAddresses->Memory; pRange; pRange = pRange->Next) { +#if DBG +// HalpDisplayAddressRange (pRange, "\n Memory:"); +#endif // DBG + if (BusAddress.QuadPart >= pRange->Base && + BusAddress.QuadPart <= pRange->Limit) { + break; + } + } + } + + break; + + case 1: + // verify IO address is within buses IO limits +#if DBG +// DbgPrint("HalpTranslateSystemBusAddress-searching(Io)....\n"); +#endif + for (pRange = &BusHandler->BusAddresses->IO; pRange; pRange = pRange->Next) { +#if DBG +// HalpDisplayAddressRange (pRange, "\n Io:"); +#endif // DBG + if (BusAddress.QuadPart >= pRange->Base && + BusAddress.QuadPart <= pRange->Limit) { + break; + } + } + break; + } + + if (pRange) { + TranslatedAddress->QuadPart = BusAddress.QuadPart + pRange->SystemBase; +#if DBG +// DbgPrint("\n Translated=0x%08x:%08x\nEnd of Translating Success!\n", TranslatedAddress->HighPart, +// TranslatedAddress->LowPart); +#endif // DBG + *AddressSpace = pRange->SystemAddressSpace; + return TRUE; + } +#if DBG +// DbgPrint("\nEnd of Translating. False!\n"); +#endif + + return FALSE; +} + +// A001 +BOOLEAN +HalpTranslateIsaBusAddress( + IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress + ) + +/*++ + +Routine Description: + + This function translates a bus-relative address space and address into + a system physical address. + +Arguments: + + BusAddress - Supplies the bus-relative address + + AddressSpace - Supplies the address space number. + Returns the host address space number. + + AddressSpace == 0 => memory space + AddressSpace == 1 => I/O space + + TranslatedAddress - Supplies a pointer to return the translated address + +Return Value: + + A return value of TRUE indicates that a system physical address + corresponding to the supplied bus relative address and bus address + number has been returned in TranslatedAddress. + + A return value of FALSE occurs if the translation for the address was + not possible + +--*/ + +{ + BOOLEAN Status; + + // + // Translated normally + // + + Status = HalpTranslateSystemBusAddress ( + BusHandler, + RootHandler, + BusAddress, + AddressSpace, + TranslatedAddress + ); + + + // + // If it could not be translated, and it's memory space + // then we allow the translation as it would occur on it's + // corrisponding EISA bus. We're allowing this because + // many VLBus drivers are claiming to be ISA devices. + // (yes, they should claim to be VLBus devices, but VLBus is + // run by video cards and like everything else about video + // there's no hope of fixing it. (At least according to + // Andre)) + // + + if (Status == FALSE && *AddressSpace == 0) { + Status = HalTranslateBusAddress ( + Eisa, + BusHandler->BusNumber, + BusAddress, + AddressSpace, + TranslatedAddress + ); + } + + return Status; +} + +// A001 +BOOLEAN +HalpTranslateEisaBusAddress( + IN PBUS_HANDLER BusHandler, + IN PBUS_HANDLER RootHandler, + IN PHYSICAL_ADDRESS BusAddress, + IN OUT PULONG AddressSpace, + OUT PPHYSICAL_ADDRESS TranslatedAddress + ) + +/*++ + +Routine Description: + + This function translates a bus-relative address space and address into + a system physical address. + +Arguments: + + BusAddress - Supplies the bus-relative address + + AddressSpace - Supplies the address space number. + Returns the host address space number. + + AddressSpace == 0 => memory space + AddressSpace == 1 => I/O space + + TranslatedAddress - Supplies a pointer to return the translated address + +Return Value: + + A return value of TRUE indicates that a system physical address + corresponding to the supplied bus relative address and bus address + number has been returned in TranslatedAddress. + + A return value of FALSE occurs if the translation for the address was + not possible + +--*/ + +{ + BOOLEAN Status; + + // + // Translated normally + // + + Status = HalpTranslateSystemBusAddress ( + BusHandler, + RootHandler, + BusAddress, + AddressSpace, + TranslatedAddress + ); + + + // + // If it could not be translated, and it's in the 640k - 1m + // range then (for compatibility) try translating it on the + // Internal bus for + // + + if (Status == FALSE && + *AddressSpace == 0 && + BusAddress.HighPart == 0 && + BusAddress.LowPart >= 0xA0000 && + BusAddress.LowPart < 0xFFFFF) { + + Status = HalTranslateBusAddress ( + Internal, + 0, + BusAddress, + AddressSpace, + TranslatedAddress + ); + } + + return Status; +} + +#if DBG +VOID +HalpDisplayAddressRange ( + PSUPPORTED_RANGE Address, + PUCHAR String + ) +/*++ + +Routine Description: + + Debugging code. Used only by HalpDisplayAllBusRanges + +--*/ +{ + ULONG i; + + i = 0; + while (Address) { + if (i == 0) { + DbgPrint (String); + i = 3; + } + + i -= 1; + DbgPrint (" %x:%08x - %x:%08x + %x:%08x", + (ULONG) (Address->Base >> 32), + (ULONG) (Address->Base), + (ULONG) (Address->Limit >> 32), + (ULONG) (Address->Limit), + (ULONG) (Address->SystemBase >> 32), + (ULONG) (Address->SystemBase) + ); + + Address = Address->Next; + } +} +#endif // DBG |