registry.c
来自「Windows CE 6.0 BSP for VOIP sample phone」· C语言 代码 · 共 201 行
C
201 行
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//------------------------------------------------------------------------------
//
// File: registry.c
//
#include <windows.h>
#include <ceddk.h>
#include <oal.h>
#ifdef KITL_PCI
#include <PCIReg.h>
//------------------------------------------------------------------------------
//
// Function: PCIReadBARs
//
// Fill out memory and I/O resource info.
// The flow is the same as that of CEPC.
// Make use of abstract functions to read/write PCI configuration.
static BOOL
PCIReadBARs(
DWORD busNumber,
PPCI_REG_INFO pInfo
)
{
DWORD NumberOfRegs;
DWORD Offset;
DWORD i;
DWORD BaseAddress;
DWORD Size;
DWORD Reg;
DWORD IoIndex = 0;
DWORD MemIndex = 0;
OAL_PCI_LOCATION pciLoc;
pciLoc.fnc = (UINT8)pInfo->Function;
pciLoc.dev = (UINT8)pInfo->Device;
pciLoc.bus = (UINT8)pInfo->Bus;
busNumber >>= 8; // bits 8-15 are host-to-PCI-bridge bus number
// Determine number of BARs to examine from header type
switch (pInfo->Cfg.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 = pInfo->Cfg.u.type0.BaseAddresses[i];
// Get size info
BaseAddress = 0xFFFFFFFF;
OALPCICfgWrite(busNumber, pciLoc, Offset, sizeof(BaseAddress), &BaseAddress);
OALPCICfgRead(busNumber, pciLoc, Offset, sizeof(BaseAddress), &BaseAddress);
OALPCICfgWrite(busNumber, pciLoc, Offset, sizeof(Reg), &Reg);
// Re-adjust BaseAddress if upper 16-bits are 0 (this happens on some devices that don't follow
// the PCI spec, like the Intel UHCI controllers)
if (((BaseAddress & 0xFFFFFFFC) != 0) && ((BaseAddress & 0xFFFF0000) == 0)) {
BaseAddress |= 0xFFFF0000;
}
if (Reg & 1) {
// IO space
Size = ~(BaseAddress & 0xFFFFFFFC);
if ((BaseAddress != 0) && (BaseAddress != 0xFFFFFFFF) && (((Size + 1) & Size) == 0)) {
// BAR has valid format (consecutive high 1's and consecutive low 0's)
pInfo->IoLen.Reg[IoIndex] = Size + 1;
pInfo->IoLen.Num++;
pInfo->IoBase.Reg[IoIndex++] = Reg & 0xFFFFFFFC;
pInfo->IoBase.Num++;
} else {
// BAR invalid => skip to next one
continue;
}
} else {
// Memory space
// TODO: don't properly handle the MEM20 case
Size = ~(BaseAddress & 0xFFFFFFF0);
if ((BaseAddress != 0) && (BaseAddress != 0xFFFFFFFF) && (((Size + 1) & Size) == 0)) {
// BAR has valid format (consecutive high 1's and consecutive low 0's)
pInfo->MemLen.Reg[MemIndex] = Size + 1;
pInfo->MemLen.Num++;
pInfo->MemBase.Reg[MemIndex++] = Reg & 0xFFFFFFF0;
pInfo->MemBase.Num++;
} else {
// BAR invalid => skip to next one
continue;
}
}
//
// check for 64 bit device - BAR is twice as big
//
if ((pInfo->Cfg.u.type0.BaseAddresses[i] & 0x7) == 0x4) {
// 64 bit device - BAR is twice as wide - zero out high part
Offset += 4;
i++;
}
}
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: RegisterKITL
//
// This function is used to update registry for KITL PCI info.
// It is almost the same as the function "OALPCIRegisterAsUsed" except calling the function "PCIReadBARs".
// It will fill up complete info on registry, includes all BAR's address and length.
void RegisterKITL(void)
{
PCI_REG_INFO KitlPCIInfo;
DEVICE_LOCATION devLoc;
PCI_COMMON_CONFIG pciCfg;
OAL_PCI_LOCATION pciLoc;
KITL_RETAILMSG(ZONE_KITL_OAL, ("+ RegisterKITL \r\n"));
OALKitlGetDevLoc(&devLoc);
pciLoc = *(OAL_PCI_LOCATION*)&devLoc.LogicalLoc;
// First read all device configuration space
OALPCICfgRead(devLoc.BusNumber, pciLoc, 0, sizeof(pciCfg), &pciCfg);
// Fill info structure
PCIInitInfo(
L"Drivers\\BuiltIn\\PCI\\Instance\\KITL", pciLoc.bus, pciLoc.dev,
pciLoc.fnc, pciCfg.u.type0.InterruptLine, &pciCfg, &KitlPCIInfo
);
PCIReadBARs(devLoc.BusNumber, &KitlPCIInfo);
PCIReg(&KitlPCIInfo);
KITL_RETAILMSG(ZONE_KITL_OAL, ("- RegisterKITL \r\n"));
}
#endif
//------------------------------------------------------------------------------
//
// Function: OALKitlInitRegistry
//
// This function is called as part of IOCTL_HAL_INITREGISTRY to update
// registry with information about KITL device. This must be done to avoid
// loading Windows CE driver in case that it is part of image. On image
// without KITL is this function replaced with empty stub.
//
// This implementation works only for PCI KITL devices. It probably should
// be replaced with platform specific code if KITL device is on internal
// bus.
//
VOID OALKitlInitRegistry()
{
DEVICE_LOCATION devLoc;
KITL_RETAILMSG(ZONE_KITL_OAL, ("+OALKitlInitRegistry\r\n"));
if (!OALKitlGetDevLoc(&devLoc)) goto cleanUp;
switch (devLoc.IfcType) {
#ifdef KITL_PCI
case PCIBus:
RegisterKITL();
break;
#endif
}
cleanUp:
KITL_RETAILMSG(ZONE_KITL_OAL, ("-OALKitlInitRegistry\r\n"));
}
//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?