Beispiel #1
0
NTSTATUS
HalpGetISAFixedPCIIrq (
    IN PBUS_HANDLER         BusHandler,
    IN PBUS_HANDLER         RootHandler,
    IN PCI_SLOT_NUMBER      PciSlot,
    OUT PSUPPORTED_RANGE    *Interrupt
    )
{
    UCHAR                   buffer[PCI_COMMON_HDR_LENGTH];
    PPCI_COMMON_CONFIG      PciData;


    PciData = (PPCI_COMMON_CONFIG) buffer;
    HalGetBusData (
        PCIConfiguration,
        BusHandler->BusNumber,
        PciSlot.u.AsULONG,
        PciData,
        PCI_COMMON_HDR_LENGTH
        );

    if (PciData->VendorID == PCI_INVALID_VENDORID  ||
        PCI_CONFIG_TYPE (PciData) != 0) {
        return STATUS_UNSUCCESSFUL;
    }

    *Interrupt = ExAllocatePool (PagedPool, sizeof (SUPPORTED_RANGE));
    if (!*Interrupt) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    RtlZeroMemory (*Interrupt, sizeof (SUPPORTED_RANGE));
    (*Interrupt)->Base = 1;                 // base = 1, limit = 0

    if (!PciData->u.type0.InterruptPin) {
        return STATUS_SUCCESS;
    }

    if (PciData->u.type0.InterruptLine == (0 ^ IRQXOR)  ||
        PciData->u.type0.InterruptLine == (0xFF ^ IRQXOR)) {

#if DBG
        DbgPrint ("HalpGetValidPCIFixedIrq: BIOS did not assign an interrupt vector for the device\n");
#endif
        //
        // We need to let the caller continue, since the caller may
        // not care that the interrupt vector is connected or not
        //

        return STATUS_SUCCESS;
    }

    (*Interrupt)->Base  = PciData->u.type0.InterruptLine;
    (*Interrupt)->Limit = PciData->u.type0.InterruptLine;
    return STATUS_SUCCESS;
}
/**
 * Helper function to handle the PCI device lookup.
 *
 * @returns NT status code.
 *
 * @param   pulBusNumber    Where to return the bus number on success.
 * @param   pSlotNumber     Where to return the slot number on success.
 */
