PassRefPtr<SharedMemory> SharedMemory::create(size_t size) { // On Symbian, global chunks (shared memory segments) have system-unique names, so we pick a random // number from the kernel's random pool and use it as a string. // Using an integer simplifies serialization of the name in Handle::encode() uint32_t random = Math::Random(); TBuf<KMaxKernelName> chunkName; chunkName.Format(_L("%d"), random); RChunk chunk; TInt error = chunk.CreateGlobal(chunkName, size, size); if (error) { qCritical() << "Failed to create WK2 shared memory of size " << size << " with error " << error; return 0; } RefPtr<SharedMemory> sharedMemory(adoptRef(new SharedMemory)); sharedMemory->m_handle = chunk.Handle(); sharedMemory->m_size = chunk.Size(); sharedMemory->m_data = static_cast<void*>(chunk.Base()); return sharedMemory.release(); }
PassRefPtr<SharedMemory> SharedMemory::create(const Handle& handle, Protection protection) { if (handle.isNull()) return 0; // Convert number to string, and open the global chunk TBuf<KMaxKernelName> chunkName; chunkName.Format(_L("%d"), handle.m_chunkID); RChunk chunk; // NOTE: Symbian OS doesn't support read-only global chunks. TInt error = chunk.OpenGlobal(chunkName, false); if (error) { qCritical() << "Failed to create WK2 shared memory from handle " << error; return 0; } chunk.Adjust(chunk.MaxSize()); RefPtr<SharedMemory> sharedMemory(adoptRef(new SharedMemory)); sharedMemory->m_handle = chunk.Handle(); sharedMemory->m_size = chunk.Size(); sharedMemory->m_data = static_cast<void*>(chunk.Base()); return sharedMemory.release(); }
void RDmaSession::SelfTest(TBool aSimulatedDmac) { test.Start(_L("Simple transfer test")); RDmaSession session; TInt r = KErrUnknown; if (aSimulatedDmac) { test.Next(_L("Open session (simulated DMA)")); r = session.OpenSim(); } else { test.Next(_L("Open session")); r = session.Open(); } test_KErrNone(r); test.Next(_L("Get test info")); TDmaV2TestInfo testInfo; r = session.GetTestInfo(testInfo); test_KErrNone(r); if(gVerboseOutput) { Print(testInfo); } // Self test just needs 1 channel // The real test will test all available ones test.Next(_L("Select test channel")); TUint testChannel = 0; if(testInfo.iMaxSbChannels > 0) { testChannel = testInfo.iSbChannels[0]; } else if(testInfo.iMaxDbChannels > 0) { testChannel = testInfo.iDbChannels[0]; } else if(testInfo.iMaxSgChannels > 0) { testChannel = testInfo.iSgChannels[0]; } else { test.Printf(_L("Driver exposes no channels to test")); test(EFalse); } test.Printf(_L("using PSL cookie %d (0x%08x)\n"), testChannel, testChannel); test.Next(_L("Open channel")); TUint channelCookie=0; r = session.ChannelOpen(testChannel, channelCookie); test.Printf(_L("cookie recived = 0x%08x\n"), channelCookie); test_KErrNone(r); test.Next(_L("Get Channel caps")); SDmacCaps channelCaps; r = session.ChannelCaps(channelCookie, channelCaps); test_KErrNone(r); if(gVerboseOutput) { PRINT(channelCaps.iChannelPriorities); PRINT(channelCaps.iChannelPauseAndResume); PRINT(channelCaps.iAddrAlignedToElementSize); PRINT(channelCaps.i1DIndexAddressing); PRINT(channelCaps.i2DIndexAddressing); PRINT(channelCaps.iSynchronizationTypes); PRINT(channelCaps.iBurstTransactions); PRINT(channelCaps.iDescriptorInterrupt); PRINT(channelCaps.iFrameInterrupt); PRINT(channelCaps.iLinkedListPausedInterrupt); PRINT(channelCaps.iEndiannessConversion); PRINT(channelCaps.iGraphicsOps); PRINT(channelCaps.iRepeatingTransfers); PRINT(channelCaps.iChannelLinking); PRINT(channelCaps.iHwDescriptors); PRINT(channelCaps.iSrcDstAsymmetry); PRINT(channelCaps.iAsymHwDescriptors); PRINT(channelCaps.iBalancedAsymSegments); PRINT(channelCaps.iAsymCompletionInterrupt); PRINT(channelCaps.iAsymDescriptorInterrupt); PRINT(channelCaps.iAsymFrameInterrupt); PRINT(channelCaps.iReserved[0]); PRINT(channelCaps.iReserved[1]); PRINT(channelCaps.iReserved[2]); PRINT(channelCaps.iReserved[3]); PRINT(channelCaps.iReserved[4]); } test.Next(_L("Get extended Channel caps (TDmacTestCaps)")); TDmacTestCaps extChannelCaps; r = session.ChannelCaps(channelCookie, extChannelCaps); test_KErrNone(r); test.Printf(_L("PIL version = %d\n"), extChannelCaps.iPILVersion); const TBool newPil = (extChannelCaps.iPILVersion > 1); test.Next(_L("Create Dma request - max fragment size 32K")); TUint reqCookie=0; r = session.RequestCreateOld(channelCookie, reqCookie, 32 * KKilo); test.Printf(_L("cookie recived = 0x%08x\n"), reqCookie); test_KErrNone(r); if(newPil) { test.Next(_L("Create Dma request (with new-style callback)")); TUint reqCookieNewStyle=0; r = session.RequestCreate(channelCookie, reqCookieNewStyle); test.Printf(_L("cookie recived = 0x%08x\n"), reqCookieNewStyle ); test_KErrNone(r); if(!aSimulatedDmac) { test.Next(_L("Fragment for ISR callback")); const TInt size = 128 * KKilo; TDmaTransferArgs transferArgs(0, size, size, KDmaMemAddr, KDmaSyncAuto, KDmaRequestCallbackFromIsr); r = session.FragmentRequest(reqCookieNewStyle, transferArgs); test_KErrNone(r); TIsrRequeArgs reque; test.Next(_L("Queue ISR callback - with default re-queue")); r = session.QueueRequestWithRequeue(reqCookieNewStyle, &reque, 1); test_KErrNone(r); } test.Next(_L("Destroy new-style Dma request")); r = session.RequestDestroy(reqCookieNewStyle); test_KErrNone(r); test.Next(_L("Attempt to destroy request again ")); r = session.RequestDestroy(reqCookieNewStyle); test_Equal(KErrNotFound, r); } test.Next(_L("Open chunk handle")); RChunk chunk; r = session.OpenSharedChunk(chunk); test_KErrNone(r); if(gVerboseOutput) { test.Printf(_L("chunk base = 0x%08x\n"), chunk.Base()); test.Printf(_L("chunk size = %d\n"), chunk.Size()); } test(chunk.IsWritable()); test(chunk.IsReadable()); if(!aSimulatedDmac) { test.Next(_L("Fragment(old style)")); const TInt size = 128 * KKilo; TInt i; for(i = 0; i<10; i++) { TUint64 time = 0; TDmaTransferArgs transferArgs(0, size, size, KDmaMemAddr); r = session.FragmentRequestOld(reqCookie, transferArgs, &time); test_KErrNone(r); if(gVerboseOutput) { test.Printf(_L("%lu us\n"), time); } } test.Next(_L("Queue")); TRequestStatus status; for(i = 0; i<10; i++) { TUint64 time = 0; r = session.QueueRequest(reqCookie, status, 0, &time); User::WaitForRequest(status); test_KErrNone(r); if(gVerboseOutput) { test.Printf(_L("%lu us\n"), time); } } if(newPil) { test.Next(_L("Fragment(new style)")); TDmaTransferArgs transferArgs; transferArgs.iSrcConfig.iAddr = 0; transferArgs.iDstConfig.iAddr = size; transferArgs.iSrcConfig.iFlags = KDmaMemAddr; transferArgs.iDstConfig.iFlags = KDmaMemAddr; transferArgs.iTransferCount = size; for(i = 0; i<10; i++) { TUint64 time = 0; r = session.FragmentRequest(reqCookie, transferArgs, &time); test_KErrNone(r); if(gVerboseOutput) { test.Printf(_L("%lu us\n"), time); } } } test.Next(_L("Queue")); TCallbackRecord record; r = session.QueueRequest(reqCookie, &record); test_KErrNone(r); test.Next(_L("check TCallbackRecord record")); if(gVerboseOutput) { record.Print(); } const TCallbackRecord expected(TCallbackRecord::EThread, 1); if(!(record == expected)) { test.Printf(_L("TCallbackRecords did not match")); if(gVerboseOutput) { test.Printf(_L("expected:")); expected.Print(); } TEST_FAULT; } } test.Next(_L("Destroy Dma request")); r = session.RequestDestroy(reqCookie); test_KErrNone(r); test.Next(_L("Close chunk handle")); chunk.Close(); test.Next(_L("Channel close")); r = session.ChannelClose(channelCookie); test_KErrNone(r); test.Next(_L("Channel close (same again)")); r = session.ChannelClose(channelCookie); test_Equal(KErrNotFound, r); test.Next(_L("Close session")); RTest::CloseHandleAndWaitForDestruction(session); test.End(); }