📄 config.c
字号:
if ((size & (size - 1)) != 0 || size == 0) continue;
// Check allocation type (let support only 32bit space for now)
if ((size & 0x00000006) != 0) {
OALMSG(OAL_WARN, (
L"WARNING: PCIConfigDevice: 64 bit space NOT supported\r\n"
));
continue;
}
// Assign memory space (allocate 4KB at least)
if (size < 4096) size = 4096;
address = (*pMemBase + size - 1) & ~(size - 1);
*pMemBase = address + size;
OALMSG(OAL_INFO, (
L"INFO: PCIConfigDevice: Mem BAR[%d] 0x%x Size 0x%x\r\n",
ix, address, size
));
}
OALPCICfgWrite(busId, pciLoc, offset, sizeof(address), &address);
offset += sizeof(UINT32);
}
// Set latency timer
u8 = OAL_PCI_LATENCY_TIMER;
OALPCICfgWrite(
busId, pciLoc, FIELD_OFFSET(PCI_COMMON_CONFIG, LatencyTimer),
sizeof(u8), &u8
);
// Set cache line size
u8 = OAL_PCI_CACHE_LINE_SIZE;
OALPCICfgWrite(
busId, pciLoc, FIELD_OFFSET(PCI_COMMON_CONFIG, CacheLineSize),
sizeof(u8), &u8
);
// Enable device and clear all status
u16 = PCI_ENABLE_MEMORY_SPACE|PCI_ENABLE_IO_SPACE|PCI_ENABLE_BUS_MASTER;
OALPCICfgWrite(
busId, pciLoc, FIELD_OFFSET(PCI_COMMON_CONFIG, Command),
sizeof(u16), &u16
);
#ifdef OAL_PCI_DUMP_CONFIG
OALPCIDumpConfig(busId, pciLoc);
#endif
OALMSG(OAL_PCI&&OAL_FUNC, (
L"-PCIConfigDevice(memBase = 0x%08x, ioBase = 0x%08x)\r\n",
*pMemBase, *pIoBase
));
}
//------------------------------------------------------------------------------
//
// Function: PCIConfigBridge
//
static VOID PCIConfigBridge(
UINT32 busId, OAL_PCI_LOCATION pciLoc, UINT32 secBus, UINT32 subBus,
UINT32 *pMemBase, UINT32 memSize, UINT32 *pIoBase, UINT32 ioSize
) {
UINT32 memLimit, ioLimit, u32;
UINT16 command, u16;
UINT8 u8;
OALMSG(OAL_PCI&&OAL_FUNC, (
L"+PCIConfigBridge(%d, %d/%d/%d, %d, %d, 0x%08x, 0x%08x, 0x%08x, 0x%08x\r\n",
busId, pciLoc.bus, pciLoc.dev, pciLoc.fnc, secBus, subBus,
*pMemBase, memSize, *pIoBase, ioSize
));
// Compute limits
if (memSize > 0) {
*pMemBase = (*pMemBase + 0xFFFFF) & ~0xFFFFF; // 1M boundary
memSize = (memSize + 0xFFFFF) & ~0xFFFFF; // 1M chunks
memLimit = (*pMemBase + memSize - 1) & ~0xFFFFF; // 1M boundary
}
if (ioSize > 0) {
*pIoBase = (*pIoBase + 0xFFF) & ~0xFFF; // 4K boundary
ioSize = (ioSize + 0xFFF) & ~0xFFF; // 4K chunks
ioLimit = (*pIoBase + ioSize - 1) & ~0xFFF; // 4K boundary
}
// Disable Memory and I/O access
command = 0;
OALPCICfgWrite(
busId, pciLoc, FIELD_OFFSET(PCI_COMMON_CONFIG, Command),
sizeof(command), &command
);
// Set master latency timer
u8 = OAL_PCI_LATENCY_TIMER;
OALPCICfgWrite(
busId, pciLoc, FIELD_OFFSET(PCI_COMMON_CONFIG, LatencyTimer),
sizeof(u8), &u8
);
// Set cache line size
u8 = OAL_PCI_CACHE_LINE_SIZE;
OALPCICfgWrite(
busId, pciLoc, FIELD_OFFSET(PCI_COMMON_CONFIG, CacheLineSize),
sizeof(u8), &u8
);
// Set primary bus number
u8 = pciLoc.bus;
OALPCICfgWrite(
busId, pciLoc,
FIELD_OFFSET(PCI_COMMON_CONFIG, u.type1.PrimaryBusNumber),
sizeof(u8), &u8
);
// Set secondary bus number
u8 = (UINT8)secBus;
OALPCICfgWrite(
busId, pciLoc,
FIELD_OFFSET(PCI_COMMON_CONFIG, u.type1.SecondaryBusNumber),
sizeof(u8), &u8
);
// Set subordinate bus number
u8 = (UINT8)subBus;
OALPCICfgWrite(
busId, pciLoc,
FIELD_OFFSET(PCI_COMMON_CONFIG, u.type1.SubordinateBusNumber),
sizeof(u8), &u8
);
// Set secondary latency timer
u8 = OAL_PCI_LATENCY_TIMER;
OALPCICfgWrite(
busId, pciLoc,
FIELD_OFFSET(PCI_COMMON_CONFIG, u.type1.SecondaryLatencyTimer),
sizeof(u8), &u8
);
// Prepare configuration command
command = PCI_ENABLE_SERR;
// Set memory range
if (memSize > 0) {
// Memory base
u16 = (UINT16)(*pMemBase >> 16);
OALPCICfgWrite(
busId, pciLoc,
FIELD_OFFSET(PCI_COMMON_CONFIG, u.type1.MemoryBase),
sizeof(u16), &u16
);
// Memory limit
u16 = (UINT16)((memLimit >> 16) & 0xFFF0);
OALPCICfgWrite(
busId, pciLoc,
FIELD_OFFSET(PCI_COMMON_CONFIG, u.type1.MemoryLimit),
sizeof(u16), &u16
);
// Disable prefetch memory - base to 0xFFF00000
u16 = 0xFFF0;
OALPCICfgWrite(
busId, pciLoc,
FIELD_OFFSET(PCI_COMMON_CONFIG, u.type1.PrefetchableMemoryBase),
sizeof(u16), &u16
);
// Disable prefetch memory - limit to 0x000FFFFF
u16 = 0x0;
OALPCICfgWrite(
busId, pciLoc,
FIELD_OFFSET(PCI_COMMON_CONFIG, u.type1.PrefetchableMemoryLimit),
sizeof(u16), &u16
);
// Disable prefetch memory
u32 = 0xFFFFFFFF;
OALPCICfgWrite(
busId, pciLoc, FIELD_OFFSET(
PCI_COMMON_CONFIG, u.type1.PrefetchableMemoryBaseUpper32
), sizeof(u32), &u32
);
// Disable prefetch memory
u32 = 0;
OALPCICfgWrite(
busId, pciLoc, FIELD_OFFSET(
PCI_COMMON_CONFIG, u.type1.PrefetchableMemoryLimitUpper32
), sizeof(u32), &u32
);
// Enable memory space
command |= PCI_ENABLE_MEMORY_SPACE|PCI_ENABLE_BUS_MASTER;
}
// Set io range (32-bit address decode)
if (ioSize > 0) {
// IO base
u8 = (UINT8)((*pIoBase >> 8) & 0xF0);
OALPCICfgWrite(
busId, pciLoc, FIELD_OFFSET(PCI_COMMON_CONFIG, u.type1.IOBase),
sizeof(u8), &u8
);
// IO upper base
u16 = (UINT16)(*pIoBase >> 16);
OALPCICfgWrite(
busId, pciLoc, FIELD_OFFSET(
PCI_COMMON_CONFIG, u.type1.IOBaseUpper
), sizeof(u16), &u16
);
// IO limit
u8 = (UINT8)((ioLimit >> 8) & 0xF0);
OALPCICfgWrite(
busId, pciLoc, FIELD_OFFSET(PCI_COMMON_CONFIG, u.type1.IOLimit),
sizeof(u8), &u8
);
// IO upper limit
u16 = (UINT16)(ioLimit >> 16);
OALPCICfgWrite(
busId, pciLoc, FIELD_OFFSET(
PCI_COMMON_CONFIG, u.type1.IOLimitUpper
), sizeof(u16), &u16
);
// Enable io space
command |= PCI_ENABLE_IO_SPACE|PCI_ENABLE_BUS_MASTER;
}
// Enable bridge
OALPCICfgWrite(
busId, pciLoc, FIELD_OFFSET(PCI_COMMON_CONFIG, Command),
sizeof(command), &command
);
#ifdef OAL_PCI_DUMP_CONFIG
OALPCIDumpConfig(busId, pciLoc);
#endif
OALMSG(OAL_PCI&&OAL_FUNC, (
L"-PCIConfigBridge(memBase = 0x%08x, ioBase = 0x%08x\r\n",
*pMemBase, *pIoBase
));
}
//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -