os/kernelhwsrv/kernel/eka/drivers/pbus/pccard/epoc/pccd_chunk.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32\drivers\pbus\pccard\epoc\pccd_chunk.cpp
    15 // 
    16 //
    17 
    18 #include <pccd_chunk.h>
    19 
    20 DPlatPccdChunk::DPlatPccdChunk()
    21 //
    22 // Constructor
    23 //
    24 	: DPccdChunkBase()
    25 	{
    26 //	iChunk=NULL;
    27 //	iFlag=0;
    28 	}
    29 
    30 DPlatPccdChunk::~DPlatPccdChunk()
    31 //
    32 // Destroy (base class destructor called after this)
    33 //
    34 	{
    35 	__KTRACE_OPT(KPBUS1,Kern::Printf(">PlatChunk:~PlatChunk(P:%xH,C:%xH)",iChunk,this));
    36 	}
    37 
    38 void DPlatPccdChunk::Close()
    39 //
    40 // Destroy (base class destructor called after this)
    41 //
    42 	{
    43 	__KTRACE_OPT(KPBUS1,Kern::Printf(">PlatChunk:Close(P:%xH,C:%xH)",iChunk,this));
    44 
    45 	Kern::SafeClose((DObject*&)iChunk,NULL);
    46 	DPccdChunkBase::Close();
    47 	}
    48 
    49 TInt DPlatPccdChunk::DoCreate(TPccdChnk aChunk, TUint aFlag)
    50 //
    51 // Create a chunk of Pc Card h/w. Base addresses are rounded down to a page size boundary and
    52 // chunk sizes are rounded up in size to a whole page.
    53 //
    54 	{
    55 	__KTRACE_OPT(KPBUS2,Kern::Printf(">PlatChunk::DoCreate"));
    56 	// Round base address down to page size boundary, then calculate physical addresss for this chunk.
    57 	TUint32 pageSize=Kern::RoundToPageSize(1);
    58 	iChnk.iMemBaseAddr&=~(pageSize-1); 	// Round it down.
    59 	TUint32 roundingOffset=aChunk.iMemBaseAddr-iChnk.iMemBaseAddr;
    60 	TUint32 physAddr=iChnk.iMemBaseAddr;
    61 	physAddr+=ThePccdCntrlInterface->MemPhysicalAddress(iSocket->iSocketNumber,iChnk.iMemType);
    62 
    63 	// Round size (plus anything gained in rounding base address) up to page size
    64 	iChnk.iMemLen=Kern::RoundToPageSize(iChnk.iMemLen+roundingOffset);
    65 
    66 	TInt attribs=EMapAttrSupRw;
    67 	if (iCacheable)
    68 		attribs |= EMapAttrCachedMax;
    69 
    70 	__KTRACE_OPT(KPBUS1,Kern::Printf("PlatChunk:DoCreate(L:%xH PA:%xH)",iChnk.iMemLen,physAddr));
    71 	TInt r=DPlatChunkHw::New(iChunk, physAddr, iChnk.iMemLen, attribs);
    72 	if (r!=KErrNone)
    73 		{
    74 		iChunk=NULL;
    75 		return r;
    76 		}
    77 	__KTRACE_OPT(KPBUS2,Kern::Printf("PlatChunk(%xH):DoCreate(LA:%xH)",iChunk,iChunk->LinearAddress()));
    78 
    79 	return KErrNone;
    80 	}
    81 	
    82 TInt DPlatPccdChunk::SetupChunkHw(TPccdAccessSpeed aSpeed,TPccdMemType aMemType,TBool aWaitSig,TUint aFlag)
    83 //
    84 // Config h/w in preparation for accessing chunk
    85 //
    86 	{
    87 
    88 	__KTRACE_OPT(KPBUS2,Kern::Printf("PlatChunk:SetupChunkHw(SP:%d CT:%d RT:%d W:%d F:%d)",aSpeed,iChnk.iMemType,aMemType,aWaitSig,aFlag));
    89 	if (ThePccdCntrlInterface->MemConfig(iSocket->iSocketNumber,aMemType,aSpeed,aWaitSig,aFlag)==KMemConfigByteAccess)
    90 		{
    91 		iFlag|=KPccdChunkByteAccessOnly;
    92 		__KTRACE_OPT(KPBUS2,Kern::Printf("Byte access only"));
    93 		}
    94 	return(KErrNone);
    95 	}
    96 
    97 TLinAddr DPlatPccdChunk::LinearAddress()
    98 //
    99 // Return linear address of window
   100 //
   101 	{
   102 	TLinAddr a=iChunk->LinearAddress();
   103 	__KTRACE_OPT(KPBUS2,Kern::Printf("<PlatChunk(%xH):LinAddr(%xH)",iChunk,a));
   104 	return a;
   105 	}
   106 
   107 TInt DPlatPccdChunk::Read(TInt aPos,TAny *aPtr,TInt aLength)
   108 //
   109 // Perform a read (length always in bytes)
   110 //
   111 	{
   112 
   113 	__KTRACE_OPT(KPBUS2,Kern::Printf("PlatChunk(%xH):Read(%xH from %08xH)",iChunk,aLength,aPos));
   114 
   115 	volatile TUint8 *pData=(volatile TUint8*)(iChunk->LinearAddress()+aPos);
   116 	if (!(iFlag&KPccdChunkByteAccessOnly))
   117 		{
   118         if (aLength==1)             // Probably the ATA command.
   119             *(TUint8*)aPtr=*pData;
   120         else
   121     		memcpy(aPtr,(TAny*)pData,aLength);
   122         }
   123     else
   124         {
   125 		// Byte copy
   126 		TUint8 *pT=(TUint8*)aPtr;
   127 		TUint8 *pTE=pT+aLength;
   128 		for (;pT<pTE;)
   129 			*pT++=*pData++;
   130 		}
   131 
   132 	return(KErrNone);
   133 	}
   134 
   135 TInt DPlatPccdChunk::Write(TInt aPos,const TAny *aPtr,TInt aLength)
   136 //
   137 // Perform a write (length always in bytes)
   138 //
   139 	{
   140 
   141 	__KTRACE_OPT(KPBUS2,Kern::Printf("PlatChunk(%xH):Write(%xH to %08xH)",iChunk,aLength,aPos));
   142 
   143 	volatile TUint8 *pData=(volatile TUint8*)((iChunk->LinearAddress())+aPos);
   144 	if (!(iFlag&KPccdChunkByteAccessOnly))
   145         {
   146         if (aLength==1)             // Probably the ATA command.
   147             *pData=*(TUint8*)aPtr;
   148         else
   149       		memcpy((TAny*)pData,aPtr,aLength);
   150         }
   151     else
   152 		{
   153 		// Byte copy
   154 		TUint8 *pS=(TUint8*)aPtr;
   155 		TUint8 *pSE=pS+aLength;
   156 		for (;pS<pSE;)
   157             *pData++=*pS++;
   158 		}
   159 
   160 	return(KErrNone);
   161 	}
   162 
   163 TInt DPlatPccdChunk::ReadByteMultiple(TInt aPos,TAny *aPtr,TInt aCount)
   164 //
   165 // Perform a multiple read from a single byte (aCount in bytes)
   166 //
   167 	{
   168 
   169 	__KTRACE_OPT(KPBUS2,Kern::Printf("PlatChunk(%xH):ReadByteMult(%xH from %08xH)",iChunk,aCount,aPos));
   170 
   171 	volatile TUint8 *pS=(volatile TUint8*)((iChunk->LinearAddress())+aPos);
   172 	TUint8 *pT=(TUint8*)aPtr;
   173 	TUint8 *pTE=pT+aCount;
   174 	for (;pT<pTE;)
   175 		*pT++=*pS;
   176 
   177 	return(KErrNone);
   178 	}
   179 
   180 TInt DPlatPccdChunk::WriteByteMultiple(TInt aPos,const TAny *aPtr,TInt aCount)
   181 //
   182 // Perform a multiple write to a single byte (aCount in bytes)
   183 //
   184 	{
   185 
   186 	__KTRACE_OPT(KPBUS2,Kern::Printf("PlatChunk(%xH):WriteByteMult(%xH to %08xH)",iChunk,aCount,aPos));
   187 
   188 	volatile TUint8 *pT=(volatile TUint8*)((iChunk->LinearAddress())+aPos);
   189 	TUint8 *pS=(TUint8*)aPtr;
   190 	TUint8 *pSE=pS+aCount;
   191 	for (;pS<pSE;)
   192 		*pT=*pS++;
   193 
   194 	return(KErrNone);
   195 	}
   196 
   197 #ifndef __PCCD_MACHINE_CODED__
   198 TInt DPlatPccdChunk::ReadHWordMultiple(TInt aPos,TAny *aPtr,TInt aCount)
   199 //
   200 // Perform a series of reads of 16bit halfwords from a single location in the chunk (aCount is in hwords).
   201 //
   202 	{
   203 
   204 	__KTRACE_OPT(KPBUS2,Kern::Printf(">PlatChunk(%xH):ReadHWordMult(%xH from %08xH)",iChunk,aCount,aPos));
   205 
   206 	volatile TUint16 *pS=(volatile TUint16*)((iChunk->LinearAddress())+aPos);
   207 	TUint16 *pT=(TUint16*)aPtr;
   208 	TUint16 *pTE=pT+aCount;
   209 	for (;pT<pTE;)
   210         *pT++=(TUint16)*pS;
   211 
   212 	__KTRACE_OPT(KPBUS2,Kern::Printf("<RHWM"));
   213 	return(KErrNone);
   214 	}
   215 
   216 TInt DPlatPccdChunk::WriteHWordMultiple(TInt aPos,const TAny *aPtr,TInt aCount)
   217 //
   218 // Perform a series of writes of 16bit halfwords to a single location in the chunk (aCount is in hwords).
   219 //
   220 	{
   221 
   222 	__KTRACE_OPT(KPBUS2,Kern::Printf(">PlatChunk(%xH):WriteHWordMult(%xH to %08xH)",iChunk,aCount,aPos));
   223 
   224 	volatile TUint16 *pT=(volatile TUint16*)((iChunk->LinearAddress())+aPos);
   225 	TUint16 *pS=(TUint16*)aPtr;
   226 	TUint16 *pSE=(pS+aCount);
   227 	for (;pS<pSE;)
   228 	    *pT=*pS++;
   229 
   230 	__KTRACE_OPT(KPBUS2,Kern::Printf("<WHWM"));
   231 	return(KErrNone);
   232 	}
   233 
   234 TUint DPlatPccdChunk::Read8(TInt aPos)
   235 	{
   236 	volatile TUint8 *pT=(volatile TUint8*)((iChunk->LinearAddress())+aPos);
   237 	return *pT;
   238 	}
   239 
   240 void DPlatPccdChunk::Write8(TInt aPos, TUint aValue)
   241 	{
   242 	volatile TUint8 *pT=(volatile TUint8*)((iChunk->LinearAddress())+aPos);
   243 	*pT=(TUint8)aValue;
   244 	}
   245 #endif
   246 
   247 TBool DPlatPccdChunk::IsTypeCompatible(TPccdMemType aMemType)
   248 //
   249 // Check if this chunk type is compatible with specified type
   250 //
   251 	{
   252 
   253 	if (aMemType==iChnk.iMemType)
   254 		return(ETrue);
   255 	if ((aMemType==EPccdAttribMem||aMemType==EPccdCommon8Mem)&&(iChnk.iMemType==EPccdAttribMem||iChnk.iMemType==EPccdCommon8Mem))
   256 		return(ETrue);
   257 	return(EFalse);
   258 	}
   259