📄 pci.c
字号:
//
// 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.
//
//------------------------------------------------------------------------------
//
// File: pci.c
//
#include <windows.h>
#include <ceddk.h>
#include <oal.h>
#include <vr4131.h>
//------------------------------------------------------------------------------
UINT32 OALPCICfgRead(
UINT32 busId, OAL_PCI_LOCATION pciLoc, UINT32 offset, UINT32 size,
VOID *pData
) {
VR4131_PCIU_REGS *pPCIURegs = OALPAtoUA(VR4131_REG_PA_PCIU);
UINT32 address, value, count = 0;
UINT8 *p = (UINT8*)pData;
OALMSG(OAL_PCI&&OAL_FUNC, (
L"+OALPCICfgRead(%d, %d/%d/%d, %d, %d, 0x%08x)\r\n", busId,
pciLoc.bus, pciLoc.dev, pciLoc.fnc, offset, size, pData
));
// We support only one bus
if (busId != 0) goto cleanUp;
// First check region to read
if ((offset + size) > 256) goto cleanUp;
// Get configuration address
if (pciLoc.bus == 0) {
// type 0 configuration
address = (1 << (pciLoc.dev + 10))|(pciLoc.fnc << 8);
} else {
// type 1 configuration
address = 1 |(pciLoc.fnc << 8) |(pciLoc.dev << 11) |(pciLoc.bus << 16);
}
// First read any unaligned data on start
if ((offset & 0x03) != 0) {
OUTREG32(&pPCIURegs->PCICONFA, address + (offset & ~0x03));
OALStall(10);
value = INREG32(&pPCIURegs->PCICONFD);
value >>= (offset & 0x03) << 3;
while ((offset & 0x03) != 0 && size > 0) {
*p++ = (UINT8)value;
value >>= 8;
offset++;
size--;
count++;
}
}
// Then read full DWORDs
while (size >= 4) {
OUTREG32(&pPCIURegs->PCICONFA, address + offset);
OALStall(10);
value = INREG32(&pPCIURegs->PCICONFD);
*p++ = (UINT8)value;
*p++ = (UINT8)(value >> 8);
*p++ = (UINT8)(value >> 16);
*p++ = (UINT8)(value >> 24);
offset += 4;
size -= 4;
count += 4;
}
// And remaining data at end
if (size > 0) {
OUTREG32(&pPCIURegs->PCICONFA, address + offset);
OALStall(10);
value = INREG32(&pPCIURegs->PCICONFD);
while (size > 0) {
*p++ = (UINT8)value;
value >>= 8;
size--;
count++;
}
}
cleanUp:
OALMSG(OAL_PCI&&OAL_FUNC, (L"-OALPCICfgRead(count = %d)\r\n", count));
return count;
}
//------------------------------------------------------------------------------
UINT32 OALPCICfgWrite(
UINT32 busId, OAL_PCI_LOCATION pciLoc, UINT32 offset, UINT32 size,
VOID *pData
) {
VR4131_PCIU_REGS *pPCIURegs = OALPAtoUA(VR4131_REG_PA_PCIU);
UINT32 address, value, count = 0;
UINT8 *p = (UINT8*)pData;
OALMSG(OAL_PCI&&OAL_FUNC, (
L"+OALPCICfgWrite(%d, %d/%d/%d, %d, %d, 0x%08x\r\n", busId,
pciLoc.bus, pciLoc.dev, pciLoc.fnc, offset, size, pData
));
// We support only one bus
if (busId != 0) goto cleanUp;
// Check region to read
if ((offset + size) > 256) goto cleanUp;
// Get configuration address
if (pciLoc.bus == 0) {
// type 0 configuration
address = (1 << (pciLoc.dev + 10))|(pciLoc.fnc << 8);
} else {
// type 1 configuration
address = 1 |(pciLoc.fnc << 8) |(pciLoc.dev << 11) |(pciLoc.bus << 16);
}
// First write any unaligned data on start
if ((offset & 0x03) != 0) {
OUTREG32(&pPCIURegs->PCICONFA, address + (offset & ~0x03));
OALStall(10);
value = INREG32(&pPCIURegs->PCICONFD);
while ((offset & 0x03) != 0 && size > 0) {
value &= ~(0xFF << ((offset & 0x03) << 3));
value |= (UINT32)(*p++ << ((offset & 0x03) << 3));
offset++;
size--;
count++;
}
OUTREG32(&pPCIURegs->PCICONFA, address + ((offset - 1)&~0x03));
OALStall(10);
OUTREG32(&pPCIURegs->PCICONFD, value);
OALStall(10);
}
// Then write full DWORDs
while (size >= 4) {
value = (UINT32)(*p++);
value |= (UINT32)(*p++ << 8);
value |= (UINT32)(*p++ << 16);
value |= (UINT32)(*p++ << 24);
OUTREG32(&pPCIURegs->PCICONFA, address + offset);
OALStall(10);
OUTREG32(&pPCIURegs->PCICONFD, value);
OALStall(10);
offset += 4;
size -= 4;
count += 4;
}
// And remaining data at end
if (size > 0) {
OUTREG32(&pPCIURegs->PCICONFA, address + offset);
OALStall(10);
value = INREG32(&pPCIURegs->PCICONFD);
while (size > 0) {
value &= ~(0xFF << ((offset & 0x03) << 3));
value |= (UINT32)(*p++ << ((offset & 0x03) << 3));
offset++;
size--;
count++;
}
OUTREG32(&pPCIURegs->PCICONFA, address + ((offset - 1)&~0x03));
OALStall(10);
OUTREG32(&pPCIURegs->PCICONFD, value);
}
cleanUp:
OALMSG(OAL_PCI&&OAL_FUNC, (L"-OALPCICfgWrite(count = %d)\r\n", count));
return count;
}
//------------------------------------------------------------------------------
VOID OALPCIPowerOff(UINT32 busId)
{
}
//------------------------------------------------------------------------------
VOID OALPCIPowerOn(UINT32 busId)
{
}
//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -