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

📄 pci.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
字号:
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 1995-2000  Microsoft Corporation

Module Name: pci.c

Abstract: Boot loader PCI access routines.

Functions:

    PCIReadBusData
    PCIInitBusInfo
    PCIGetBusDataByOffset
    PCISetBusDataByOffset

Notes:

--*/

#define WINCEMACRO 1

#include <windows.h>
#include <nkintr.h>
#include <ceddk.h>
#include "bldr.h"


// Preprocessor definitions.
//
#define MAX_SUPPORTED_PCI_BUS   8
#define PCI_TYPE1_ADDRESS       0x0CF8
#define PCI_TYPE1_DATA          0x0CFC


// Type definitions.
//
typedef struct  _TYPE1_PCI_ADDRESS {
    union {
        struct {
            ULONG   Reserved:2;
            ULONG   Register:6;
            ULONG   Function:3;
            ULONG   Device:5;
            ULONG   Bus:8;
            ULONG   Reserved2:7;
            ULONG   ConfigurationAccess:1;
        } bits;
        ULONG   AsULONG;
    } u;
} TYPE1_PCI_ADDRESS, *PTYPE1_PCI_ADDRESS;


// Global variables.
//
UCHAR   ucPCIMaxBus = 0;                // Highest Bus #+1, Inited to 0 on load
UCHAR   ucPCIMaxDeviceNumber = PCI_MAX_DEVICES;
UCHAR   ucPCIMaxDevice[MAX_SUPPORTED_PCI_BUS];  // For Each Bus, Highest Device Number + 1
BOOL    bPCIInitialized = FALSE;
const LPSTR BaseClass[] =
{
    TEXT("PRE_20"),
    TEXT("MASS_STORAGE_CTLR"),
    TEXT("NETWORK_CTLR"),
    TEXT("DISPLAY_CTLR"),
    TEXT("MULTIMEDIA_DEV"),
    TEXT("MEMORY_CTLR"),
    TEXT("BRIDGE_DEV"),
    TEXT("SIMPLE_COMMS_CTLR"),
    TEXT("BASE_SYSTEM_DEV"),
    TEXT("INPUT_DEV"),
    TEXT("DOCKING_STATION"),
    TEXT("PROCESSOR"),
    TEXT("SERIAL_BUS_CTLR")
};



ULONG
PCIReadBusData(
    IN ULONG BusNumber,
    IN ULONG DeviceNumber,
    IN ULONG FunctionNumber,
    IN PVOID Buffer,
    IN ULONG Offset,
    IN ULONG Length
    )
{
    PULONG              pBuffer;
    int                 registerOffset, endOffset;
    TYPE1_PCI_ADDRESS   type1Address;

    registerOffset = Offset / sizeof(ULONG);
    endOffset = registerOffset + (Length + sizeof(ULONG) - 1) / sizeof(ULONG);
    pBuffer = Buffer;

    type1Address.u.AsULONG = 0;
    type1Address.u.bits.ConfigurationAccess = 1;
    type1Address.u.bits.Bus = BusNumber;
    type1Address.u.bits.Device = DeviceNumber;
    type1Address.u.bits.Function = FunctionNumber;

    for ( ; registerOffset < endOffset; registerOffset++ ) {
        type1Address.u.bits.Register = registerOffset;
        _outpd((USHORT)PCI_TYPE1_ADDRESS, type1Address.u.AsULONG);
        *pBuffer++ = _inpd((USHORT)PCI_TYPE1_DATA);
    }

    return(Length);
}


void PCIInitBusInfo(void)
{

    if ( bPCIInitialized ) {
        return;
    }

    bPCIInitialized = TRUE;
    ucPCIMaxBus = 8;

    DEBUGMSG(ZONE_INFO, (TEXT("PCI devices = %d\r\n"), ucPCIMaxBus));

    if ( ucPCIMaxBus == 1 && ucPCIMaxDevice[0] == 0 ) {
        ucPCIMaxBus = (UCHAR)~0;
    }
}


