⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcicfg.cpp

📁 这是运行在windows ce 4.2 版本下的关于硬盘加载的驱动程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
#include <windows.h>
#include <nkintr.h>
#include <ceddk.h>
#include <cardserv.h>
#include <cardapi.h>
#include <tuple.h>
#include <devload.h>
#include <PCIbus.h>
#include <debug.h>

//
// Function prototypes
//
static BOOL ConfigRsrc(
    PPCI_DEV_INFO pInfo,
    PPCI_RSRC pMemHead,
    PPCI_RSRC pIoHead,
    DWORD *pMemSize,
    DWORD *pIoSize 
    );

static BOOL ConfigSize(
    PPCI_DEV_INFO pInfo 
    );

static BOOL ConfigInit(
    PPCI_DEV_INFO pInfo 
    );


__inline static DWORD
PCIConfig_Read(
    ULONG BusNumber,
    ULONG Device,
    ULONG Function,
    ULONG Offset
    );


__inline static void
PCIConfig_Write(
    ULONG BusNumber,
    ULONG Device,
    ULONG Function,
    ULONG Offset,
    ULONG Value,
    ULONG Size = sizeof(DWORD)
    );



//
// DeviceConfig
//
EXTERN_C DWORD GenericConfig(
    DWORD Command, 
    PPCI_DEV_INFO pInfo,
    PPCI_RSRC pRsrc1,
    PPCI_RSRC pRsrc2,
    DWORD *pMemSize,
    DWORD *pIoSize
    )
{
    DEBUGMSG(1, (L"ATAPI:PCIConfig!DeviceConfig+(%d)\r\n", Command));

    switch (Command) {
    case PCIBUS_CONFIG_RSRC:
        if (ConfigRsrc(pInfo, pRsrc1, pRsrc2, pMemSize, pIoSize)) {
            return ERROR_SUCCESS;
        } else {
            return ERROR_GEN_FAILURE;
        }

    case PCIBUS_CONFIG_SET:
        return ERROR_NOT_SUPPORTED;
        
    case PCIBUS_CONFIG_SIZE:
        if (ConfigSize(pInfo)) {
            return ERROR_SUCCESS;
        } else {
            return ERROR_GEN_FAILURE;
        }

    case PCIBUS_CONFIG_INIT:
        if (ConfigInit(pInfo)) {
            return ERROR_SUCCESS;
        } else {
            return ERROR_GEN_FAILURE;
        }

    default:
        break;
    }

    DEBUGMSG(1, (L"ATAPI:PCIConfig!DeviceConfig-: ERROR: Command %d not recognized\r\n", Command));
    
    return ERROR_BAD_COMMAND;
}


// Inline functions
__inline static DWORD
PCIConfig_Read(
    ULONG BusNumber,
    ULONG Device,
    ULONG Function,
    ULONG Offset
    )
{
    ULONG RetVal = FALSE;
    PCI_SLOT_NUMBER SlotNumber;

    SlotNumber.u.AsULONG = 0;
    SlotNumber.u.bits.DeviceNumber = Device;
    SlotNumber.u.bits.FunctionNumber = Function;
    
    HalGetBusDataByOffset(PCIConfiguration, BusNumber, SlotNumber.u.AsULONG, &RetVal, Offset, sizeof(RetVal));

    return RetVal;
}

// Inline functions
__inline static BYTE
PCIConfig_ReadByte(
    ULONG BusNumber,
    ULONG Device,
    ULONG Function,
    ULONG Offset
    )
{
    BYTE  RetVal = FALSE;
    PCI_SLOT_NUMBER SlotNumber;

    SlotNumber.u.AsULONG = 0;
    SlotNumber.u.bits.DeviceNumber = Device;
    SlotNumber.u.bits.FunctionNumber = Function;
    
    HalGetBusDataByOffset(PCIConfiguration, BusNumber, SlotNumber.u.AsULONG, &RetVal, Offset, sizeof(RetVal));

    return RetVal;
}



