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

📄 pcicfg.c

📁 WINCE5.0操作系统下的PCI总线驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
//
// 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.
//

//
// Routines to configure and initialize the PCIbus
//
#include <windows.h>
#include <ceddk.h>
#include <devload.h>
#include <PCIbus.h>
#include "PCIcfg.h"
#include "PCIproto.h"
#include "PCIdbg.h"

#pragma warning (disable: 4002)

//
// Resource lists for Memory and I/O
//
PPCI_RSRC g_MemHead, g_IoHead,g_PrefetchMemHead;
DWORD       g_dwBusNumberBase,g_dwBusNumberLength;

//   
// Function prototypes
//
static BOOL
PCICfgBus(
    PPCI_DEV_INFO pBusInfo,
    ULONG Bus,
    PULONG pSubordinateBus,
    PULONG pMemSize,
    PULONG pIoSize,
    PULONG pPrefetchMemSize
    );

static BOOL
PCICfgDevice(
    PPCI_DEV_INFO pBusInfo,
    ULONG Bus,
    ULONG Device,
    ULONG Function,
    PPCI_COMMON_CONFIG pCfg,
    PULONG pMemSize,
    PULONG pIoSize,
    PULONG pPrefetchMemSize
    );

static BOOL
PCICfgBridge(
    PPCI_DEV_INFO pBusInfo,
    ULONG Bus,
    ULONG Device,
    ULONG Function,
    PPCI_COMMON_CONFIG pCfg,
    PULONG pSubordinateBus,
    PULONG pMemSize,
    PULONG pIoSize,
    PULONG pPrefetchMemSize
    );

static BOOL
PCICfgCardBusBridge(
    PPCI_DEV_INFO pBusInfo,
    ULONG Bus,
    ULONG Device,
    ULONG Function,
    PPCI_COMMON_CONFIG pCfg,
    PULONG pSubordinateBus,
    PULONG pMemSize,
    PULONG pIoSize
    );

static BOOL
PCICfgCheckBARs(
    PPCI_DEV_INFO pInfo,
    PULONG pMemSize,
    PULONG pIoSize,
    PULONG pPrefetchMemSize
    );

static BOOL
PCICfgAllocateIoSpace(
    DWORD Bus,
    DWORD Base,
    DWORD Size
    );

static BOOL
PCICfgAllocateMemSpace(
    DWORD Bus,
    DWORD Base,
    DWORD Size
    );

static BOOL
PCICfgAllocatePrefetchMemSpace(
    DWORD Bus,
    DWORD Base,
    DWORD Size
    );

static BOOL
PCICfgFindMatch(
    PPCI_DEV_INFO pInfo
    );

static BOOL
RequestIrq(
    PDEVICE_LOCATION pDevLoc,
    PDWORD pIrq
    );
//    
// Inline functions
//

//
// Read a DWORD from a device's configuration space
//
__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;
}


//
// Write a DWORD to a device's configuration space
//
__inline static void
PCIConfig_Write(
    ULONG BusNumber,
    ULONG Device,
    ULONG Function,
    ULONG Offset,
    ULONG Value
    )
{
    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, sizeof(Value));
}