ULONG
PCIGetBusDataByOffset(
                     IN ULONG BusNumber,
                     IN ULONG SlotNumber,
                     IN PVOID Buffer,
                     IN ULONG Offset,
                     IN ULONG Length
                     )
{
    PCI_SLOT_NUMBER     slotNumber;

    if ( bPCIInitialized == FALSE )
        PCIInitBusInfo();

    if ( ucPCIMaxBus == (UCHAR)~0U || BusNumber >= ucPCIMaxBus ) {
        RETAILMSG(1, (TEXT("Invalid bus number passed (%d >= %d)\r\n"),
                      BusNumber, ucPCIMaxBus));

        return(0);
    }

    slotNumber.u.AsULONG = SlotNumber;

    if ( slotNumber.u.bits.DeviceNumber >= ucPCIMaxDeviceNumber ) {
        return(0);
    }

    Length = PCIReadBusData(
                           BusNumber, slotNumber.u.bits.DeviceNumber,
                           slotNumber.u.bits.FunctionNumber, Buffer, Offset, Length);

    return(Length);
}


ULONG
PCISetBusDataByOffset(
                     IN ULONG BusNumber,
                     IN ULONG SlotNumber,
                     IN PVOID Buffer,
                     IN ULONG Offset,
                     IN ULONG Length
                     )
{
    PCI_SLOT_NUMBER     slotNumber;
    PULONG              pBuffer;
    int                 registerOffset, endOffset;
    TYPE1_PCI_ADDRESS   type1Address;

    if ( bPCIInitialized == FALSE )
        PCIInitBusInfo();

    if ( ucPCIMaxBus == (UCHAR)~0U || BusNumber >= ucPCIMaxBus ) {
        RETAILMSG(1, (TEXT("Invalid bus number passed (%d >= %d)\r\n"),
                      BusNumber, ucPCIMaxBus));

        return(0);
    }

    slotNumber.u.AsULONG = SlotNumber;

    if ( slotNumber.u.bits.DeviceNumber >= ucPCIMaxDeviceNumber ) {
        return(0);
    }


    type1Address.u.AsULONG = 0;
    type1Address.u.bits.ConfigurationAccess = 1;
    type1Address.u.bits.Bus = BusNumber;
    type1Address.u.bits.Device = slotNumber.u.bits.DeviceNumber;
    type1Address.u.bits.Function = slotNumber.u.bits.FunctionNumber;

    registerOffset = Offset / sizeof(ULONG);
    endOffset = registerOffset + (Length + 3) / sizeof(ULONG);
    pBuffer = Buffer;

    for ( ; registerOffset < endOffset; registerOffset++ ) {
        type1Address.u.bits.Register = registerOffset;
        _outpd((USHORT)PCI_TYPE1_ADDRESS, type1Address.u.AsULONG);
        _outpd((USHORT)PCI_TYPE1_DATA, *pBuffer++);
    }

    return(Length);
}


BYTE GetMaxBusNumber(void)
{
    PCI_SLOT_NUMBER     slotNumber;
    PCI_COMMON_CONFIG   pciConfig;
    int                 bus, device, function;
    int                 length;
    BYTE                bMaxBus = 0;

    //
    // Scan bus 0 for bridges. They'll tell us the number of buses
    //
    bus = 0;
    
    for (device = 0; device < PCI_MAX_DEVICES; device++)
    {
        slotNumber.u.bits.DeviceNumber = device;

        for (function = 0; function < PCI_MAX_FUNCTION; function++)
        {
            slotNumber.u.bits.FunctionNumber = function;

            length = PCIGetBusDataByOffset(bus, slotNumber.u.AsULONG,
                                   &pciConfig, 0, sizeof(pciConfig));

            if (length == 0 || pciConfig.VendorID == 0xFFFF) 
                break;

            if (pciConfig.BaseClass == PCI_CLASS_BRIDGE_DEV && pciConfig.SubClass == PCI_SUBCLASS_BR_PCI_TO_PCI)
            {
                if (pciConfig.u.type1.SubordinateBusNumber > bMaxBus)
                {
                    bMaxBus = pciConfig.u.type1.SubordinateBusNumber;
                }
            }

            if (function == 0 && !(pciConfig.HeaderType & 0x80)) 
                break;
            
        }
        if (length == 0)
            break;
    }

    return(bMaxBus);
}

⌨️ 快捷键说明

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