📄 common.cpp
字号:
if (dwLen--==0) goto pcft_continue;
//
// Parse the feature select byte
//
//
// Power requirements present
//
bmPowerPresent = *pCIS & 0x03;
//
// I/O space descriptions present
//
IOPresent = *pCIS & 0x08;
//
// Irq description present
//
IrqPresent = *pCIS & 0x10;
//
// Memory description present
//
MemPresent = *pCIS & 0x20;
//
// Misc description present
//
MiscPresent = *pCIS & 0x80;
pCIS++;
if (dwLen--==0) goto pcft_continue;
//
// Parse the power description structures if present
//
DWORD dwParsedLength;
if (bmPowerPresent >= 1) {
pCfTable->VccDescr.ValidMask = 0xFF;
pCIS +=(dwParsedLength=ParseVoltageDescr(pCIS, &pCfTable->VccDescr));
if (dwParsedLength >dwLen) goto pcft_continue;
dwLen -=dwParsedLength;
for (i = 0; i < 3; i++) {
if ((PWR_DESCR_NOMINALV << i) & pCfTable->VccDescr.ValidMask )
pCfTable->VccDescr.ValidMask |= (PWR_AVAIL_NOMINALV << i);
}
}
if (bmPowerPresent >= 2) {
pCfTable->Vpp1Descr.ValidMask = 0xFF;
pCIS += (dwParsedLength=ParseVoltageDescr(pCIS, &pCfTable->Vpp1Descr));
if (dwParsedLength >dwLen) goto pcft_continue;
dwLen -=dwParsedLength;
for (i = 0; i < 3; i++) {
if ((PWR_DESCR_NOMINALV << i) & pCfTable->Vpp1Descr.ValidMask )
pCfTable->Vpp1Descr.ValidMask |= (PWR_AVAIL_NOMINALV << i);
}
pCfTable->Vpp2Descr.ValidMask = 0xFF;
if (bmPowerPresent == 3) {
pCIS += (dwParsedLength=ParseVoltageDescr(pCIS, &pCfTable->Vpp2Descr));
if (dwParsedLength >dwLen) goto pcft_continue;
dwLen -=dwParsedLength;
for (i = 0; i < 3; i++) {
if ((PWR_DESCR_NOMINALV << i) & pCfTable->Vpp1Descr.ValidMask )
pCfTable->Vpp2Descr.ValidMask |= (PWR_AVAIL_NOMINALV << i);
}
} else
pCfTable->Vpp2Descr = pCfTable->Vpp1Descr;
}
//
// Process the I/O address ranges (up to MAX_IO_RANGES)
//
if (IOPresent) {
pCfTable->bUsedBarForIo = ((*pCIS)>>1) & 0x1f;
pCIS++;
if (dwLen--==0) goto pcft_continue;
}
// Irq description present
//
if ( IrqPresent) {
if ((*pCIS & 0x10)==0) { // Mask Bit is set
pCfTable->wIrqMask =(1<< (*pCIS & 0xf));
pCIS++;
if (dwLen--==0) goto pcft_continue;
}
else {
if (dwLen <3) goto pcft_continue;
pCIS++;
pCfTable->wIrqMask=*pCIS+(((WORD)*(pCIS+1))<<8);
pCIS+=2;
dwLen -= 3;
}
}
if (MemPresent) {
pCfTable->bUsedBarForMem = ((*pCIS)>>1) & 0x7f; // 7 Bit. INCLUDE ROM.
pCIS++;
if (dwLen--==0) goto pcft_continue;
}
// else it has already been either defaulted or memset to zeros.
pcft_continue:
pCfTable++;
pcft_next:
if ((pBuf != NULL) && (nItems == *pnItems)) {
status = CERR_NO_MORE_ITEMS; // no more room in caller's buffer
} else {
//
// Get the next CISTPL_CFTABLE_ENTRY
//
status = CardGetNextTuple(pTuple);
}
} // while (status == CERR_SUCCESS)
pcft_exit:
if(pnItems != NULL)
*pnItems = nItems;
//
// If there were problems and no CFTABLE_ENTRYs found then return an error.
//
if (nItems) {
return CERR_SUCCESS;
}
return status;
}
USHORT VoltageConversionTable[16] = {
10, 12, 13, 15, 20, 25, 30, 35,
40, 45, 50, 55, 60, 70, 80, 90
};
//
// ConvertVoltage - normalize a single CISTPL_CFTABLE_ENTRY voltage entry and
// return its length in bytes
//
UINT ConvertVoltage(PUCHAR pCIS, PUSHORT pDescr)
{
UINT Length;
SHORT power;
USHORT value;
UCHAR MantissaExponentByte;
UCHAR ExtensionByte;
Length = 1;
power = 1;
MantissaExponentByte = pCIS[0];
ExtensionByte = pCIS[1];
value = VoltageConversionTable[(MantissaExponentByte >> 3) & 0x0f];
if ((MantissaExponentByte & TPCE_PD_EXT) &&
(ExtensionByte < 100)) {
value = (100 * value + (ExtensionByte & 0x7f));
power += 2;
}
power = (MantissaExponentByte & 0x07) - 4 - power;
while (power > 0) {
value *= 10;
power--;
}
while (power < 0) {
value /= 10;
power++;
}
*pDescr = value;
//
// Skip any subsequent extension bytes for now.
//
while (*pCIS & TPCE_PD_EXT) {
Length++;
pCIS++;
}
return Length;
} // ConvertVoltage
//
// ParseVoltageDescr - convert the variable length power description structure
// from a CISTPL_CFTABLE_ENTRY to a POWER_DESCR structure
// and normalize the values.
// Returns the length of the variable length power description structure.
//
// A typical call would be:
// if (pCfTable->VccDescr.ValidMask) {
// pCIS += ParseVoltageDescr(pCIS, &pCfTable->VccDescr);
// }
//
UINT ParseVoltageDescr(PUCHAR pVolt, PPOWER_DESCR pDescr)
{
UINT Length;
UINT Mask;
UINT i;
PUSHORT pDVolt;
Length = 1;
Mask = pDescr->ValidMask = (UINT)*pVolt;
pVolt++;
pDVolt = &(pDescr->NominalV);
while (Mask) {
if (Mask & 1) {
i = ConvertVoltage(pVolt, pDVolt);
Length += i;
pVolt += i;
} else {
*pDVolt = 0;
}
pDVolt++;
Mask >>= 1;
}
return Length;
} // ParseVoltageDescr
void CreateDefaultInfo(CARD_SOCKET_HANDLE hSocket, PPARSED_CBCFTABLE pCfTable)
{
ASSERT(pCfTable);
PCB_BUS_INFO pBusInfo = NULL;
if (GetCBCardBusInfo(hSocket, &pBusInfo) == FALSE){
return;
}
memset(pCfTable,0,sizeof(PARSED_CBCFTABLE));
// Scan Bar
BYTE bShiftBit=1;
for (DWORD dwIndex=0;dwIndex<PCI_TYPE0_ADDRESSES;dwIndex++) {
DWORD dwPos=dwIndex*sizeof(DWORD)+PCI_CONFIG_BASE0;
// GetValue
DWORD dwOldValue=PCIConfig_Read(dwPos, pBusInfo);
PCIConfig_Write(dwPos,(DWORD)-1, pBusInfo);
DWORD dwSizeValue = PCIConfig_Read(dwPos, pBusInfo);
PCIConfig_Write(dwPos,dwOldValue, pBusInfo);
if (dwSizeValue & 1) { // IO
dwSizeValue &=0xfffffffc;
g_CBCardInfo.m_BARType[dwIndex]=1;// for IO;
}
else {
dwSizeValue &=0xfffffff0;
g_CBCardInfo.m_BARType[dwIndex]=0;// for Memory
}
g_CBCardInfo.m_BARSize[dwIndex]=(~dwSizeValue)+1;
if (g_CBCardInfo.m_BARSize[dwIndex]!=0) {
if (g_CBCardInfo.m_BARType[dwIndex]!=0)
pCfTable->bUsedBarForIo = bShiftBit;
else
pCfTable->bUsedBarForMem = bShiftBit;
}
bShiftBit <<=1;
}
DWORD dwValue= PCIConfig_Read(15*sizeof(DWORD), pBusInfo);
if ((dwValue & 0xff00)!=0) { // If there is interrupt PIN value, Assume it need irq
pCfTable->wIrqMask = (WORD) -1;
};
}
DWORD PCIConfig_Read(DWORD dwOffset, PCB_BUS_INFO pInfo)
{
DWORD RetVal = 0;
if(pInfo == NULL)
return (DWORD)-1;
HalGetBusDataByOffset(PCIConfiguration, pInfo->dwBusNumber, pInfo->SlotNumber.u.AsULONG, &RetVal, dwOffset, sizeof(RetVal));
return RetVal;
}
void PCIConfig_Write(DWORD dwOffset,DWORD dwValue, PCB_BUS_INFO pInfo)
{
if(pInfo == NULL)
return;
HalSetBusDataByOffset(PCIConfiguration, pInfo->dwBusNumber, pInfo->SlotNumber.u.AsULONG, &dwValue, dwOffset, sizeof(dwValue));
}
VOID Add_CBCardBusInfo(CARD_SOCKET_HANDLE hSocket, DWORD dwBusNumber, INTERFACE_TYPE iType, PCI_SLOT_NUMBER SlotNumber)
{
PCB_BUS_INFO pNode = new CB_BUS_INFO;
if(pNode == NULL)//out of memory, should not happen though
return;
pNode->hSocket = hSocket;
pNode->dwBusNumber = dwBusNumber;
pNode->InterfaceType = iType;
pNode->SlotNumber = SlotNumber;
pNode->pNext = NULL;
if(g_pCBBusInfoHead == NULL){
g_pCBBusInfoHead = pNode;
}
else{
PCB_BUS_INFO pCur = g_pCBBusInfoHead;
while(pCur->pNext!= NULL)
pCur= pCur->pNext;
pCur->pNext = pNode;
}
}
VOID Delete_CBCardBusInfo(CARD_SOCKET_HANDLE hSocket){
PCB_BUS_INFO pCur, pPrev;
if(g_pCBBusInfoHead == NULL)
return;
pPrev=pCur= g_pCBBusInfoHead;
do{
if((pCur->hSocket.uFunction == hSocket.uFunction) || (pCur->hSocket.uSocket == hSocket.uSocket))
break;
pPrev = pCur;
pCur = pCur->pNext;
}while(pCur != NULL);
if(pCur == NULL){//not found
return;
}
else{
if(pPrev == g_pCBBusInfoHead){//this is the head
delete pPrev;
g_pCBBusInfoHead = NULL;
}
else{
pPrev->pNext = pCur->pNext;
delete pCur;
}
}
}
BOOL GetCBCardBusInfo(CARD_SOCKET_HANDLE hSocket, PCB_BUS_INFO *ppInfo){
if(ppInfo == NULL)
return FALSE;
PCB_BUS_INFO pCur = g_pCBBusInfoHead;
while(pCur != NULL){
if((pCur->hSocket.uFunction == hSocket.uFunction) || (pCur->hSocket.uSocket == hSocket.uSocket))
break;
pCur = pCur->pNext;
}
if(pCur != NULL){//found
*ppInfo = pCur;
return TRUE;
}
else
return FALSE;
}
VOID Cleanup_CBCardBusInfo(){
PCB_BUS_INFO pCur, pNext;
pCur = g_pCBBusInfoHead;
while(pCur != NULL){
pNext = pCur->pNext;
delete pCur;
pCur = pNext;
}
g_pCBBusInfoHead = NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -