1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/personality/example/init.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,444 @@
1.4 +// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32test\personality\example\init.cpp
1.18 +// Test code for example RTOS personality.
1.19 +//
1.20 +//
1.21 +
1.22 +#include <kernel/kern_priv.h>
1.23 +#include <personality/example/personality.h>
1.24 +#include <personality/example/personality_int.h>
1.25 +#include "ifcldd.h"
1.26 +
1.27 +#define OC_TASK 0
1.28 +
1.29 +#define MSG_ID_INIT 1
1.30 +#define MSG_ID_RUN 2
1.31 +#define MSG_ID_RUN_P 3
1.32 +#define MSG_ID_RND_ISR 4
1.33 +#define MSG_ID_DONE 5
1.34 +#define MSG_ID_DATA 6
1.35 +#define MSG_ID_FLUSH 7
1.36 +#define MSG_ID_SEM_RPT 8
1.37 +#define MSG_ID_RCV_RPT 9
1.38 +#define MSG_ID_TM_RPT 10
1.39 +
1.40 +typedef struct _random_isr_msg
1.41 + {
1.42 + msghdr header;
1.43 + unsigned random_isr_number;
1.44 + unsigned extra;
1.45 + } random_isr_msg;
1.46 +
1.47 +typedef struct _data_msg
1.48 + {
1.49 + msghdr header;
1.50 + int length;
1.51 + unsigned char checksum;
1.52 + unsigned char data[1];
1.53 + } data_msg;
1.54 +
1.55 +typedef struct _report_msg
1.56 + {
1.57 + msghdr header;
1.58 + int pad;
1.59 + unsigned count;
1.60 + unsigned ok_count;
1.61 + unsigned bad_count;
1.62 + } report_msg;
1.63 +
1.64 +const TInt KMajorVersionNumber=0;
1.65 +const TInt KMinorVersionNumber=1;
1.66 +const TInt KBuildVersionNumber=1;
1.67 +
1.68 +void RxMsg(TAny* aPtr);
1.69 +
1.70 +TPMsgQ ThePMsgQ(&RxMsg, 0, Kern::DfcQue0(), 7);
1.71 +
1.72 +NONSHARABLE_CLASS(DRtosIfcFactory) : public DLogicalDevice
1.73 + {
1.74 +public:
1.75 + DRtosIfcFactory();
1.76 + virtual TInt Install(); //overriding pure virtual
1.77 + virtual void GetCaps(TDes8& aDes) const; //overriding pure virtual
1.78 + virtual TInt Create(DLogicalChannelBase*& aChannel); //overriding pure virtual
1.79 + };
1.80 +
1.81 +class TRxQ
1.82 + {
1.83 +public:
1.84 + TRxQ(DThread* aThread) : iFirst(0), iLast(0), iStatus(0), iPtr(0), iThread(aThread) {}
1.85 + TInt QueueReq(TRequestStatus* aStatus, TAny* aPtr);
1.86 + void AddMsg(msghdr* aM);
1.87 + inline TBool MsgPresent() {return iFirst!=NULL;}
1.88 + void CompleteReq();
1.89 + void CancelReq();
1.90 + void Close();
1.91 +public:
1.92 + msghdr* iFirst;
1.93 + msghdr* iLast;
1.94 + TRequestStatus* iStatus;
1.95 + TAny* iPtr;
1.96 + DThread* iThread;
1.97 + };
1.98 +
1.99 +TInt TRxQ::QueueReq(TRequestStatus* aStatus, TAny* aPtr)
1.100 + {
1.101 + if (iStatus)
1.102 + return KErrInUse;
1.103 + iStatus = aStatus;
1.104 + iPtr = aPtr;
1.105 + if (iFirst)
1.106 + CompleteReq();
1.107 + return KErrNone;
1.108 + }
1.109 +
1.110 +void TRxQ::AddMsg(msghdr* aM)
1.111 + {
1.112 + aM->next = NULL;
1.113 + if (iLast)
1.114 + iLast->next = aM;
1.115 + else
1.116 + iFirst = aM;
1.117 + iLast = aM;
1.118 + if (iStatus)
1.119 + CompleteReq();
1.120 + }
1.121 +
1.122 +void TRxQ::CompleteReq()
1.123 + {
1.124 + msghdr* m = iFirst;
1.125 + iFirst = m->next;
1.126 + if (!iFirst)
1.127 + iLast = NULL;
1.128 + TInt r = KErrNone;
1.129 + switch (m->msg_id)
1.130 + {
1.131 + case MSG_ID_DATA:
1.132 + {
1.133 + data_msg* dm = (data_msg*)m;
1.134 + r = Kern::ThreadRawWrite(iThread, iPtr, &dm->length, dm->length + 5, iThread);
1.135 + break;
1.136 + }
1.137 + case MSG_ID_SEM_RPT:
1.138 + case MSG_ID_RCV_RPT:
1.139 + case MSG_ID_TM_RPT:
1.140 + {
1.141 + report_msg* rpt = (report_msg*)m;
1.142 + rpt->pad = m->msg_id;
1.143 + r = Kern::ThreadRawWrite(iThread, iPtr, &rpt->pad, sizeof(SReport), iThread);
1.144 + break;
1.145 + }
1.146 + default:
1.147 + break;
1.148 + }
1.149 + free_mem_block(m);
1.150 + Kern::RequestComplete(iThread, iStatus, r);
1.151 + iStatus = NULL;
1.152 + }
1.153 +
1.154 +void TRxQ::CancelReq()
1.155 + {
1.156 + if (iStatus)
1.157 + Kern::RequestComplete(iThread, iStatus, KErrCancel);
1.158 + iStatus = NULL;
1.159 + }
1.160 +
1.161 +void TRxQ::Close()
1.162 + {
1.163 + CancelReq();
1.164 + while (iFirst)
1.165 + {
1.166 + msghdr* m = iFirst;
1.167 + iFirst = m->next;
1.168 + free_mem_block(m);
1.169 + }
1.170 + iFirst = NULL;
1.171 + iLast = NULL;
1.172 + }
1.173 +
1.174 +NONSHARABLE_CLASS(DRtosIfc) : public DLogicalChannel
1.175 + {
1.176 +public:
1.177 + DRtosIfc();
1.178 + virtual ~DRtosIfc();
1.179 +protected:
1.180 + virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
1.181 + virtual void HandleMsg(TMessageBase* aMsg);
1.182 +public:
1.183 + TInt DoControl(TInt aFunc, TAny* a1, TAny* a2);
1.184 + TInt DoRequest(TInt aFunc, TRequestStatus* aStatus, TAny* a1, TAny* a2);
1.185 + void DoCancel(TInt aMask);
1.186 + void HandleRtosMsg(msghdr* aMsg);
1.187 +public:
1.188 + DThread* iThread;
1.189 + TRequestStatus* iDoneStatus;
1.190 + TRxQ iRxQ;
1.191 + TRxQ iRptQ;
1.192 + };
1.193 +
1.194 +void RxMsg(TAny* aPtr)
1.195 + {
1.196 + msghdr* m = ThePMsgQ.Get();
1.197 + ((DRtosIfc*)aPtr)->HandleRtosMsg(m);
1.198 + }
1.199 +
1.200 +TInt EntryPoint()
1.201 + {
1.202 + TPMsgQ::ThePMsgQ = &::ThePMsgQ;
1.203 + init_personality();
1.204 +
1.205 + assert(current_task_id() == TASK_ID_UNKNOWN);
1.206 +
1.207 + kprintf("Entry point exit");
1.208 +
1.209 + return 0;
1.210 + }
1.211 +
1.212 +void SendInitMsg()
1.213 + {
1.214 + kprintf("Send init msg");
1.215 + msghdr* m = (msghdr*)alloc_mem_block(sizeof(msghdr));
1.216 + m->msg_id = MSG_ID_INIT;
1.217 + int r = send_msg(OC_TASK, m);
1.218 + assert(r == OK);
1.219 + }
1.220 +
1.221 +void SendFlushMsg()
1.222 + {
1.223 + msghdr* m = (msghdr*)alloc_mem_block(sizeof(msghdr));
1.224 + m->msg_id = MSG_ID_FLUSH;
1.225 + int r = send_msg(OC_TASK, m);
1.226 + assert(r == OK);
1.227 + }
1.228 +
1.229 +void SendFinishMsg()
1.230 + {
1.231 + msghdr* m = (msghdr*)alloc_mem_block(sizeof(msghdr));
1.232 + m->msg_id = MSG_ID_DONE;
1.233 + int r = send_msg(OC_TASK, m);
1.234 + assert(r == OK);
1.235 + }
1.236 +
1.237 +DRtosIfcFactory::DRtosIfcFactory()
1.238 + {
1.239 + iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
1.240 + //iParseMask=0;//No units, no info, no PDD
1.241 + //iUnitsMask=0;//Only one thing
1.242 + }
1.243 +
1.244 +TInt DRtosIfcFactory::Create(DLogicalChannelBase*& aChannel)
1.245 + {
1.246 + aChannel = new DRtosIfc;
1.247 + return aChannel ? KErrNone : KErrNoMemory;
1.248 + }
1.249 +
1.250 +TInt DRtosIfcFactory::Install()
1.251 + {
1.252 + TInt r = SetName(&KRtosIfcLddName);
1.253 +#ifndef __EPOC32__
1.254 + if (r == KErrNone)
1.255 + r = EntryPoint();
1.256 +#endif
1.257 + return r;
1.258 + }
1.259 +
1.260 +void DRtosIfcFactory::GetCaps(TDes8& aDes) const
1.261 + {
1.262 + TCapsRtosIfcV01 b;
1.263 + b.iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
1.264 + Kern::InfoCopy(aDes,(TUint8*)&b,sizeof(b));
1.265 + }
1.266 +
1.267 +DRtosIfc::DRtosIfc()
1.268 + : iRxQ(&Kern::CurrentThread()),
1.269 + iRptQ(&Kern::CurrentThread())
1.270 + {
1.271 + iThread=&Kern::CurrentThread();
1.272 + iThread->Open();
1.273 + }
1.274 +
1.275 +DRtosIfc::~DRtosIfc()
1.276 + {
1.277 + iRxQ.Close();
1.278 + iRptQ.Close();
1.279 + Kern::SafeClose((DObject*&)iThread, NULL);
1.280 + }
1.281 +
1.282 +TInt DRtosIfc::DoCreate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer)
1.283 +//
1.284 +// Create channel
1.285 +//
1.286 + {
1.287 +
1.288 + if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer))
1.289 + return KErrNotSupported;
1.290 + if (ThePMsgQ.iPtr)
1.291 + return KErrInUse;
1.292 + SetDfcQ(Kern::DfcQue0());
1.293 + iMsgQ.Receive();
1.294 + ThePMsgQ.iPtr = this;
1.295 + ThePMsgQ.Receive();
1.296 + return KErrNone;
1.297 + }
1.298 +
1.299 +void DRtosIfc::HandleMsg(TMessageBase* aMsg)
1.300 + {
1.301 + TThreadMessage& m=*(TThreadMessage*)aMsg;
1.302 + TInt id=m.iValue;
1.303 + if (id==(TInt)ECloseMsg)
1.304 + {
1.305 + ThePMsgQ.CancelReceive();
1.306 + ThePMsgQ.iPtr = NULL;
1.307 + m.Complete(KErrNone,EFalse);
1.308 + iMsgQ.CompleteAll(KErrServerTerminated);
1.309 + return;
1.310 + }
1.311 + else if (id==KMaxTInt)
1.312 + {
1.313 + // DoCancel
1.314 + DoCancel(m.Int0());
1.315 + m.Complete(KErrNone,ETrue);
1.316 + return;
1.317 + }
1.318 +
1.319 + if (id<0)
1.320 + {
1.321 + // DoRequest
1.322 + TRequestStatus* pS=(TRequestStatus*)m.Ptr0();
1.323 + TInt r=DoRequest(~id,pS,m.Ptr1(),m.Ptr2());
1.324 + if (r!=KErrNone)
1.325 + Kern::RequestComplete(iThread,pS,r);
1.326 + m.Complete(KErrNone,ETrue);
1.327 + }
1.328 + else
1.329 + {
1.330 + // DoControl
1.331 + TInt r=DoControl(id,m.Ptr0(),m.Ptr1());
1.332 + m.Complete(r,ETrue);
1.333 + }
1.334 + }
1.335 +
1.336 +TInt DRtosIfc::DoControl(TInt aFunc, TAny* a1, TAny* a2)
1.337 + {
1.338 + (void)a1;
1.339 + (void)a2;
1.340 + TInt r = KErrNone;
1.341 + switch (aFunc)
1.342 + {
1.343 + case RRtosIfc::EControlInit:
1.344 + SendInitMsg();
1.345 + break;
1.346 + case RRtosIfc::EControlFlush:
1.347 + SendFlushMsg();
1.348 + break;
1.349 + case RRtosIfc::EControlFinish:
1.350 + SendFinishMsg();
1.351 + break;
1.352 + case RRtosIfc::EControlSend:
1.353 + {
1.354 + data_msg* dm = (data_msg*)alloc_mem_block(512);
1.355 + TPtr8 lptr(dm->data, 0, 516-sizeof(data_msg));
1.356 + r = Kern::ThreadDesRead(iThread, a1, lptr, 0, 0);
1.357 + if (r == KErrNone)
1.358 + {
1.359 + dm->header.msg_id = MSG_ID_DATA;
1.360 + dm->length = lptr.Length();
1.361 + dm->checksum = 0;
1.362 + send_msg(OC_TASK, &dm->header);
1.363 + }
1.364 + else
1.365 + free_mem_block(dm);
1.366 + break;
1.367 + }
1.368 + default:
1.369 + r = KErrNotSupported;
1.370 + break;
1.371 + }
1.372 + return r;
1.373 + }
1.374 +
1.375 +TInt DRtosIfc::DoRequest(TInt aFunc, TRequestStatus* aStatus, TAny* a1, TAny* a2)
1.376 + {
1.377 + (void)a1;
1.378 + (void)a2;
1.379 + switch (aFunc)
1.380 + {
1.381 + case RRtosIfc::ERequestWaitInitialTests:
1.382 + iDoneStatus = aStatus;
1.383 + return KErrNone;
1.384 + case RRtosIfc::ERequestReceive:
1.385 + return iRxQ.QueueReq(aStatus, a1);
1.386 + case RRtosIfc::ERequestReport:
1.387 + return iRptQ.QueueReq(aStatus, a1);
1.388 + default:
1.389 + return KErrNotSupported;
1.390 + }
1.391 + }
1.392 +
1.393 +void DRtosIfc::DoCancel(TInt aMask)
1.394 + {
1.395 + if (aMask & RRtosIfc::ECancelWaitInitialTests)
1.396 + {
1.397 + Kern::RequestComplete(iThread, iDoneStatus, KErrCancel), iDoneStatus=NULL;
1.398 + }
1.399 + if (aMask & RRtosIfc::ECancelReceive)
1.400 + iRxQ.CancelReq();
1.401 + if (aMask & RRtosIfc::ECancelReport)
1.402 + iRptQ.CancelReq();
1.403 + }
1.404 +
1.405 +void DRtosIfc::HandleRtosMsg(msghdr* aM)
1.406 + {
1.407 + switch (aM->msg_id)
1.408 + {
1.409 + case MSG_ID_DONE:
1.410 + if (iDoneStatus)
1.411 + Kern::RequestComplete(iThread, iDoneStatus, KErrNone), iDoneStatus=NULL;
1.412 + break;
1.413 + case MSG_ID_DATA:
1.414 + iRxQ.AddMsg(aM);
1.415 + aM = NULL;
1.416 + break;
1.417 + case MSG_ID_SEM_RPT:
1.418 + case MSG_ID_RCV_RPT:
1.419 + case MSG_ID_TM_RPT:
1.420 + iRptQ.AddMsg(aM);
1.421 + aM = NULL;
1.422 + break;
1.423 + default:
1.424 + break;
1.425 + }
1.426 + if (aM)
1.427 + free_mem_block(aM);
1.428 + ThePMsgQ.Receive();
1.429 + }
1.430 +
1.431 +#ifdef __EPOC32__
1.432 +DECLARE_STANDARD_EXTENSION()
1.433 + {
1.434 + return EntryPoint();
1.435 + }
1.436 +
1.437 +DECLARE_EXTENSION_LDD()
1.438 + {
1.439 + return new DRtosIfcFactory;
1.440 + }
1.441 +#else
1.442 +DECLARE_STANDARD_LDD()
1.443 + {
1.444 + return new DRtosIfcFactory;
1.445 + }
1.446 +#endif
1.447 +