static NTSTATUS vgdrvNt4FindPciDevice(PULONG pulBusNumber, PPCI_SLOT_NUMBER pSlotNumber)
{
    Log(("vgdrvNt4FindPciDevice\n"));

    PCI_SLOT_NUMBER SlotNumber;
    SlotNumber.u.AsULONG = 0;

    /* Scan each bus. */
    for (ULONG ulBusNumber = 0; ulBusNumber < PCI_MAX_BUSES; ulBusNumber++)
    {
        /* Scan each device. */
        for (ULONG deviceNumber = 0; deviceNumber < PCI_MAX_DEVICES; deviceNumber++)
        {
            SlotNumber.u.bits.DeviceNumber = deviceNumber;

            /* Scan each function (not really required...). */
            for (ULONG functionNumber = 0; functionNumber < PCI_MAX_FUNCTION; functionNumber++)
            {
                SlotNumber.u.bits.FunctionNumber = functionNumber;

                /* Have a look at what's in this slot. */
                PCI_COMMON_CONFIG PciData;
                if (!HalGetBusData(PCIConfiguration, ulBusNumber, SlotNumber.u.AsULONG, &PciData, sizeof(ULONG)))
                {
                    /* No such bus, we're done with it. */
                    deviceNumber = PCI_MAX_DEVICES;
                    break;
                }

                if (PciData.VendorID == PCI_INVALID_VENDORID)
                    /* We have to proceed to the next function. */
                    continue;

                /* Check if it's another device. */
                if (   PciData.VendorID != VMMDEV_VENDORID
                    || PciData.DeviceID != VMMDEV_DEVICEID)
                    continue;

                /* Hooray, we've found it! */
                Log(("vgdrvNt4FindPciDevice: Device found!\n"));

                *pulBusNumber = ulBusNumber;
                *pSlotNumber  = SlotNumber;
                return STATUS_SUCCESS;
            }
        }
    }

    return STATUS_DEVICE_DOES_NOT_EXIST;
}
Beispiel #3
0
NTSTATUS NTAPI
IntVideoPortGetLegacyResources(
    IN PVIDEO_PORT_DRIVER_EXTENSION DriverExtension,
    IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
    OUT PVIDEO_ACCESS_RANGE *AccessRanges,
    OUT PULONG AccessRangeCount)
{
    PCI_COMMON_CONFIG PciConfig;
    ULONG ReadLength;
    
    if (!DriverExtension->InitializationData.HwGetLegacyResources &&
        !DriverExtension->InitializationData.HwLegacyResourceCount)
    {
        /* No legacy resources to report */
        *AccessRangeCount = 0;
        return STATUS_SUCCESS;
    }
    
    if (DriverExtension->InitializationData.HwGetLegacyResources)
    {
        ReadLength = HalGetBusData(PCIConfiguration,
                                   DeviceExtension->SystemIoBusNumber,
                                   DeviceExtension->SystemIoSlotNumber,
                                   &PciConfig,
                                   sizeof(PciConfig));
        if (ReadLength != sizeof(PciConfig))
        {
            /* This device doesn't exist */
            return STATUS_NO_SUCH_DEVICE;
        }
        
        DriverExtension->InitializationData.HwGetLegacyResources(PciConfig.VendorID,
                                                                 PciConfig.DeviceID,
                                                                 AccessRanges,
                                                                 AccessRangeCount);
    }
    else
    {
        *AccessRanges = DriverExtension->InitializationData.HwLegacyResourceList;
        *AccessRangeCount = DriverExtension->InitializationData.HwLegacyResourceCount;
    }

    INFO_(VIDEOPRT, "Got %d legacy access ranges\n", *AccessRangeCount);

    return STATUS_SUCCESS;
}
Beispiel #4
0
NTSTATUS
NTAPI
HalpGetISAFixedPCIIrq(IN PBUS_HANDLER BusHandler,
                      IN PBUS_HANDLER RootHandler,
                      IN PCI_SLOT_NUMBER PciSlot,
                      OUT PSUPPORTED_RANGE *Range)
{
    PCI_COMMON_HEADER PciData;

    /* Read PCI configuration data */
    HalGetBusData(PCIConfiguration,
                  BusHandler->BusNumber,
                  PciSlot.u.AsULONG,
                  &PciData,
                  PCI_COMMON_HDR_LENGTH);

    /* Make sure it's a real device */
    if (PciData.VendorID == PCI_INVALID_VENDORID) return STATUS_UNSUCCESSFUL;

    /* Allocate the supported range structure */
    *Range = ExAllocatePoolWithTag(PagedPool, sizeof(SUPPORTED_RANGE), TAG_HAL);
    if (!*Range) return STATUS_INSUFFICIENT_RESOURCES;

    /* Set it up */
    RtlZeroMemory(*Range, sizeof(SUPPORTED_RANGE));
    (*Range)->Base = 1;

    /* If the PCI device has no IRQ, nothing to do */
    if (!PciData.u.type0.InterruptPin) return STATUS_SUCCESS;

    /* FIXME: The PCI IRQ Routing Miniport should be called */

    /* Also if the INT# seems bogus, nothing to do either */
    if ((PciData.u.type0.InterruptLine == 0) ||
        (PciData.u.type0.InterruptLine == 255))
    {
        /* Fake success */
        return STATUS_SUCCESS;
    }

    /* Otherwise, the INT# should be valid, return it to the caller */
    (*Range)->Base = PciData.u.type0.InterruptLine;
    (*Range)->Limit = PciData.u.type0.InterruptLine;
    return STATUS_SUCCESS;
}
Beispiel #5
0
NTSTATUS
HalpGetISAFixedPCIIrq (
    IN PBUS_HANDLER		BusHandler,
    IN PBUS_HANDLER		RootHandler,
    IN PCI_SLOT_NUMBER  PciSlot,
    OUT PUCHAR			IrqTable
)
{
    UCHAR					buffer[PCI_COMMON_HDR_LENGTH];
    PPCI_COMMON_CONFIG		PciData;
    ULONG					slot;
    ULONG					interrupt;

    PciData = (PPCI_COMMON_CONFIG) buffer;
    HalGetBusData (
        PCIConfiguration,
        BusHandler->BusNumber,
        PciSlot.u.AsULONG,
        PciData,
        PCI_COMMON_HDR_LENGTH
    );

    HDBG(DBG_INTERRUPTS,
         HalpDebugPrint("HalpGetISAFixedPCIIrq: %x, %x, %x, %x %x \n",
                        PCIConfiguration,
                        BusHandler->BusNumber,
                        PciSlot.u.AsULONG,
                        PciData,
                        PCI_COMMON_HDR_LENGTH ));

    if (PciData->VendorID == PCI_INVALID_VENDORID  ||
            PCI_CONFIG_TYPE (PciData) != 0) {
        return STATUS_UNSUCCESSFUL;
    }

    // For Primary PCI slots, the interrupt corresponds to the primary
    // slot number
    if ( BusHandler->BusNumber == 0 ) {
        slot = PciSlot.u.bits.DeviceNumber;
    }
    // For Secondary PCI slots, the interrupt corresponds to the slot
    // number of the primary parent
    else {
        slot = HalpGetPciInterruptSlot(BusHandler, PciSlot );
    }

    // Search the interrupt table for the interrupt corresponding to the slot
    if (slot < MAXIMUM_PCI_SLOTS) {
        interrupt = PciDevicePrimaryInts[slot];
        if (interrupt != INVALID_INT) {
            IrqTable[interrupt] = IRQ_VALID;
        } else {
            return STATUS_UNSUCCESSFUL;
        }
    } else {
        return STATUS_UNSUCCESSFUL;
    }

    HDBG(DBG_INTERRUPTS,
         HalpDebugPrint("HalpGetISAFixedPCIIrq: index = 0x%x \n",
                        PciSlot.u.bits.DeviceNumber););
/**
 * Helper function to handle the PCI device lookup.
 *
 * @returns NT status code.
 *
 * @param pBusNumber
 * @param pSlotNumber
 *
 */
static NTSTATUS vboxguestwinnt4FindPCIDevice(PULONG pBusNumber, PPCI_SLOT_NUMBER pSlotNumber)
{
    NTSTATUS rc;

    ULONG busNumber;
    ULONG deviceNumber;
    ULONG functionNumber;
    PCI_SLOT_NUMBER slotNumber;
    PCI_COMMON_CONFIG pciData;

    Log(("VBoxGuest::vboxguestwinnt4FindPCIDevice\n"));

    rc = STATUS_DEVICE_DOES_NOT_EXIST;
    slotNumber.u.AsULONG = 0;

    /* Scan each bus. */
    for (busNumber = 0; busNumber < PCI_MAX_BUSES; busNumber++)
    {
        /* Scan each device. */
        for (deviceNumber = 0; deviceNumber < PCI_MAX_DEVICES; deviceNumber++)
        {
            slotNumber.u.bits.DeviceNumber = deviceNumber;

            /* Scan each function (not really required...). */
            for (functionNumber = 0; functionNumber < PCI_MAX_FUNCTION; functionNumber++)
            {
                slotNumber.u.bits.FunctionNumber = functionNumber;

                /* Have a look at what's in this slot. */
                if (!HalGetBusData(PCIConfiguration, busNumber, slotNumber.u.AsULONG,
                                   &pciData, sizeof(ULONG)))
                {
                    /* No such bus, we're done with it. */
                    deviceNumber = PCI_MAX_DEVICES;
                    break;
                }

                if (pciData.VendorID == PCI_INVALID_VENDORID)
                {
                    /* We have to proceed to the next function. */
                    continue;
                }

                /* Check if it's another device. */
                if ((pciData.VendorID != VMMDEV_VENDORID) ||
                        (pciData.DeviceID != VMMDEV_DEVICEID))
                {
                    continue;
                }

                /* Hooray, we've found it! */
                Log(("VBoxGuest::vboxguestwinnt4FindPCIDevice: Device found!\n"));

                *pBusNumber = busNumber;
                *pSlotNumber = slotNumber;
                rc = STATUS_SUCCESS;
            }
        }
    }

    return rc;
}
Beispiel #7
0
static NTSTATUS
FdoEnumerateDevices(
  PDEVICE_OBJECT DeviceObject)
{
  PFDO_DEVICE_EXTENSION DeviceExtension;
  PCI_COMMON_CONFIG PciConfig;
  PPCI_DEVICE Device;
  PCI_SLOT_NUMBER SlotNumber;
  ULONG DeviceNumber;
  ULONG FunctionNumber;
  ULONG Size;
  NTSTATUS Status;

  DPRINT("Called\n");

  DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

  DeviceExtension->DeviceListCount = 0;

  /* Enumerate devices on the PCI bus */
  SlotNumber.u.AsULONG = 0;
  for (DeviceNumber = 0; DeviceNumber < PCI_MAX_DEVICES; DeviceNumber++)
  {
    SlotNumber.u.bits.DeviceNumber = DeviceNumber;
    for (FunctionNumber = 0; FunctionNumber < PCI_MAX_FUNCTION; FunctionNumber++)
    {
      SlotNumber.u.bits.FunctionNumber = FunctionNumber;

      DPRINT("Bus %1lu  Device %2lu  Func %1lu\n",
        DeviceExtension->BusNumber,
        DeviceNumber,
        FunctionNumber);

      RtlZeroMemory(&PciConfig,
                    sizeof(PCI_COMMON_CONFIG));

      Size = HalGetBusData(PCIConfiguration,
                           DeviceExtension->BusNumber,
                           SlotNumber.u.AsULONG,
                           &PciConfig,
                           PCI_COMMON_HDR_LENGTH);
      DPRINT("Size %lu\n", Size);
      if (Size < PCI_COMMON_HDR_LENGTH)
      {
        if (FunctionNumber == 0)
        {
          break;
        }
        else
        {
          continue;
        }
      }

      DPRINT("Bus %1lu  Device %2lu  Func %1lu  VenID 0x%04hx  DevID 0x%04hx\n",
        DeviceExtension->BusNumber,
        DeviceNumber,
        FunctionNumber,
        PciConfig.VendorID,
        PciConfig.DeviceID);

      Status = FdoLocateChildDevice(&Device, DeviceExtension, SlotNumber, &PciConfig);
      if (!NT_SUCCESS(Status))
      {
        Device = (PPCI_DEVICE)ExAllocatePoolWithTag(NonPagedPool, sizeof(PCI_DEVICE),TAG_PCI);
        if (!Device)
        {
          /* FIXME: Cleanup resources for already discovered devices */
          return STATUS_INSUFFICIENT_RESOURCES;
        }

        RtlZeroMemory(Device,
                      sizeof(PCI_DEVICE));

        Device->BusNumber = DeviceExtension->BusNumber;

        RtlCopyMemory(&Device->SlotNumber,
                      &SlotNumber,
                      sizeof(PCI_SLOT_NUMBER));

        RtlCopyMemory(&Device->PciConfig,
                      &PciConfig,
                      sizeof(PCI_COMMON_CONFIG));

        ExInterlockedInsertTailList(
          &DeviceExtension->DeviceListHead,
          &Device->ListEntry,
          &DeviceExtension->DeviceListLock);
      }

      DeviceExtension->DeviceListCount++;

      /* Skip to next device if the current one is not a multifunction device */
      if ((FunctionNumber == 0) &&
          ((PciConfig.HeaderType & 0x80) == 0))
      {
        break;
      }
    }
  }

  DPRINT("Done\n");

  return STATUS_SUCCESS;
}
Beispiel #8
0
VOID HalpInitializeX86DisplayAdapter()

/*++

Routine Description:

    This function performs the initialization required to use an X86 emulator.
    If a firmware level X86 emulator is available, then that emulator will be used.  
    Otherwise, we will default to using the emulator built into the HAL if it is 
    available.

Arguments:

    None.

Return Value:

    None.

--*/

{
    XM86_CONTEXT Context;
    PSYSTEM_PARAMETER_BLOCK SystemParameterBlock = SYSTEM_BLOCK;
    PCI_SLOT_NUMBER     SlotNumber;
    PPCI_COMMON_CONFIG  PciData;
    UCHAR               buffer[PCI_COMMON_HDR_LENGTH];
    ULONG               PciLength;
    ULONG               PciBus;
    ULONG               PciDevice;
    ULONG               PciFunction;
    ULONG               PciVideoAdapterFound;

    //
    // If EISA I/O Ports or EISA Memory could not be mapped, then leave the
    // X86 BIOS Emulator disabled.
    //

    if (HalpEisaControlBase[0] == NULL || HalpEisaMemoryBase[0] == NULL) {
        return;
    }

    //
    // If Firmware level X86 Bios Emulator exists, then use that instead of the
    // one built into the HAL.
    //

    if ((SystemParameterBlock->VendorVectorLength/4) >= 34) {

        VendorX86ExecuteInt =
            *(PVENDOR_EXECUTE_INT *)((ULONG)(SystemParameterBlock->VendorVector) + 34*4);

        if (VendorX86ExecuteInt != NULL) {
            HalpX86BiosInitialized     = TRUE;
            HalpUseFirmwareX86Emulator = TRUE;
            HalpEnableInt10Calls       = TRUE;
            return;
        }
    }

#ifdef ENABLE_HAL_X86_EMULATOR

    //
    // Attempt to initialize the Display Adapter by executing the Display Adapters
    // initialization code in its BIOS.  The standard for PC video adapters is for
    // the BIOS to reside at 0xC000:0000 on the ISA bus.
    //

    PciVideoAdapterFound = FALSE;
    PciData = (PPCI_COMMON_CONFIG) buffer;
    PciBus      = 0;
    do {
      for(PciDevice=0;PciDevice < PCI_MAX_DEVICES;PciDevice++) {
          PciFunction = 0;
          do {
              SlotNumber.u.AsULONG = 0;
              SlotNumber.u.bits.DeviceNumber = PciDevice;
              SlotNumber.u.bits.FunctionNumber = PciFunction;

              PciLength = HalGetBusData (
                              PCIConfiguration,
                              PciBus,
                              SlotNumber.u.AsULONG,
                              PciData,
                              PCI_COMMON_HDR_LENGTH
                              );

              if (PciLength==0) {
                  break;
              }

              if (PciData->VendorID == PCI_INVALID_VENDORID) {
                  break;
              }

              if ( (PciData->BaseClass == 0x00 && PciData->SubClass == 0x01) ||
                   (PciData->BaseClass == 0x03 && PciData->SubClass == 0x00)    ) {
                  PciVideoAdapterFound = TRUE;
                  break;
              }
              if (PciFunction == 0 && ((PciData->HeaderType & 0x80)==0)) {
                  break;
              }
              PciFunction++;
          } while (PciFunction < PCI_MAX_FUNCTION);
          if (PciLength==0 || PciVideoAdapterFound) {
              break;
          }
      }
      if (PciLength==0 || PciVideoAdapterFound) {
          break;
      }
      PciBus++;
    } while (PciLength!=0);

    if (PciVideoAdapterFound) {
        if (PciBus < HalpSecondPciBridgeBusNumber) {
            x86BiosInitializeBios(HalpPciControlBase[0], HalpPciMemoryBase[0]);
        } else {
            x86BiosInitializeBios(HalpPciControlBase[1], HalpPciMemoryBase[1]);
        }
        Context.Eax = (PciBus<<8) | (PciDevice<<3) | PciFunction;
    } else {
        x86BiosInitializeBios(HalpEisaControlBase[0], HalpEisaMemoryBase[0]);
        Context.Eax = 0;
    }
    HalpX86BiosInitialized = TRUE;

    Context.Ecx = 0;
    Context.Edx = 0;
    Context.Ebx = 0;
    Context.Ebp = 0;
    Context.Esi = 0;
    Context.Edi = 0;

    if (x86BiosInitializeAdapter(0xc0000, &Context, NULL, NULL) != XM_SUCCESS) {
        HalpEnableInt10Calls = FALSE;
        return;
    }

    HalpEnableInt10Calls = TRUE;

#endif
}