summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/halr98mp/mips/r98busdt.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/nthals/halr98mp/mips/r98busdt.c')
-rw-r--r--private/ntos/nthals/halr98mp/mips/r98busdt.c1181
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