__inline static void
PCIConfig_Write(
    ULONG BusNumber,
    ULONG Device,
    ULONG Function,
    ULONG Offset,
    ULONG Value,
    ULONG Size
    )
{
    PCI_SLOT_NUMBER SlotNumber;

    SlotNumber.u.AsULONG = 0;
    SlotNumber.u.bits.DeviceNumber = Device;
    SlotNumber.u.bits.FunctionNumber = Function;

    HalSetBusDataByOffset(PCIConfiguration, BusNumber, SlotNumber.u.AsULONG, &Value, Offset, Size);
}


__inline static void
InsertRsrc(
    PPCI_RSRC Ptr, 
    PPCI_RSRC Rsrc
    ) 
{
    Rsrc->Next = Ptr;
    Rsrc->Prev = Ptr->Prev;
    Ptr->Prev->Next = Rsrc;
    Ptr->Prev = Rsrc;
}


__inline static void
RemoveRsrc(
    PPCI_RSRC Rsrc
    )
{
    Rsrc->Prev->Next = Rsrc->Next;
    Rsrc->Next->Prev = Rsrc->Prev;
}
void
PCIRsrc_Add(
    PPCI_RSRC Head,
    PPCI_RSRC Rsrc
    )
{
    PPCI_RSRC Ptr;

    // Find place to insert Rsrc.  Sort first on Placed then Size.
    for (Ptr = Head->Next; Ptr != Head; Ptr = Ptr->Next) {
        if (Rsrc->Placed) {
            if (!Ptr->Placed) break;

            if (Rsrc->Size > Ptr->Size) break;
        } else {
            if (Ptr->Placed) continue;

            if (Rsrc->Size > Ptr->Size) break;
        }
    }
            
    // Insert Rsrc node
    InsertRsrc(Ptr, Rsrc); 
}


PPCI_RSRC
PCIRsrc_New(
    DWORD Bus,
    DWORD Device,
    DWORD Function,
    DWORD Offset,
    DWORD Base,
    DWORD Size,
    BOOL Bridge,
    DWORD SecBus,
    BOOL Placed,
    PPCI_CFG_INFO ConfigInfo
    )
{
    PPCI_RSRC Rsrc;

    Rsrc = (PPCI_RSRC)LocalAlloc(0, sizeof(PCI_RSRC));

    if (!Rsrc) return NULL;
    
    Rsrc->Bus = Bus;
    Rsrc->Device = Device;
    Rsrc->Function = Function;
    Rsrc->Offset = Offset;
    Rsrc->Base = Base;
    Rsrc->Size = Size;
    Rsrc->Bridge = Bridge;
    Rsrc->SecBus = SecBus;
    Rsrc->Placed = Placed;
    Rsrc->ConfigInfo = ConfigInfo;
    Rsrc->Next = Rsrc;
    Rsrc->Prev = Rsrc;

    return Rsrc;
}

