📄 tmpci.c
字号:
SDRAMBegin = (UInt8*)*(UInt32*)(((UInt8*)_MMIO_base) + DRAM_BASE);
SDRAMEnd = (UInt8*)((*(UInt32*)(((UInt8*)_MMIO_base) + DRAM_LIMIT)) - 1);
if ( ( Destination > SDRAMBegin ) && ( Destination < SDRAMEnd ) )
{
/* destination is inside SDRAM range */
/* make sure that at least the Source is in SDRAM */
if ( ( Source > SDRAMBegin ) && ( Source < SDRAMEnd ) )
{
PRINTF ((
"tmPCI:Error:Source[%x] & Destination[%x] within SDRAM[%x:%x]\n",
Source, Destination, SDRAMBegin, SDRAMEnd ));
return PCI_ERR_SDRAM_RANGE;
/* error - both source and destination are in sdram */
}
else
{
/* destination in SDRAM : source in PCI */
TransferDirection = dmaPCI_TO_SDRAM;
PCIAddress = Source;
SDRAMPreAlignAddress = Destination;
}
}
else /* destination not in SDRAM */
{
/* make sure that at least the Source is in SDRAM */
if ( ( Source > SDRAMBegin ) && ( Source < SDRAMEnd ) )
{
/* source in SDRAM : destination in PCI */
TransferDirection = dmaSDRAM_TO_PCI;
PCIAddress = Destination;
SDRAMPreAlignAddress = Source;
}
else
{
PRINTF ((
"tmPCI:Error:Source[%x] & Destination[%x] outside SDRAM[%x:%x]\n",
Source, Destination, SDRAMBegin, SDRAMEnd ));
return PCI_ERR_SDRAM_RANGE;
/* error - neither source nor destination in sdram */
}
}
/*
the entire SDRAM transfer buffer is broken down into 3 blocks
1. a cache aligned block of length = integral multiple of cache size
2. the protion of the buffer before the cache aligned block.
3. the protion of the buffer after before the cache aligned block.
*/
SDRAMCacheAlignAddress = (UInt8*)ALIGN((UInt32)SDRAMPreAlignAddress, DCACHE_PAGE_SIZE);
SDRAMPreAlignLength = ALIGN((UInt32)SDRAMPreAlignAddress, DCACHE_PAGE_SIZE) - (UInt32)SDRAMPreAlignAddress;
SDRAMCacheAlignLength = ( ( Length - SDRAMPreAlignLength ) / DCACHE_PAGE_SIZE ) * DCACHE_PAGE_SIZE;
SDRAMPostAlignAddress = (UInt8*)(((UInt32)SDRAMPreAlignAddress) + SDRAMPreAlignLength + SDRAMCacheAlignLength);
SDRAMPostAlignLength = Length - ( SDRAMCacheAlignLength + SDRAMPreAlignLength);
PRINTF ((
"tmPCI:PreAddr[%x]:PreLen[%x]:CacheAddr[%x]:Cachelen[%x]:PostAddr[%x]:PostLen[%x]\n",
SDRAMPreAlignAddress,
SDRAMPreAlignLength,
SDRAMCacheAlignAddress,
SDRAMCacheAlignLength,
SDRAMPostAlignAddress,
SDRAMPostAlignLength ));
if ( (ErrorCode = dmaOpen(&Instance) ))
{
PRINTF ((
"tmPCI:Error:dmaOpen:FAIL[%x]\n", ErrorCode ));
return (ErrorCode);
}
_cache_copyback(SDRAMCacheAlignAddress, SDRAMCacheAlignLength);
/* the request contains 1 description */
DMARequest.slack_function = Null;/*slackFunc; */
DMARequest.completion_function = Null; /*compFunc; */
DMARequest.nr_of_descriptions = 1;
DMARequest.mode = dmaSynchronous;
DMARequest.done = 0;
/* this description contains four transfers */
if ( TransferDirection == dmaSDRAM_TO_PCI )
{
DMARequest.descriptions[0].direction = dmaSDRAM_TO_PCI;
DMARequest.descriptions[0].source = (void *) SDRAMCacheAlignAddress;
DMARequest.descriptions[0].destination = (void *)(PCIAddress + SDRAMPreAlignLength);
}
else
{
DMARequest.descriptions[0].direction = dmaPCI_TO_SDRAM;
DMARequest.descriptions[0].source = (void *)(PCIAddress + SDRAMPreAlignLength);
DMARequest.descriptions[0].destination = (void *) SDRAMCacheAlignAddress;
}
DMARequest.descriptions[0].write_and_invalidate = 1;
DMARequest.descriptions[0].length = SDRAMCacheAlignLength;
DMARequest.descriptions[0].nr_of_transfers = 1;
DMARequest.descriptions[0].source_stride = SDRAMCacheAlignLength;
DMARequest.descriptions[0].destination_stride = SDRAMCacheAlignLength;
if ( ( ErrorCode = dmaDispatch(Instance, &DMARequest) ) )
{
PRINTF ((
"tmPCI:Error:dmaDispatch:FAIL[%x]\n", ErrorCode ));
return (ErrorCode);
}
_cache_invalidate(SDRAMCacheAlignAddress, SDRAMCacheAlignLength);
dmaClose ( Instance );
if ( TransferDirection == dmaSDRAM_TO_PCI )
{
pciDWORDAlignedCopy (
Destination,
SDRAMPreAlignAddress,
SDRAMPreAlignLength,
( ALIGN( (UInt32)Destination, sizeof (UInt32) ) - (UInt32)Destination ) );
pciDWORDAlignedCopy (
Destination + SDRAMPreAlignLength + SDRAMCacheAlignLength,
SDRAMPostAlignAddress,
SDRAMPostAlignLength,
( ALIGN( (UInt32)Destination + SDRAMPreAlignLength + SDRAMCacheAlignLength,
sizeof (UInt32) ) - ((UInt32)Destination + SDRAMPreAlignLength + SDRAMCacheAlignLength )) );
}
else
{
pciDWORDAlignedCopy (
SDRAMPreAlignAddress,
Source,
SDRAMPreAlignLength,
( ALIGN( (UInt32)Source, sizeof (UInt32) ) - (UInt32)Source ) );
pciDWORDAlignedCopy (
SDRAMPostAlignAddress,
Source + SDRAMPreAlignLength + SDRAMCacheAlignLength,
SDRAMPostAlignLength,
( ALIGN( (UInt32)Source + SDRAMPreAlignLength + SDRAMCacheAlignLength,
sizeof (UInt32) ) - ((UInt32)Source + SDRAMPreAlignLength + SDRAMCacheAlignLength) ) );
}
return TMLIBDEV_OK;
}
extern
tmLibdevErr_t
pciIOReadUInt8(
UInt32 address,
UInt32* Data )
{
#pragma TCS_atomic
UInt32 Shift,Res;
UInt32 byte_enable;
Shift = address & 0x03;
byte_enable = ~(0x01 << Shift) & 0x0F;
/*poll until previous I/O transaction completes */
while (MMIO(BIU_STATUS) & PCI_IO_BUSY)
{
;
}
/*clear the DONE bit */
MMIO(BIU_STATUS) = PCI_IO_DONE;
MMIO(IO_ADR) = address;
MMIO(IO_CTL) = PCI_IO_READ | byte_enable;
/* poll until I/O cycle done */
while ((MMIO(BIU_STATUS) & PCI_IO_DONE) == 0)
{
;
}
/* get the value and clear the DONE bit */
Res = MMIO(IO_DATA);
MMIO(BIU_STATUS) = PCI_IO_DONE;
Res >>=(Shift*8);
*Data = (Res & 0xFF);
return TMLIBDEV_OK;
}
extern
tmLibdevErr_t
pciIOWriteUInt8(
UInt32 address,
UInt32 Data)
{
#pragma TCS_atomic
UInt32 Shift;
UInt32 byte_enable;
Shift = address & 0x03;
byte_enable = ~(0x01 << Shift) & 0x0F;
Data <<=(Shift*8);
/* poll until previous I/O transaction completes */
while (MMIO(BIU_STATUS) & PCI_IO_BUSY)
{
;
}
/* clear the DONE bit */
MMIO(BIU_STATUS) = PCI_IO_DONE;
/* perform the write */
MMIO(IO_ADR) = address;
MMIO(IO_DATA) = Data;
MMIO(IO_CTL) = PCI_IO_WRITE | byte_enable;
/* poll until I/O cycle done */
while ((MMIO(BIU_STATUS) & PCI_IO_DONE) == 0)
{
;
}
/* clear the DONE bit */
MMIO(BIU_STATUS) = PCI_IO_DONE;
return TMLIBDEV_OK;
}
/*-------------------------------------------------------------------------*/
/*--------------------LOCAL FUNCTIONS--------------------------------------*/
/*-------------------------------------------------------------------------*/
static void pciDWORDAlignedCopy (
UInt8* Destination,
UInt8* Source,
UInt32 Length,
UInt32 AlignmentBase )
{
UInt32 Copied, Idx;
UInt32* Dest32, *Src32;
UInt32 GlobalInterruptState;
UInt32 DCLockCtlState;
GlobalInterruptState = intCLEAR_IEN();
DCLockCtlState = pciExtractDC_LOCK();
pciSetDC_LOCK(PCI_DC_LOCK_CTL_HDS);
Copied = AlignmentBase;
PRINTF ((
"tmPCI:pciDWORDAlignedCopy1:Dst[%x]:Src[%x]:Len[%x]\n",
Destination, Source, Copied ));
switch ( Copied )
{
case 3:
*Destination++ = *Source++;
case 2:
*Destination++ = *Source++;
case 1:
*Destination++ = *Source++;
break;
case 0:
default:
break;
}
PRINTF ((
"tmPCI:pciDWORDAlignedCopy2:Dst[%x]:Src[%x]:Len[%x]\n",
Destination, Source, (Length/sizeof(UInt32))*sizeof(UInt32) ));
Dest32 = (UInt32*)Destination;
Src32 = (UInt32*)Source;
for ( Idx = 0 ; Idx < Length/sizeof(UInt32) ; Idx ++, Copied+= sizeof(UInt32) )
{
*Dest32++ = *Src32++;
}
Destination = (UInt8*)Dest32;
Source = (UInt8*)Src32;
PRINTF ((
"tmPCI:pciDWORDAlignedCopy3:Dst[%x]:Src[%x]:Len[%x]\n",
Destination, Source, Length - Copied ));
switch ( Length - Copied )
{
case 3:
*Destination++ = *Source++;
case 2:
*Destination++ = *Source++;
case 1:
*Destination++ = *Source++;
break;
case 0:
default:
break;
}
pciSetDC_LOCK(DCLockCtlState);
intRESTORE_IEN(GlobalInterruptState);
}
/*---------------------------------------------------------------------------
Check PCI config cycle status
Input: "bits" to check
Return Value: 0 if BIU_STATUS & bits == 0
1 if timed out or an error
---------------------------------------------------------------------------*/
static int pciConfigStatus (UInt32 bits, UInt32 zero_flag)
{
int timeout = 0;
unsigned biu_status, x;
while (timeout < CONFIG_TIMEOUT)
{
biu_status = MMIO(BIU_STATUS) ;
if ((biu_status & 0x100) != 0)
{
/*DP(("duplicate config bit set after busy wait\n")); */
}
x = (biu_status & bits);
if (zero_flag)
{
if (x == 0)
{
break;
}
}
else
{
if (x != 0)
{
break;
}
}
timeout++ ;
}
if (timeout >= CONFIG_TIMEOUT)
{
return 1;
}
else
{
return 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -