Exemplo n.º 1
0
VOID
NTAPI
PPBridge_SaveLimits(IN PPCI_CONFIGURATOR_CONTEXT Context)
{
    PIO_RESOURCE_DESCRIPTOR Limit;
    PULONG BarArray;
    PHYSICAL_ADDRESS MemoryLimit;
    ULONG i;
    PPCI_COMMON_HEADER Working;
    PPCI_PDO_EXTENSION PdoExtension;

    /* Get the pointers from the context */
    Working = Context->PciData;
    PdoExtension = Context->PdoExtension;

    /* Scan the BARs into the limit descriptors */
    BarArray = Working->u.type1.BaseAddresses;
    Limit = PdoExtension->Resources->Limit;

    /* First of all, loop all the BARs */
    for (i = 0; i < PCI_TYPE1_ADDRESSES; i++)
    {
        /* Create a descriptor for their limits */
        if (PciCreateIoDescriptorFromBarLimit(&Limit[i], &BarArray[i], FALSE))
        {
            /* This was a 64-bit descriptor, make sure there's space */
            ASSERT((i + 1) < PCI_TYPE1_ADDRESSES);

            /* Skip the next descriptor since this one is double sized */
            i++;
            Limit[i].Type = CmResourceTypeNull;
        }
    }

    /* Check if this is a subtractive decode bridge */
    if (PciBridgeIsSubtractiveDecode(Context))
    {
        /* This bridge is subtractive */
        PdoExtension->Dependent.type1.SubtractiveDecode = TRUE;

        /* Subtractive bridges cannot use legacy ISA or VGA functionality */
        PdoExtension->Dependent.type1.IsaBitSet = FALSE;
        PdoExtension->Dependent.type1.VgaBitSet = FALSE;
    }

    /* For normal decode bridges, we'll need to find the bridge limits too */
    if (!PdoExtension->Dependent.type1.SubtractiveDecode)
    {
        /* Loop the descriptors that are left, to store the bridge limits */
        for (i = PCI_TYPE1_ADDRESSES; i < 5; i++)
        {
            /* No 64-bit memory addresses, and set the address to 0 to begin */
            MemoryLimit.HighPart = 0;
            (&Limit[i])->u.Port.MinimumAddress.QuadPart = 0;

            /* Are we getting the I/O limit? */
            if (i == 2)
            {
                /* There should be one, get it */
                ASSERT(Working->u.type1.IOLimit != 0);
                ASSERT((Working->u.type1.IOLimit & 0x0E) == 0);
                MemoryLimit.LowPart = PciBridgeIoLimit(Working);

                /* Build a descriptor for this limit */
                (&Limit[i])->Type = CmResourceTypePort;
                (&Limit[i])->Flags = CM_RESOURCE_PORT_WINDOW_DECODE |
                                     CM_RESOURCE_PORT_POSITIVE_DECODE;
                (&Limit[i])->u.Port.Alignment = 0x1000;
                (&Limit[i])->u.Port.MinimumAddress.QuadPart = 0;
                (&Limit[i])->u.Port.MaximumAddress = MemoryLimit;
                (&Limit[i])->u.Port.Length = 0;
            }
            else if (i == 3)
            {
                /* There should be a valid memory limit, get it */
                ASSERT((Working->u.type1.MemoryLimit & 0xF) == 0);
                MemoryLimit.LowPart = PciBridgeMemoryLimit(Working);

                /* Build the descriptor for it */
                (&Limit[i])->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
                (&Limit[i])->Type = CmResourceTypeMemory;
                (&Limit[i])->u.Memory.Alignment = 0x100000;
                (&Limit[i])->u.Memory.MinimumAddress.QuadPart = 0;
                (&Limit[i])->u.Memory.MaximumAddress = MemoryLimit;
                (&Limit[i])->u.Memory.Length = 0;
            }
            else if (Working->u.type1.PrefetchLimit)
            {
                /* Get the prefetch memory limit, if there is one */
                MemoryLimit = PciBridgePrefetchMemoryLimit(Working);

                /* Write out the descriptor for it */
                (&Limit[i])->Flags = CM_RESOURCE_MEMORY_PREFETCHABLE;
                (&Limit[i])->Type = CmResourceTypeMemory;
                (&Limit[i])->u.Memory.Alignment = 0x100000;
                (&Limit[i])->u.Memory.MinimumAddress.QuadPart = 0;
                (&Limit[i])->u.Memory.MaximumAddress = MemoryLimit;
                (&Limit[i])->u.Memory.Length = 0;
            }
            else
            {
                /* Blank descriptor */
                (&Limit[i])->Type = CmResourceTypeNull;
            }
        }
    }

    /* Does the ROM have its own BAR? */
    if (Working->u.type1.ROMBaseAddress & PCI_ROMADDRESS_ENABLED)
    {
        /* Build a limit for it as well */
        PciCreateIoDescriptorFromBarLimit(&Limit[i],
                                          &Working->u.type1.ROMBaseAddress,
                                          TRUE);
    }
}
Exemplo n.º 2
0
VOID
NTAPI
Device_SaveLimits(IN PPCI_CONFIGURATOR_CONTEXT Context)
{
    PPCI_COMMON_HEADER Current, PciData;
    PPCI_PDO_EXTENSION PdoExtension;
    PULONG BarArray;
    PIO_RESOURCE_DESCRIPTOR Limit;
    ULONG i;

    /* Get pointers from the context */
    PdoExtension = Context->PdoExtension;
    Current = Context->Current;
    PciData = Context->PciData;

    /* And get the array of bARs */
    BarArray = PciData->u.type0.BaseAddresses;

    /* First, check for IDE controllers that are not in native mode */
    if ((PdoExtension->BaseClass == PCI_CLASS_MASS_STORAGE_CTLR) &&
        (PdoExtension->SubClass == PCI_SUBCLASS_MSC_IDE_CTLR) &&
        (PdoExtension->ProgIf & 5) != 5)
    {
        /* They should not be using any non-legacy resources */
        BarArray[0] = 0;
        BarArray[1] = 0;
        BarArray[2] = 0;
        BarArray[3] = 0;
    }
    else if ((PdoExtension->VendorId == 0x5333) &&
             ((PdoExtension->DeviceId == 0x88F0) ||
              (PdoExtension->DeviceId == 0x8880)))
    {
        /*
         * The problem is caused by the S3 Vision 968/868 video controller which
         * is used on the Diamond Stealth 64 Video 3000 series, Number Nine 9FX
         * motion 771, and other popular video cards, all containing a memory bug.
         * The 968/868 claims to require 32 MB of memory, but it actually decodes
         * 64 MB of memory.
         */
        for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
        {
            /* Find its 32MB RAM BAR */
            if (BarArray[i] == 0xFE000000)
            {
                /* Increase it to 64MB to make sure nobody touches the buffer */
                BarArray[i] = 0xFC000000;
                DPRINT1("PCI - Adjusted broken S3 requirement from 32MB to 64MB\n");
            }
        }
    }

    /* Check for Cirrus Logic GD5430/5440 cards */
    if ((PdoExtension->VendorId == 0x1013) && (PdoExtension->DeviceId == 0xA0))
    {
        /* Check for the I/O port requirement */
        if (BarArray[1] == 0xFC01)
        {
            /* Check for completely bogus BAR */
            if (Current->u.type0.BaseAddresses[1] == 1)
            {
                /* Ignore it */
                BarArray[1] = 0;
                DPRINT1("PCI - Ignored Cirrus GD54xx broken IO requirement (400 ports)\n");
            }
            else
            {
                /* Otherwise, this BAR seems okay */
                DPRINT1("PCI - Cirrus GD54xx 400 port IO requirement has a valid setting (%08x)\n",
                        Current->u.type0.BaseAddresses[1]);
            }
        }
        else if (BarArray[1])
        {
            /* Strange, the I/O BAR was not found as expected (or at all) */
            DPRINT1("PCI - Warning Cirrus Adapter 101300a0 has unexpected resource requirement (%08x)\n",
                    BarArray[1]);
        }
    }

    /* Finally, process all the limit descriptors */
    Limit = PdoExtension->Resources->Limit;
    for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
    {
        /* And build them based on the BARs */
        if (PciCreateIoDescriptorFromBarLimit(&Limit[i], &BarArray[i], FALSE))
        {
            /* This function returns TRUE if the BAR was 64-bit, handle this */
            ASSERT((i + 1) < PCI_TYPE0_ADDRESSES);
            i++;
            Limit[i].Type = CmResourceTypeNull;
        }
    }

    /* Create the last descriptor based on the ROM address */
    PciCreateIoDescriptorFromBarLimit(&Limit[i],
                                      &PciData->u.type0.ROMBaseAddress,
                                      TRUE);
}