--- a/kernel/eka/drivers/locmedia/locmedia.cpp Wed Jun 23 11:59:44 2010 +0100
+++ b/kernel/eka/drivers/locmedia/locmedia.cpp Wed Jun 23 12:52:28 2010 +0100
@@ -78,6 +78,7 @@
#ifdef __DEMAND_PAGING__
DMediaPagingDevice* iPagingDevice;
TInt iPageSizeMsk; // Mask of page size (e.g. 4096-1 -> 4095)
+ TInt iPageSizeLog2; // LOG2 of page size (i.e. 4096 -> 12)
TInt iMediaChanges;
#endif
@@ -1529,6 +1530,10 @@
RemoteDes()=(TAny*)d.iPtr;
RemoteDesOffset()=d.iOffset;
DriverFlags()=d.iFlags;
+
+ // EPhysAddrOnly should not be set for client requests
+ Flags() &= ~TLocDrvRequest::EPhysAddrOnly;
+
if (Pos()<0 || Length()<0)
{
OstTraceFunctionExitExt( TLOCDRVREQUEST_PROCESSMESSAGEDATA_EXIT2, this, KErrArgument );
@@ -1828,6 +1833,7 @@
#ifdef __DEMAND_PAGING__
TInt pageSize = Kern::RoundToPageSize(1);
iBody->iPageSizeMsk = pageSize-1;
+ iBody->iPageSizeLog2 = __e32_find_ms1_32(pageSize);
#endif
iLastMediaId=aLastMediaId;
@@ -4070,19 +4076,23 @@
TInt len = I64LOW(m.Length());
TBool needSyncAfterRead = EFalse;
- if (m.Drive()->iDmaHelper)
- {
- m.Flags() |= TLocDrvRequest::EPhysAddr;
- if (m.Id() == DLocalDrive::EWrite)
- {
- Cache::SyncMemoryBeforeDmaWrite(addr, len);
- }
- else
- {
- Cache::SyncMemoryBeforeDmaRead(addr, len);
- needSyncAfterRead = ETrue;
- }
- }
+ if (m.Drive()->iDmaHelper)
+ {
+ m.Flags() |= TLocDrvRequest::EPhysAddr;
+ // don't cache sync for zero mapping...
+ if (!(m.Flags() & TLocDrvRequest::EPhysAddrOnly))
+ {
+ if (m.Id() == DLocalDrive::EWrite)
+ {
+ Cache::SyncMemoryBeforeDmaWrite(addr, len);
+ }
+ else
+ {
+ Cache::SyncMemoryBeforeDmaRead(addr, len);
+ needSyncAfterRead = ETrue;
+ }
+ }
+ }
// Count the number of outstanding requests if this is the data-paging media, so that
// we can call DPagingDevice::NotifyBusy() / DPagingDevice::NotifyIdle()
@@ -4139,6 +4149,17 @@
}
TInt DMediaPagingDevice::Read(TThreadMessage* aReq,TLinAddr aBuffer,TUint aOffset,TUint aSize,TInt aDrvNumber)
+ {
+ return BaseRead(aReq,(TUint32)aBuffer,aOffset,aSize,aDrvNumber,EFalse);
+ }
+
+TInt DMediaPagingDevice::ReadPhysical(TThreadMessage* aReq, TPhysAddr* aPageArray, TUint aPageCount, TUint aOffset, TInt aDrvNumber)
+ {
+ TUint adjSize = (aPageCount << iPrimaryMedia->iBody->iPageSizeLog2) >> iReadUnitShift; // translate to Read Units
+ return BaseRead(aReq,(TUint32)aPageArray,aOffset,adjSize,aDrvNumber,ETrue);
+ }
+
+TInt DMediaPagingDevice::BaseRead(TThreadMessage* aReq,TUint32 aBuffer,TUint aOffset,TUint aSize,TInt aDrvNumber, TBool aPhysAddr)
{
OstTraceFunctionEntry1( DMEDIAPAGINGDEVICE_READ_ENTRY, this );
__ASSERT_ALWAYS(NKern::CurrentThread()!=iPrimaryMedia->iDfcQ->iThread,LOCM_FAULT()); // that would lock up the system, thus better die now
@@ -4287,7 +4308,10 @@
m.Length()=Int64(size);
m.RemoteDes()=(TAny*)aBuffer;
m.RemoteDesOffset()=0; // pre-aligned
- m.DriverFlags()=0;
+ m.DriverFlags() = 0;
+ if (aPhysAddr)
+ m.Flags() |= TLocDrvRequest::EPhysAddrOnly;
+
__KTRACE_OPT2(KLOCDRV,KLOCDPAGING,Kern::Printf("ReqId=%d, Pos=0x%lx, Len=0x%lx, remote Des 0x%x",m.Id(),m.Pos(),m.Length(),m.RemoteDes()));
OstTraceDefExt2(OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DMEDIAPAGINGDEVICE_READ2, "reqId=%d; remote Des=0x%x", (TInt) m.Id(), (TUint) m.RemoteDes());
OstTraceDefExt4(OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DMEDIAPAGINGDEVICE_READ3, "length=%x:%x, pos=%x:%x", (TUint) I64HIGH(m.Length()), (TUint) I64LOW(m.Length()), (TUint) I64HIGH(m.Pos()), (TUint) I64LOW(m.Pos()));
@@ -4336,7 +4360,18 @@
}
TInt DMediaPagingDevice::Write(TThreadMessage* aReq,TLinAddr aBuffer,TUint aOffset,TUint aSize,TBool aBackground)
- {
+ {
+ return BaseWrite(aReq,(TUint32)aBuffer,aOffset,aSize,aBackground,EFalse);
+ }
+
+TInt DMediaPagingDevice::WritePhysical(TThreadMessage* aReq, TPhysAddr* aPageArray, TUint aPageCount, TUint aOffset, TBool aBackground)
+ {
+ TUint adjSize = (aPageCount << iPrimaryMedia->iBody->iPageSizeLog2) >> iReadUnitShift; // translate to Read Units
+ return BaseWrite(aReq,(TUint32)aPageArray,aOffset,adjSize,aBackground,ETrue);
+ }
+
+TInt DMediaPagingDevice::BaseWrite(TThreadMessage* aReq,TUint32 aBuffer,TUint aOffset,TUint aSize,TBool aBackground, TBool aPhysAddr)
+ {
OstTraceFunctionEntry1( DMEDIAPAGINGDEVICE_WRITE_ENTRY, this );
__ASSERT_ALWAYS(NKern::CurrentThread()!=iPrimaryMedia->iDfcQ->iThread,LOCM_FAULT()); // that would lock up the system, thus better die now
__ASSERT_ALWAYS(aReq,LOCM_FAULT());
@@ -4396,7 +4431,11 @@
TInt retVal = KErrGeneral;
for (TInt i=0; retVal != KErrNone && i < KPageOutRetries; i++)
{
- m.Flags() = TLocDrvRequest::EKernelBuffer | TLocDrvRequest::EPaging | TLocDrvRequest::EDataPaging | (aBackground ? TLocDrvRequest::EBackgroundPaging : 0);
+ m.Flags() = TLocDrvRequest::EKernelBuffer |
+ TLocDrvRequest::EPaging |
+ TLocDrvRequest::EDataPaging |
+ (aBackground ? TLocDrvRequest::EBackgroundPaging : 0) |
+ (aPhysAddr ? TLocDrvRequest::EPhysAddrOnly : 0);
m.Id() = DLocalDrive::EWrite;
m.Drive() = TheDrives[iDataPagingDriveNumber];
@@ -4406,7 +4445,8 @@
m.Length()=Int64(size);
m.RemoteDes()=(TAny*)aBuffer;
m.RemoteDesOffset()=0; // pre-aligned
- m.DriverFlags()=0;
+ m.DriverFlags() = 0;
+
__KTRACE_OPT2(KLOCDRV,KLOCDPAGING,Kern::Printf("ReqId=%d, Pos=0x%lx, Len=0x%lx, remote Des 0x%x",m.Id(),m.Pos(),m.Length(),m.RemoteDes()));
OstTraceDefExt2(OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DMEDIAPAGINGDEVICE_WRITE2, "reqId=%d; remote Des=0x%x", (TInt) m.Id(), (TUint) m.RemoteDes());
OstTraceDefExt4(OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DMEDIAPAGINGDEVICE_WRITE3, "length=%x:%x, pos=%x:%x", (TUint) I64HIGH(m.Length()), (TUint) I64LOW(m.Length()), (TUint) I64HIGH(m.Pos()), (TUint) I64LOW(m.Pos()));
@@ -5267,6 +5307,8 @@
TInt dataPagingDriveNumber = KErrNotFound;
TInt swapSize = 0;
+ TInt blockSize = 0;
+ TUint16 flags = 0;
// find the local drive assocated with the primary media
for (i=0; i<KMaxLocalDrives; ++i)
@@ -5301,9 +5343,10 @@
TLocDrvRequest m;
+ TBuf8<KMaxLocalDriveCapsLength> capsBuf;
+
memclr(&m, sizeof(m));
-
// Get the Caps from the device. NB for MMC/SD we may need to retry as some PSLs start up
// in "door open" or "media not present" state which can result in the cancellation of requests
TInt i;
@@ -5311,7 +5354,6 @@
TInt r = KErrNotReady;
for (i=0; r == KErrNotReady && i < KRetries; i++)
{
- TBuf8<KMaxLocalDriveCapsLength> capsBuf;
capsBuf.SetMax();
capsBuf.FillZ();
m.Drive() = TheDrives[firstLocalDriveNumber];
@@ -5333,6 +5375,11 @@
return KErrNotSupported;
}
+ TLocalDriveCapsV6& caps = *(TLocalDriveCapsV6*)capsBuf.Ptr();
+ blockSize = caps.iBlockSize;
+ __ASSERT_DEBUG(blockSize,LOCM_FAULT());
+ __ASSERT_DEBUG(__e32_bit_count_32(blockSize)==1,LOCM_FAULT());
+
TLocDrv* drive;
for (i=0; i<KMaxLocalDrives; ++i)
{
@@ -5359,6 +5406,10 @@
dataPagingDriveNumber = i;
TheDataPagingDrive = drive;
swapSize = drive->iPartitionLen >> aReadShift;
+
+ // Mark Paging Device capable of utilising physical addresss only accesses
+ if (drive->iDmaHelper)
+ flags |= DPagingDevice::ESupportsPhysicalAccess;
}
}
}
@@ -5393,16 +5444,20 @@
pagingDevice->iDataPagingDriveNumber = dataPagingDriveNumber;
pagingDevice->iSwapSize = swapSize;
+
+ pagingDevice->iPreferredWriteShift = (blockSize) ? __e32_find_ms1_32(blockSize) : 0;
#ifdef __DEBUG_DEMAND_PAGING__
Kern::Printf("PagingDevice :");
Kern::Printf("Name %S", firstLocalDriveNumber >= 0 && DriveNames[firstLocalDriveNumber] ? DriveNames[firstLocalDriveNumber] : &KNullDesC8);
Kern::Printf("iType 0x%x", pagingDevice->iType);
+ Kern::Printf("iFlags 0x%x\n", pagingDevice->iFlags);
Kern::Printf("iReadUnitShift 0x%x", pagingDevice->iReadUnitShift);
Kern::Printf("iFirstLocalDriveNumber 0x%x", pagingDevice->iFirstLocalDriveNumber);
Kern::Printf("iRomPagingDriveNumber 0x%x", pagingDevice->iRomPagingDriveNumber);
Kern::Printf("iDataPagingDriveNumber 0x%x", pagingDevice->iDataPagingDriveNumber);
Kern::Printf("iSwapSize 0x%x", pagingDevice->iSwapSize);
+ Kern::Printf("iPreferredWriteShift 0x%x\n", pagingDevice->iPreferredWriteShift);
#endif