//
// Top-level PCIbus initialization and configuration routine
//
BOOL
PCICfg(
    PPCI_DEV_INFO_EX pBusInfoEx
    )
{
    ULONG SubordinateBus = 0;
    ULONG MemSize = 0;
    ULONG IoSize = 0;
    ULONG PrefetchMem = 0;
    BOOL Status = TRUE;
    PPCI_DEV_INFO pBusInfo = &(pBusInfoEx->pciDevice);
        
    DEBUGMSG(ZONE_FUNCTION, (L"PCIBUS!PCICfg+(%s, BusNumberBase 0x%X, BusNumberLength 0x%X MemBase 0x%X, MemLen 0x%X, IoBase 0x%X, IoLen 0x%X)\r\n",
        pBusInfo->RegPath, pBusInfoEx->dwBusNumberBase, pBusInfoEx->dwBusNumberLength, pBusInfo->MemBase.Reg[0], pBusInfo->MemLen.Reg[0], pBusInfo->IoBase.Reg[0], pBusInfo->IoLen.Reg[0]));

    if (pBusInfoEx->PrefetchMemBase.Num!=0 && pBusInfoEx->PrefetchMemLen.Num!=0 ) {
        DEBUGMSG(ZONE_FUNCTION, (L"PCIBUS!PCICfg(%s, PrefetchMemBase 0x%X, PrefetchMemLen 0x%X)\r\n",
            pBusInfo->RegPath, pBusInfoEx->PrefetchMemBase.Reg[0], pBusInfoEx->PrefetchMemLen.Reg[0]));
    }
    else {
        DEBUGMSG(ZONE_FUNCTION, (L"PCIBUS!PCICfg : No Prefetchable Memory Support\r\n"));
    }
    g_MemHead = g_PrefetchMemHead = g_IoHead = NULL; 
    g_dwBusNumberBase = pBusInfoEx->dwBusNumberBase;
    g_dwBusNumberLength = pBusInfoEx->dwBusNumberLength;
    SubordinateBus = pBusInfoEx->dwBusNumberBase;
    
    // Initialize resource lists
    if (!(g_MemHead = PCIRsrc_New(0, 0, 0, 0, pBusInfo->MemBase.Reg[0], pBusInfo->MemLen.Reg[0], TRUE, 0, TRUE, NULL))) {
        DEBUGMSG(ZONE_ERROR, (L"PCIBUS!PCICfg: Failed local alloc of g_MemHead)\r\n"));
        return FALSE;
    }
    
    if (!(g_IoHead = PCIRsrc_New(0, 0, 0, 0, pBusInfo->IoBase.Reg[0], pBusInfo->IoLen.Reg[0], TRUE, 0, TRUE, NULL))) {
        DEBUGMSG(ZONE_ERROR, (L"PCIBUS!PCICfg: Failed local alloc of g_IoHead)\r\n"));
        PCIRsrc_DelList(g_MemHead);
        return FALSE;
    }
    if ( pBusInfoEx->PrefetchMemBase.Num!=0 && pBusInfoEx->PrefetchMemLen.Num!=0 && 
            !(g_PrefetchMemHead = PCIRsrc_New(0, 0, 0, 0, pBusInfoEx->PrefetchMemBase.Reg[0], pBusInfoEx->PrefetchMemLen.Reg[0], TRUE, 0, TRUE, NULL))) {
        DEBUGMSG(ZONE_WARNING, (L"PCIBUS!PCICfg: No Prefetchable Memory Support!)\r\n"));
    }
    if (!PCICfgBus(pBusInfo, 0, &SubordinateBus, &MemSize, &IoSize,g_PrefetchMemHead!=NULL?&PrefetchMem:NULL)) {
        DEBUGMSG(ZONE_ERROR, (L"PCIBUS!PCICfg: Failed PCICfgBus( ) call. At least one device does not configure properly\r\n"));
    }

#ifdef DEBUG
    DEBUGMSG(ZONE_RSRC, (L"Mem List:\r\n"));
    if (ZONE_RSRC) PCIRsrc_PrintList(g_MemHead);
    DEBUGMSG(ZONE_RSRC, (L"I/O List:\r\n"));
    if (ZONE_RSRC) PCIRsrc_PrintList(g_IoHead);
    DEBUGMSG(ZONE_RSRC, (L"Prefetch Mem List:\r\n"));
    if (ZONE_RSRC && g_PrefetchMemHead) PCIRsrc_PrintList(g_PrefetchMemHead);
#endif
    
    if (MemSize > pBusInfo->MemLen.Reg[0]) {
        RETAILMSG(1, (L"PCIBUS!PCICfg: Not enough memory space allocated for PCI Bus, PCIbus driver terminating.\r\n"));
        RETAILMSG(1, (L"PCIBUS!PCICfg: Host Bridge window size: 0x%X, requested: 0x%X\r\n", pBusInfo->MemLen.Reg[0], MemSize));
        RETAILMSG(1, (L"PCIBUS!PCICfg: List of requested memory resources:\r\n"));
        PCIRsrc_PrintList(g_MemHead);
        Status = FALSE;
        goto PCICfg_Exit;
    }
     
    if (IoSize > pBusInfo->IoLen.Reg[0]) {
        RETAILMSG(1, (L"PCIBUS!PCICfg: Not enough I/O space allocated for PCI Bus, PCIbus driver terminating.\r\n"));
        RETAILMSG(1, (L"PCIBUS!PCICfg: Host Bridge window size: 0x%X, requested: 0x%X\r\n", pBusInfo->IoLen.Reg[0], IoSize));
        RETAILMSG(1, (L"PCIBUS!PCICfg: List of requested I/O resources:\r\n"));
        PCIRsrc_PrintList(g_IoHead);
        Status = FALSE;
        goto PCICfg_Exit;
    }

    if (g_PrefetchMemHead && PrefetchMem > pBusInfoEx->PrefetchMemLen.Reg[0]) {
        RETAILMSG(1, (L"PCIBUS!PCICfg: Not enough Prefetch space allocated for PCI Bus, PCIbus driver terminating.\r\n"));
        RETAILMSG(1, (L"PCIBUS!PCICfg: Host Bridge window size: 0x%X, requested: 0x%X\r\n", pBusInfoEx->PrefetchMemLen.Reg[0], PrefetchMem));
        RETAILMSG(1, (L"PCIBUS!PCICfg: List of requested prefetch memory resources:\r\n"));
        PCIRsrc_PrintList(g_PrefetchMemHead);
        Status = FALSE;
        goto PCICfg_Exit;
    }
        
    if (!PCICfgAllocateMemSpace(0, pBusInfo->MemBase.Reg[0], pBusInfo->MemLen.Reg[0])) {
        RETAILMSG(1, (L"PCIBUS!PCICfg: Failure allocating PCI memory space, PCIbus driver terminating.\r\n"));
        Status = FALSE;
        goto PCICfg_Exit;
    }
    
    if (!PCICfgAllocateIoSpace(0, pBusInfo->IoBase.Reg[0], pBusInfo->IoLen.Reg[0])) {
        RETAILMSG(1, (L"PCIBUS!PCICfg: Failure allocating PCI I/O space, PCIbus driver terminating.\r\n"));
        Status = FALSE;
        goto PCICfg_Exit;
    }

    if (g_PrefetchMemHead && !PCICfgAllocatePrefetchMemSpace(0, pBusInfoEx->PrefetchMemBase.Reg[0], pBusInfoEx->PrefetchMemLen.Reg[0])) {
        RETAILMSG(1, (L"PCIBUS!PCICfg: Failure allocating Prefetchable Memory space, PCIbus driver terminating.\r\n"));
        Status = FALSE;
        goto PCICfg_Exit;
    }

PCICfg_Exit:
    UnloadConfigEntrys();           // Unload any configuration DLLs that were loaded
    PCIRsrc_DelList(g_MemHead);
    PCIRsrc_DelList(g_IoHead);
    if (g_PrefetchMemHead)
        PCIRsrc_DelList(g_PrefetchMemHead);
    g_MemHead = g_IoHead = g_PrefetchMemHead = NULL;
        
    DEBUGMSG(ZONE_FUNCTION, (L"PCIBUS!PCICfg-\r\n"));
    
    return Status;
}