//
// ConfigRsrc
//
static BOOL ConfigRsrc(
    PPCI_DEV_INFO pInfo,
    PPCI_RSRC pMemHead,
    PPCI_RSRC pIoHead,
    DWORD *pMemSize,
    DWORD *pIoSize   
    )
{
    DWORD NumberOfRegs;
    ULONG Offset;
    ULONG i;
    ULONG BaseAddress;
    ULONG Size;
    ULONG Type;
    DWORD Reg;
    BOOL SizeFound;
    DWORD IoIndex = 0;
    DWORD MemIndex = 0;
    DWORD Bus = pInfo->Bus;
    DWORD Device = pInfo->Device;
    DWORD Function = pInfo->Function;
    PPCI_COMMON_CONFIG pCfg = pInfo->Cfg;

    DEBUGMSG(ZONE_PCI | ZONE_INIT, (L"ATAPI:PCIConfig!ConfigRsrc+(Bus %d, Device %d, Function %d)\r\n",
        Bus, Device, Function));

    // Determine number of BARs to examine from header type
    switch (pCfg->HeaderType & ~PCI_MULTIFUNCTION) {
    case PCI_DEVICE_TYPE:
        NumberOfRegs = PCI_TYPE0_ADDRESSES;
        break;

    case PCI_BRIDGE_TYPE:
        NumberOfRegs = PCI_TYPE1_ADDRESSES;
        break;

    case PCI_CARDBUS_TYPE:
        NumberOfRegs = PCI_TYPE2_ADDRESSES;
        break;

    default:
        return FALSE;
    }
    
    for (i = 0, Offset = 0x10; i < NumberOfRegs; i++, Offset += 4) {
        // Get base address register value
        Reg = pCfg->u.type0.BaseAddresses[i];
        Type = Reg & PCI_ADDRESS_IO_SPACE;
        
        // Probe hardware for size
        PCIConfig_Write(Bus,Device,Function,Offset,0xFFFFFFFF);
        BaseAddress = PCIConfig_Read(Bus,Device,Function,Offset);
        PCIConfig_Write(Bus, Device, Function, Offset, Reg);

        if (Type) {
            // IO space
            // Re-adjust BaseAddress if upper 16-bits are 0 (allowable in PCI 2.2 spec)
            if (((BaseAddress & PCI_ADDRESS_IO_ADDRESS_MASK) != 0) && ((BaseAddress & 0xFFFF0000) == 0)) {
                BaseAddress |= 0xFFFF0000;
            }
            
            Size = ~(BaseAddress & PCI_ADDRESS_IO_ADDRESS_MASK);
            Reg &= PCI_ADDRESS_IO_ADDRESS_MASK;
        } else {
            // Memory space
            if ((Reg & PCI_ADDRESS_MEMORY_TYPE_MASK) == PCI_TYPE_20BIT) {
                // PCI 2.2 spec no longer supports this type of memory addressing
                DEBUGMSG(ZONE_ERROR, (L"ATAPI:PCIConfig!ConfigRsrc: 20-bit addressing not supported\r\n"));
                return FALSE;
            }
            
            // Re-adjust BaseAddress if upper 16-bits are 0 (allowed by PCI 2.2 spec)
            if (((BaseAddress & PCI_ADDRESS_MEMORY_ADDRESS_MASK) != 0) && ((BaseAddress & 0xFFFF0000) == 0)) {
                BaseAddress |= 0xFFFF0000;
            }
            
            Size = ~(BaseAddress & PCI_ADDRESS_MEMORY_ADDRESS_MASK);
            Reg &= PCI_ADDRESS_MEMORY_ADDRESS_MASK;
        }

        // Check that the register has a valid format; it should have consecutive high 1's and consecutive low 0's
        SizeFound = (BaseAddress != 0) && (BaseAddress != 0xFFFFFFFF) && (((Size + 1) & Size) == 0);

        Size +=1;

        if (SizeFound) {
            PPCI_RSRC Rsrc = PCIRsrc_New(Bus, Device, Function, Offset, Reg, Size, FALSE, 0, FALSE, pInfo->ConfigInfo);

            if (!Rsrc) {
                DEBUGMSG(ZONE_PCI | ZONE_ERROR, (L"ATAPI:PCIConfig!ConfigRsrc: Failed local alloc of Rsrc\r\n"));
                return FALSE;
            }

            if (Type == PCI_ADDRESS_IO_SPACE) {
                *pIoSize += Size;
                PCIRsrc_Add(pIoHead, Rsrc);
            } else {
                *pMemSize += Size;
                PCIRsrc_Add(pMemHead, Rsrc);
            }

            DEBUGMSG(ZONE_PCI | ZONE_INIT, (L"ATAPI:PCIConfig!ConfigRsrc: BAR(%d/%d/%d): Offset 0x%x, Type %s, Size 0x%X\r\n",
                Bus, Device, Function, Offset, (Type == PCI_ADDRESS_IO_SPACE) ? TEXT("I/O") : TEXT("Memory"), Size));
        } else {
            // Some devices have invalid BARs before valid ones (even though the spec says you can't).  Skip invalid BARs.
            continue;
        }

        // check for 64 bit device (memory only)
        if ((Type == PCI_ADDRESS_MEMORY_SPACE) && ((Reg & PCI_ADDRESS_MEMORY_TYPE_MASK) == PCI_TYPE_64BIT)) {
            // 64 bit device - BAR is twice as wide - zero out high part

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -