oempci.c
来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 1,258 行 · 第 1/4 页
C
1,258 行
if(!(V3_InternalRegBase = VirtualAddress(PHYSICAL_V3_INTERNAL_REG_BASE, 0x100))) {
ERRORMSG(1, (TEXT("Could not Allocate VirtualAddress to V3 Internal BASE Register.\r\n")));
retval = FALSE;
}
else if(!(PciConfigBase = VirtualAddress(PHYSICAL_PCI_CONFIG_BASE, PCI_CONFIG_SIZE))) {
ERRORMSG(1, (TEXT("Could not Allocate VirtualAddress to PCI Config Register.\r\n")));
retval = FALSE;
}
else if(!(PciIoBase = VirtualAddress(PHYSICAL_PCI_IO_BASE, PCI_IO_SIZE))) {
ERRORMSG(1, (TEXT("Could not Allocate VirtualAddress to PCI IO Register.\r\n")));
retval = FALSE;
}
// PCI Memory is not allocated any more in the pci driver. Any driver which
// needs pci memory must map it on it's own. This helps in saving virtual
// address space in the device drivers that don't need it.
// ALLOCATE_PCI_MEM would not be defined in the final version.
#ifdef PCI_DRIVER_ALLOCATES_PCI_MEM
else if(!(PciMemBase = VirtualAddress(PHYSICAL_PCI_MEM_BASE, PCI_MEM_SIZE))) {
ERRORMSG(1, (TEXT("Could not Allocate VirtualAddress to PCI IO Register.\r\n")));
retval = FALSE;
}
#else
PciMemBase = 0;
#endif
if(retval) {
DEBUGMSG(DEB_PCI_INIT, (TEXT("PCI: MapRegisters: V3_InternalRegBase = 0x%x, PciConfigBase=0x%x, PciIoBase=0x%x\r\n"), V3_InternalRegBase, PciConfigBase, PciIoBase));
// Fill in the members of PciBaseAddresses.
PciBaseAddresses.PciIoBase = (ULONG)PciIoBase;
PciBaseAddresses.PciMemBase = (ULONG)PciMemBase;
PhysicalPciIoBase = PHYSICAL_PCI_IO_BASE;
PhysicalPciMemBase = PHYSICAL_PCI_MEM_BASE;
}
else {
if ( PciMemBase )
VirtualFree((PVOID)PciMemBase, 0, MEM_RELEASE);
if ( PciIoBase )
VirtualFree((PVOID)PciIoBase, 0, MEM_RELEASE);
PciMemBase = 0;
PciIoBase = 0;
}
#endif
DEBUGMSG(DEB_PCI_INIT, (TEXT("PCI: -MapRegisters returning %d\r\n"), retval));
return retval;
}
int OEM_InitPCIHostBridge( void )
{
unsigned tmp, i;
RETAILMSG(1, (TEXT("\r\n+InitPCIHostBridge\r\n")));
/* Map Registers into your virtual address space. */
MapRegisters();
#if (SH_PLATFORM == PLATFORM_S1)
// Set the BCR2 and WCR2 registers to get correct Wait states.
// This might be different in Aspen.
WRITE_REGISTER_USHORT(BCR2, 0x2a3c);
WRITE_REGISTER_ULONG(WCR2, 0xFFF666FB);
#endif (SH_PLATFORM == PLATFORM_S1)
// Initialization of the V3 chip.
// Step 1: Set Base register for V3 Internal registers.
// Step 1a: Assert and De-assert LRESET #
// Step 1b: Write to V3_INITIAL_LB_IO_BASE_RES register.
#if (SH_PLATFORM == PLATFORM_S1)
// The PBC is initialized by asserting LRESET# pin for more than 8 clock
// cycles (To initialize from the local bus).
// The FPGA should provide a register which can be used to assert this pin.
DEBUGMSG(DEB_PCI_INIT, (TEXT("\r\nAsserting and Deasserting the FPGA LRESET#...\r\n")));
FPGA_PCI_CNT = 0x000000FF;
INIT_WAIT;
FPGA_PCI_CNT = 0x000080FF;
// This is not a good idea. I should not generate any local bus writes
// till i've successfully written to the LB_IO_BASE register.
// But if i don't put this delay loop, i'm not able to write to successfully
// to LB_IO_BASE register. These writes would also be captured by the V3
// device.
INIT_WAIT;
// Now Set the V3 registers.
// To initialize from the PCI bus, the first step is to set the Local
// Bus to PCI Aperture. Once this is set, the rest of the registers can
// be accessed from this aperture.
// Set Local to Internal Register Map Base Address.
// DbgPrintf("Setting V3 LB IOBASE at 0x%x...\r\n", (V3_INTERNAL_REG_OFFSET >> 16));
V360_INITIAL_LB_IO_BASE_RES = 0x01800000; // ( (V3_INTERNAL_REG_BASE - V3_MEM_AREA) );
#endif (SH_PLATFORM == PLATFORM_S1)
#if ( (SH_PLATFORM == PLATFORM_ASPEN) || (SH_PLATFORM == PLATFORM_BIGSUR) )
INIT_WAIT;
RETAILMSG(1, (TEXT("PCI_INIT: Writing 0x%x to 0x%x\r\n"), (PHYSICAL_V3_INTERNAL_REG_BASE + 0x6c), &V360_LB_IO_BASE_RES));
V360_LB_IO_BASE_RES = (0x6c+PHYSICAL_V3_INTERNAL_REG_BASE);
INIT_WAIT;
#endif (SH_PLATFORM == PLATFORM_ASPEN)
#if 0
DbgPrintf("Set io base register. \r\n");
{
unsigned tmp;
DbgPrintf("BCR1 = 0x%x\r\n", *(unsigned long *)0xFF800000);
tmp = V3_PCI_DEV_VEN;
DbgPrintf("tmp = %x\r\n", tmp);
}
#endif 0
RETAILMSG(1, (TEXT("PCI_INIT: V3 device reads Vendor ID = %x, Device ID = %x\r\n"),
(V3_PCI_DEV_VEN & 0xFFFF), ((V3_PCI_DEV_VEN >> 16) & 0xFFFF)) );
// Flush ALL FIFOs
#if ( (SH_PLATFORM == PLATFORM_ASPEN) || (SH_PLATFORM == PLATFORM_BIGSUR) )
V360_LB_CFG_SYSTEM = 0x00008077; // 0x8000; // 0x00008077; // 0x63008077;
V360_LB_CFG_SYSTEM = 0x00000000; // 0x63008077;
V360_LB_CFG_SYSTEM = 0x63c08000; // 0x8000; // 0x63c08000; //
INIT_WAIT;
#else (SH_PLATFORM == PLATFORM_ASPEN)
V360_LB_CFG_SYSTEM = 0x00038077; // 0x63008077;
V360_LB_CFG_SYSTEM = 0x03c08000; //
#endif (SH_PLATFORM == PLATFORM_ASPEN)
V3_PCI_STAT_CMD = 0x00000246; // 0x00000246;
V3_PCI_HDR_CFG = 0x0000F800; // 0x00000800;
#if ( (SH_PLATFORM == PLATFORM_ASPEN) || (SH_PLATFORM == PLATFORM_BIGSUR) )
// Find out what to write in the BASE1 registers, Size bits.
// The size bits contain the encoded value of the bits that is 1 above 1 Mb.
i = 0;
tmp = MB_1;
// Possible values of ADR_SIZE are from 0 (1Mb) to 11 (2 Gb). Though SH4 will not support such big value
// I still check for it.
for(i = 0; i <= 11; i++) {
if(tmp == PCI_MEM_SIZE)
break;
tmp <<= 1;
}
// At present i support only slots up to 64 Mb.
if( i > 6) {
ERRORMSG(1, (TEXT("Error: Got invalid size of PCI Memory Space (0x%x). Check PCI_MEM_SIZE in oempci.c\n"), PCI_MEM_SIZE));
return -1;
}
tmp = PHYSICAL_PCI_MEM_BASE | (i << 4) | 0x1;
// DbgPrintf("Writing 0x%x to LB_BASE1\n", tmp);
V360_LB_BASE0 =PHYSICAL_PCI_IO_BASE | 0x01; // Enable.
V360_LB_BASE1 = tmp;
V360_LB_MAP0_RES = 0x00020000;
V360_LB_MAP1_RES = 0x00060000;
DEBUGMSG(DEB_PCI_INIT, (TEXT("LB_BASE0=0x%x, 1=0x%x, MAP0=0x%x, 1=0x%x, tmp=0x%x\r\n"), V360_LB_BASE0, V360_LB_BASE1,
V360_LB_MAP0_RES, V360_LB_MAP1_RES, tmp));
#else (SH_PLATFORM == PLATFORM_ASPEN)
V360_LB_BASE0 = 0x00000041; // No prefetch
V360_LB_BASE1 = 0x01000001; // No prefetch
V360_LB_MAP0_RES = 0x00060000;
V360_LB_MAP1_RES = 0x00020000;
#endif (SH_PLATFORM == PLATFORM_ASPEN)
V360_FIFO_PRIOR_CFG = 0x0f0f0000;
#if 0
WRITE_REGISTER_USHORT(V3_LB_MAP0, 0x000a);
WRITE_REGISTER_USHORT(FPGA_PCI_CNT, 0xa0FF);
#endif
RETAILMSG(1, (TEXT("-InitPCIHostBridge\r\n")));
Command_Scan();
return 0;
#if 0
/* Enable Bus Mastering on the primary PCI segment for the ATU through the */
/* Primary ATU Command Register */
*(volatile WORD *)0x00001204 = 0x0157;
/* Set PCI Interrupt Routing Control so that it does not route CPU board */
/* secondary interrupts to primary PCI segment */
*(volatile DWORD *)0x00001050 = 0x0000000F;
/* Make sure that the internal bridge does not accept any accesses */
*(volatile WORD *)0x00001004 = 0;
#endif
return 0;
}
/* This routine sets the PCI base address used to access shared RAM when the */
/* CPU board is acting as a PCI memory target device. */
/* If operation succeeds, it returns 0. If the operation fails, or this */
/* capability is not supported, it returns non-zero. */
int OEM_SetSharedRAMBaseAddr( DWORD dwPCISharedRAMBase ) {
#if 0
/* Set the primary inbound ATU base address to allow DMA onto the CPU card */
*(volatile DWORD *)0x00001210 = dwPCISharedRAMBase;
#endif
return 0;
} /* OEM_SetSharedRAMBaseAddr */
/* Function returning a record describing the base address and size for */
/* the PCI memory and I/O space windows that pass through the PCI host */
/* bridge for the processor. */
void OEM_GetPCIHostBridgeWindowInfo( PCIHostBridgeWindowInfoRec *pPCIHostBridgeWindowInfo ) {
#if ( (SH_PLATFORM == PLATFORM_ASPEN) || (SH_PLATFORM == PLATFORM_BIGSUR) )
/* Processor base address to access PCI memory window */
pPCIHostBridgeWindowInfo->dwMemWinBase = PHYSICAL_PCI_MEM_BASE;
/* Size of PCI memory window */
pPCIHostBridgeWindowInfo->dwMemWinSize = PCI_MEM_SIZE;
/* Processor base address to access PCI I/O window */
pPCIHostBridgeWindowInfo->dwIOWinBase = PHYSICAL_PCI_IO_BASE;
/* Size of PCI I/O window */
pPCIHostBridgeWindowInfo->dwIOWinSize = PCI_IO_SIZE;
/* Indicate that the board does support PCI memory target operation */
pPCIHostBridgeWindowInfo->fPCIMemTargetSupported = 0;
#else (SH_PLATFORM == PLATFORM_ASPEN)
/* Processor base address to access PCI memory window */
pPCIHostBridgeWindowInfo->dwMemWinBase = 0xA4000000;
/* Size of PCI memory window */
pPCIHostBridgeWindowInfo->dwMemWinSize = 16*1024*1024;
/* Processor base address to access PCI I/O window */
pPCIHostBridgeWindowInfo->dwIOWinBase = 0xA5000000;
/* Size of PCI I/O window */
pPCIHostBridgeWindowInfo->dwIOWinSize = 1*1024*1024;
/* Indicate that the board does support PCI memory target operation */
pPCIHostBridgeWindowInfo->fPCIMemTargetSupported = 0;
#endif (SH_PLATFORM == PLATFORM_ASPEN)
} /* GetPCIWindowInfo() */
/* This function returns the extents of the range of PCI memory and I/O */
/* addresses that the PCI host bridge can generate. This is not just */
/* the size of the host bridge windows, but also includes what can be */
/* reached using the PCI paging registers. The host bridge should */
/* allow all of PCI address space to be addressed if the paging */
/* registers are used; however, the test program itself may need to */
/* map devices into certain ranges for use with the debug serial for */
/* example. This data returned from this function allows the */
/* exclusion of some address ranges so that they will not be altered. */
void OEM_GetLegalPCIAddrRange( PCIMapInfoRec *pPCIMapInfo ) {
/* For ASPEN, this is currently returning the same values as in the
* original code, though for this platform the whole PCI range from 0
* to 4GB can be accessed.
* I'll modify the code for that later.
*/
#if ( (SH_PLATFORM == PLATFORM_ASPEN) || (SH_PLATFORM == PLATFORM_BIGSUR) )
/* Processor base address to access PCI memory window */
pPCIMapInfo->dwPCIMemBase = PHYSICAL_PCI_MEM_BASE; // 0x80000000; // PCI_MEM_AREA;
/* Size of PCI memory window */
pPCIMapInfo->dwPCIMemLimit = PCI_MEM_SIZE; // 64 * 1024 * 1024; // PCI_MEM_SIZE;
/* Processor base address to access PCI I/O window */
pPCIMapInfo->dwPCIIOBase = PHYSICAL_PCI_IO_BASE; // 0x90000000; // PCI_IO_AREA;
/* Size of PCI I/O window */
pPCIMapInfo->dwPCIIOLimit = PCI_IO_SIZE; // 64 * 1024; // PCI_IO_SIZE;
#else (SH_PLATFORM == PLATFORM_ASPEN)
#endif (SH_PLATFORM == PLATFORM_ASPEN)
} /* GetPCIWindowInfo() */
/* This routine will return the state of the PCI interrupt lines that */
/* are directly connected to the host PCI bridge. */
/* *pbInterrupts is interpretted as follows: */
/* Bit 3 - INTA# */
/* Bit 2 - INTB# */
/* Bit 1 - INTC# */
/* Bit 0 - INTD# */
/* If a bit is a 0, then the interrupt is asserted. if a bit is a 1, */
/* then the interrupt is not asserted. Unassigned bits should be 0. */
/* The routine will return 0 if there is no error or will return non- */
/* zero if an error occurs. */
int OEM_GetPCIInterruptState( BYTE *pbInterrupts ) {
#if 0
/* Unimplemented at this time */
*pbInterrupts = 0x0F;
#endif
return 0;
} /* OEM_GetPCIInterruptState() */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?