//
// Initialize and configure PCIbus
//
static BOOL
PCICfgBus(
    PPCI_DEV_INFO pBusInfo,
    ULONG Bus,
    PULONG pSubordinateBus,
    PULONG pMemSize,
    PULONG pIoSize ,
    PULONG pPrefetchMemSize
    )
{
    DWORD Device;
    DWORD Function;
    DWORD Length;

    PCI_SLOT_NUMBER SlotNumber;
    PCI_COMMON_CONFIG Cfg;

    BOOL RetVal = TRUE;

    DEBUGMSG(ZONE_FUNCTION, (L"PCIBUS!PCICfgBus+(Bus %d)\r\n", Bus));
    if (Bus<g_dwBusNumberBase || Bus>=g_dwBusNumberBase + g_dwBusNumberLength) {
        DEBUGMSG(ZONE_ERROR, (L"PCIBUS!PCICfgBus: Invalid BusNumber 0x%X, BusNumberBase 0x%X, BusNumberLength 0x%X\r\n",
            Bus, g_dwBusNumberBase, g_dwBusNumberLength));
        return FALSE;
    }

    SlotNumber.u.AsULONG = 0;
    
    // Loop through all device numbers
    for (Device = 0; Device < PCI_MAX_DEVICES; Device++) {
        SlotNumber.u.bits.DeviceNumber = Device;
        
        // Loop through all functions  
        for (Function = 0; Function < PCI_MAX_FUNCTION; Function++) {
            Cfg.VendorID = PCI_INVALID_VENDORID;
            Cfg.DeviceID = PCI_INVALID_DEVICEID;
            Cfg.HeaderType = PCI_DEVICE_TYPE;
            
            SlotNumber.u.bits.FunctionNumber = Function;

⌨️ 快捷键说明

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