?? pcicfg.c
字號(hào):
//
// 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;
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -