author | Mike Kinghan <mikek@symbian.org> |
Mon, 19 Jul 2010 14:32:36 +0100 | |
branch | GCC_SURGE |
changeset 210 | b592f7984442 |
parent 90 | 947f0dc9f7a8 |
child 176 | af6ec97d9189 |
permissions | -rw-r--r-- |
0 | 1 |
// Copyright (c) 1996-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\kernel\sinit.cpp |
|
15 |
// |
|
16 |
// |
|
17 |
||
18 |
#include <kernel/kern_priv.h> |
|
19 |
#include <e32uid.h> |
|
20 |
#include <collate.h> |
|
21 |
#include <kernel/emi.h> |
|
22 |
#include <kernel/sshbuf.h> |
|
23 |
#include "platform.h" |
|
90
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
24 |
#include "securerng.h" |
0 | 25 |
|
26 |
#ifdef __VC32__ |
|
27 |
#pragma setlocale("english") |
|
28 |
#endif |
|
29 |
||
30 |
#ifndef _UNICODE |
|
31 |
Non-unicode kernel builds not supported |
|
32 |
#endif |
|
33 |
||
34 |
_LIT(KLitNull,"Null"); |
|
35 |
_LIT(KLitSupervisor,"Supervisor"); |
|
36 |
_LIT(KLitSvHeap,"SvHeap"); |
|
37 |
_LIT(KLitCodeSegLock,"CodeSegLock"); |
|
38 |
_LIT(KLitMsgChunk, "MsgChunk"); |
|
39 |
_LIT(KLitMsgChunkLock, "MsgChunkLock"); |
|
40 |
const TInt KMaxMsgChunkSize = 0x200000; |
|
41 |
||
42 |
_LIT(KDShBufThreadName,"DShBufThread"); |
|
43 |
const TInt KDShBufThreadPriority = 7; // same priority as normal background thread |
|
44 |
const TInt KDfcThread0Priority=27; |
|
45 |
const TInt KDfcThread1Priority=48; |
|
46 |
const TInt KMaxEventQueue=40; |
|
47 |
||
90
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
48 |
#ifdef __SMP__ |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
49 |
_LIT(KRebalanceName, "LB"); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
50 |
const TInt KRebalancePriority=26; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
51 |
#endif |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
52 |
|
0 | 53 |
TInt SupervisorThread(TAny*); |
54 |
TInt DebuggerInit(); |
|
90
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
55 |
extern TInt InitialiseEntropyBuffers(); |
0 | 56 |
|
57 |
extern const SNThreadHandlers EpocThreadHandlers; |
|
58 |
||
59 |
/** |
|
60 |
Returns information about how the system started |
|
61 |
||
62 |
@return ETrue if the startup reason was a cold start and |
|
63 |
EFalse otherwise |
|
64 |
*/ |
|
65 |
EXPORT_C TBool Kern::ColdStart() |
|
66 |
{ |
|
67 |
return K::ColdStart; |
|
68 |
} |
|
69 |
||
70 |
#ifdef __SMP__ |
|
71 |
EXPORT_D extern const TInt KSMPNumCpus = 0; // used in platform specific cinit.cpp to restrict number of CPUs |
|
72 |
||
73 |
extern "C" void ApMainGeneric(volatile SAPBootInfo* aInfo) |
|
74 |
{ |
|
75 |
DThread* t = (DThread*)aInfo->iArgs[0]; |
|
76 |
__KTRACE_OPT(KBOOT,DEBUGPRINT("Initial thread at %08x", t)); |
|
77 |
SNThreadCreateInfo info; |
|
78 |
info.iFunction = 0; |
|
79 |
info.iStackBase = (TAny*)aInfo->iInitStackBase; |
|
80 |
info.iStackSize = aInfo->iInitStackSize; |
|
81 |
info.iPriority = 0; |
|
82 |
info.iTimeslice = -1; |
|
83 |
info.iAttributes = t->iNThread.i_ThrdAttr; |
|
84 |
info.iHandlers = &EpocThreadHandlers; |
|
85 |
info.iFastExecTable = (const SFastExecTable*)EpocFastExecTable; |
|
86 |
info.iSlowExecTable = (const SSlowExecTable*)EpocSlowExecTable; |
|
87 |
info.iParameterBlock = (const TUint32*)aInfo; |
|
88 |
info.iParameterBlockSize = 0; |
|
89 |
info.iCpuAffinity = 0; // nanokernel substitutes with correct CPU number |
|
90 |
info.iGroup = 0; |
|
91 |
||
92 |
TAny* ec = t->iNThread.iExtraContext; |
|
93 |
TInt ecs = t->iNThread.iExtraContextSize; |
|
94 |
NKern::Init(&t->iNThread, info); |
|
95 |
t->iNThread.SetExtraContext(ec, ecs); |
|
96 |
||
97 |
__KTRACE_OPT(KBOOT,DEBUGPRINT("NKern::CurrentThread() = %08x", NKern::CurrentThread())); |
|
98 |
||
99 |
M::Init2AP(); |
|
100 |
A::Init2AP(); |
|
101 |
||
102 |
__e32_atomic_store_ord32(&aInfo->iArgs[1], 1); |
|
103 |
||
104 |
FOREVER |
|
105 |
{ |
|
106 |
NKern::Idle(); |
|
107 |
} |
|
108 |
} |
|
109 |
||
110 |
||
111 |
void K::InitAP(TInt aCpu, volatile SAPBootInfo* aInfo, TInt aTimeout) |
|
112 |
{ |
|
113 |
__KTRACE_OPT(KBOOT,Kern::Printf("K::InitAP aCpu=%d aInfo=%08x HwId=%08x aTimeout=%d", aCpu, aInfo, aInfo->iCpu, aTimeout)); |
|
114 |
SThreadCreateInfo t; |
|
115 |
TBuf8<8> name(KLitNull); |
|
116 |
name.AppendNum(aCpu); |
|
117 |
memclr(&t, sizeof(t)); |
|
118 |
t.iType=EThreadAPInitial; |
|
119 |
t.iName.Set(name); |
|
120 |
t.iTotalSize = sizeof(t); |
|
121 |
DThread* pN1 = NULL; |
|
122 |
TInt r = K::TheKernelProcess->NewThread(pN1, t, NULL, EOwnerProcess); |
|
123 |
__KTRACE_OPT(KBOOT,Kern::Printf("Created idle thread %d, %d", aCpu+1, r)); |
|
124 |
if (r!=KErrNone) |
|
125 |
K::Fault(K::EAPInitialThreadCreateFailed); |
|
126 |
||
127 |
aInfo->iInitStackSize = pN1->iSupervisorStackSize; |
|
128 |
aInfo->iInitStackBase = (TLinAddr)pN1->iSupervisorStack; |
|
129 |
aInfo->iMain = &ApMainGeneric; |
|
130 |
aInfo->iArgs[0] = (TAny*)pN1; |
|
131 |
aInfo->iArgs[1] = 0; |
|
132 |
__KTRACE_OPT(KTHREAD,DEBUGPRINT("AP Initial thread at %08x", aInfo->iArgs[0])); |
|
133 |
||
134 |
r = NKern::BootAP(aInfo); |
|
135 |
__NK_ASSERT_ALWAYS(r==KErrNone); |
|
136 |
while (--aTimeout && !__e32_atomic_load_acq32(&aInfo->iArgs[1])) |
|
137 |
{ |
|
138 |
Kern::NanoWait(1000000); |
|
139 |
} |
|
140 |
if (!aTimeout) |
|
141 |
K::Fault(K::EInit2APTimeout); |
|
142 |
} |
|
143 |
#endif |
|
144 |
||
145 |
TInt K::InitialiseMicrokernel() |
|
146 |
{ |
|
147 |
__KTRACE_OPT(KBOOT,Kern::Printf("K::InitialiseMicrokernel()")); |
|
148 |
||
149 |
// first phase cache/memory model initialisation |
|
150 |
M::Init1(); |
|
151 |
||
152 |
// miscellaneous first-phase initialisation |
|
153 |
// this enables interrupts |
|
154 |
A::Init1(); |
|
155 |
||
156 |
TProcessCreateInfo kpinfo; |
|
157 |
TAny* kern_stack_addr; |
|
158 |
TAny* kern_heap_addr; |
|
159 |
P::KernelInfo(kpinfo, kern_stack_addr, kern_heap_addr); |
|
160 |
__KTRACE_OPT(KBOOT,Kern::Printf("kern_heap_addr %08x, kern_stack_addr %08x",kern_heap_addr,kern_stack_addr)); |
|
161 |
__KTRACE_OPT(KBOOT,Kern::Printf("HeapSizeMin %08x",kpinfo.iHeapSizeMin)); |
|
162 |
||
163 |
// set up the kernel heap as a fixed heap |
|
164 |
RHeapK* kheap = RHeapK::FixedHeap(kern_heap_addr, kpinfo.iHeapSizeMin); |
|
165 |
K::Allocator = kheap; |
|
166 |
__KTRACE_OPT(KBOOT,Kern::Printf("Created kernel fixed heap at %08x, size %08x",K::Allocator,kpinfo.iHeapSizeMin)); |
|
167 |
||
168 |
// create the initial thread and process |
|
169 |
DProcess* pP=P::NewProcess(); |
|
170 |
pP->iPriority=EProcPrioritySystemServer3; |
|
171 |
DThread* pT=NULL; |
|
172 |
||
173 |
SThreadCreateInfo t; |
|
174 |
t.iType=EThreadInitial; |
|
175 |
t.iSupervisorStack=kern_stack_addr; |
|
176 |
t.iSupervisorStackSize=kpinfo.iStackSize; |
|
177 |
t.iName.Set(KLitNull); |
|
178 |
t.iTotalSize = sizeof(t); |
|
179 |
TInt r=pP->GetNewThread(pT, t); |
|
180 |
__KTRACE_OPT(KBOOT,Kern::Printf("Get initial thread, %d",r)); |
|
181 |
if (r!=KErrNone) |
|
182 |
return r; |
|
183 |
||
184 |
SNThreadCreateInfo ni; |
|
185 |
ni.iHandlers = &EpocThreadHandlers; |
|
186 |
ni.iFastExecTable=(const SFastExecTable*)EpocFastExecTable; |
|
187 |
ni.iSlowExecTable=(const SSlowExecTable*)EpocSlowExecTable; |
|
188 |
ni.iParameterBlock=NULL; |
|
189 |
ni.iParameterBlockSize=0; |
|
190 |
ni.iStackBase=kern_stack_addr; |
|
191 |
ni.iStackSize=kpinfo.iStackSize; |
|
192 |
#ifdef __SMP__ |
|
193 |
ni.iCpuAffinity=0; |
|
194 |
ni.iGroup = 0; |
|
195 |
#endif |
|
196 |
TAny* ec = pT->iNThread.iExtraContext; |
|
197 |
TInt ecs = pT->iNThread.iExtraContextSize; |
|
198 |
NKern::Init(&pT->iNThread,ni); |
|
199 |
__KTRACE_OPT(KBOOT,Kern::Printf("Done NKern::Init")); |
|
200 |
pT->iNThread.SetExtraContext(ec, ecs); |
|
201 |
||
202 |
r=pT->Create(t); |
|
203 |
__KTRACE_OPT(KBOOT,Kern::Printf("Created initial thread, %d",r)); |
|
204 |
if (r!=KErrNone) |
|
205 |
return r; |
|
206 |
r=pP->Create(ETrue, kpinfo, NULL); |
|
207 |
__KTRACE_OPT(KBOOT,Kern::Printf("Created initial process, %d",r)); |
|
208 |
if (r!=KErrNone) |
|
209 |
return r; |
|
210 |
K::TheNullThread=pT; |
|
211 |
K::TheKernelProcess=pP; |
|
212 |
K::SvMsgQ=new TDfcQue; |
|
213 |
if (!K::SvMsgQ) |
|
214 |
return KErrNoMemory; |
|
215 |
K::AsyncFreeDfc.SetDfcQ(K::SvMsgQ); |
|
216 |
K::AsyncChangeNotifierDfc.SetDfcQ(K::SvMsgQ); |
|
217 |
DCodeSeg::KernelCleanupDfc.SetDfcQ(K::SvMsgQ); |
|
218 |
TClientRequest::DeadClientCleanupDfc.SetDfcQ(K::SvMsgQ); |
|
219 |
||
220 |
// add the initial thread to the initial process |
|
221 |
pP->AddThread(*pT); |
|
222 |
||
223 |
// second phase memory model initialisation |
|
224 |
M::Init2(); |
|
225 |
A::Init2(); |
|
226 |
||
227 |
// create the object containers |
|
228 |
r=K::CreateObjectContainers(); |
|
229 |
__KTRACE_OPT(KBOOT,Kern::Printf("Created object containers, %d",r)); |
|
230 |
if (r!=KErrNone) |
|
231 |
return r; |
|
232 |
||
233 |
// add the initial thread to container |
|
234 |
r=K::AddObject(pT,EThread); |
|
235 |
__KTRACE_OPT(KBOOT,Kern::Printf("Added initial thread, %d",r)); |
|
236 |
if (r!=KErrNone) |
|
237 |
return r; |
|
238 |
||
239 |
// add the initial process to container |
|
240 |
r=K::AddObject(pP,EProcess); |
|
241 |
__KTRACE_OPT(KBOOT,Kern::Printf("Added initial process, %d",r)); |
|
242 |
if (r!=KErrNone) |
|
243 |
return r; |
|
244 |
||
245 |
SChunkCreateInfo cinfo; |
|
246 |
DChunk* pC=NULL; |
|
247 |
TLinAddr dataSectionBase=0; |
|
248 |
TInt kheap_offset = TInt(kern_heap_addr) - TInt(kpinfo.iDataRunAddress); |
|
249 |
TInt init_kernel_size = kheap_offset + kpinfo.iHeapSizeMin; |
|
250 |
TInt total_kernel_size = Kern::RoundToChunkSize(kheap_offset + kpinfo.iHeapSizeMax); |
|
251 |
pP->iDataBssRunAddress=kpinfo.iDataRunAddress; |
|
252 |
pP->iDataBssStackChunk=NULL; // kernel doesn't have separate data chunk |
|
253 |
__KTRACE_OPT(KBOOT,Kern::Printf("kpinfo.iTotalDataSize = %08x",kpinfo.iTotalDataSize)); |
|
254 |
__KTRACE_OPT(KBOOT,Kern::Printf("kpinfo.iStackSize = %08x",kpinfo.iStackSize)); |
|
255 |
__KTRACE_OPT(KBOOT,Kern::Printf("kheap_offset = %08x",kheap_offset)); |
|
256 |
__KTRACE_OPT(KBOOT,Kern::Printf("init_kernel_size = %08x",init_kernel_size)); |
|
257 |
__KTRACE_OPT(KBOOT,Kern::Printf("kpinfo.iHeapSizeMax = %08x",kpinfo.iHeapSizeMax)); |
|
258 |
__KTRACE_OPT(KBOOT,Kern::Printf("total_kernel_size = %08x",total_kernel_size)); |
|
259 |
||
260 |
// create the kernel heap chunk |
|
261 |
// this includes kernel .data, .bss, initial thread stack as well as kernel heap |
|
262 |
cinfo.iGlobal=EFalse; |
|
263 |
cinfo.iAtt=TChunkCreate::ENormal; |
|
264 |
cinfo.iForceFixed=EFalse; |
|
265 |
cinfo.iOperations=0; |
|
266 |
cinfo.iType=EKernelData; |
|
267 |
cinfo.iMaxSize=total_kernel_size; |
|
268 |
cinfo.iPreallocated=0; |
|
269 |
cinfo.iName.Set(KLitSvHeap); |
|
270 |
cinfo.iOwner=pP; |
|
271 |
r=pP->NewChunk(pC,cinfo,dataSectionBase); |
|
272 |
__KTRACE_OPT(KBOOT,Kern::Printf("Created SvHeap, %d",r)); |
|
273 |
if (r!=KErrNone) |
|
274 |
return r; |
|
275 |
r=M::InitSvHeapChunk(pC, init_kernel_size); |
|
276 |
if (r!=KErrNone) |
|
277 |
return r; |
|
278 |
__KTRACE_OPT(KMEMTRACE,Kern::Printf("MT:A %d %x %x %O",NTickCount(), pC, pC->iSize, pC)); |
|
279 |
#ifdef BTRACE_CHUNKS |
|
280 |
BTraceContext12(BTrace::EChunks,BTrace::EChunkMemoryAllocated,pC,0,pC->iSize); |
|
281 |
#endif |
|
282 |
||
283 |
// create the kernel heap interlock mutex |
|
284 |
r = kheap->CreateMutex(); |
|
285 |
if (r!=KErrNone) |
|
286 |
return r; |
|
287 |
||
288 |
// create a chunk to hold supervisor-mode stacks |
|
289 |
r=M::InitSvStackChunk(); |
|
290 |
if (r!=KErrNone) |
|
291 |
return r; |
|
292 |
||
293 |
// mutate the kernel heap into a chunk heap |
|
294 |
kheap->Mutate(kheap_offset, kpinfo.iHeapSizeMax); |
|
295 |
||
296 |
// Intialise debugger |
|
297 |
r= DebuggerInit(); |
|
298 |
if (r!=KErrNone) |
|
299 |
return r; |
|
300 |
||
301 |
// create a chunk to hold all RMessageKs |
|
302 |
memset(&cinfo, 0, sizeof(cinfo)); |
|
303 |
cinfo.iGlobal = EFalse; |
|
304 |
cinfo.iAtt = TChunkCreate::ENormal; |
|
305 |
cinfo.iForceFixed = EFalse; |
|
306 |
cinfo.iOperations = SChunkCreateInfo::EAdjust|SChunkCreateInfo::EAdd; |
|
307 |
cinfo.iType = EKernelMessage; |
|
308 |
cinfo.iMaxSize = Kern::RoundToChunkSize(KMaxMsgChunkSize); |
|
309 |
cinfo.iName.Set(KLitMsgChunk); |
|
310 |
cinfo.iOwner = pP; |
|
311 |
#ifdef __EPOC32__ |
|
312 |
cinfo.iMapAttr = EMapAttrSupRw | EMapAttrCachedMax; // Full caching (not supported in emulator) |
|
313 |
#endif |
|
314 |
||
315 |
pC = NULL; |
|
316 |
TLinAddr msgChunkAddress = 0; |
|
317 |
r = pP->NewChunk(pC, cinfo, msgChunkAddress); |
|
318 |
__KTRACE_OPT(KBOOT, Kern::Printf("NewChunk(MsgChunk) returned %d, address %08X", r, msgChunkAddress)); |
|
319 |
if (r != KErrNone) |
|
320 |
return r; |
|
321 |
K::MsgInfo.iChunk = pC; |
|
322 |
K::MsgInfo.iBase = (TUint8*)msgChunkAddress; |
|
323 |
K::MsgInfo.iMaxSize = pC->iMaxSize; |
|
324 |
K::MsgInfo.iCurrSize = pC->iSize; |
|
325 |
__KTRACE_OPT(KBOOT, Kern::Printf("Created MsgChunk, base %08X, size %d, max size %08X", |
|
326 |
K::MsgInfo.iBase, K::MsgInfo.iCurrSize, K::MsgInfo.iMaxSize)); |
|
327 |
||
328 |
// create the msg chunk mutex |
|
329 |
r = K::MutexCreate(K::MsgInfo.iMsgChunkLock, KLitMsgChunkLock, NULL, EFalse, KMutexOrdGeneral0); |
|
330 |
if (r != KErrNone) |
|
331 |
return r; |
|
332 |
||
333 |
// Create a DPowerModel object and setup K::PowerModel to point to. |
|
334 |
r = PowerModelInit(); |
|
335 |
if (r!=KErrNone) |
|
336 |
return r; |
|
337 |
||
338 |
// create the code segment mutex |
|
339 |
r=K::MutexCreate(DCodeSeg::CodeSegLock, KLitCodeSegLock, NULL, EFalse, KMutexOrdCodeSegLock); |
|
340 |
if (r!=KErrNone) |
|
341 |
return r; |
|
342 |
||
343 |
// Create request object for implementation of NotifyIfCodeSegDestroyed |
|
344 |
r = Kern::CreateClientRequest(DCodeSeg::DestructNotifyRequest); |
|
345 |
if (r!=KErrNone) |
|
346 |
return r; |
|
347 |
||
348 |
#ifdef __EMI_SUPPORT__ |
|
349 |
// Create EMI a thread and Semaphore |
|
350 |
r = EMI::Init(); |
|
351 |
if (r!=KErrNone) |
|
352 |
return r; |
|
353 |
#endif |
|
354 |
||
355 |
pP->Loaded(kpinfo); |
|
356 |
||
357 |
K::TheMiscNotifierMgr.Init2(); |
|
358 |
||
359 |
#ifdef __SMP__ |
|
360 |
if (!(TheSuperPage().KernelConfigFlags() & EKernelConfigDisableAPs)) |
|
361 |
A::InitAPs(); |
|
362 |
#endif |
|
363 |
||
364 |
// create the supervisor thread |
|
365 |
t.iType=EThreadSupervisor; |
|
366 |
t.iFunction=SupervisorThread; |
|
367 |
t.iPtr=NULL; |
|
368 |
t.iInitialThreadPriority=EThrdPriorityMuchMore; |
|
369 |
t.iName.Set(KLitSupervisor); |
|
370 |
t.iSupervisorStack=NULL; |
|
371 |
t.iSupervisorStackSize=0; // zero means use default value |
|
372 |
DThread* pN=NULL; |
|
373 |
r=pP->NewThread(pN, t, NULL, EOwnerProcess); |
|
374 |
__KTRACE_OPT(KBOOT,Kern::Printf("Created supervisor thread, %d",r)); |
|
375 |
if (r!=KErrNone) |
|
376 |
return r; |
|
377 |
||
378 |
pN->iFlags |= KThreadFlagSystemPermanent; // supervisor thread can't exit for any reason |
|
379 |
||
380 |
K::TheKernelThread=pN; |
|
381 |
K::SvMsgQ->iThread=&pN->iNThread; |
|
382 |
K::SvBarrierQ.SetDfcQ(K::SvMsgQ); |
|
383 |
||
384 |
// clear IPC V1 available flag |
|
385 |
TheSuperPage().SetKernelConfigFlags(TheSuperPage().KernelConfigFlags() & ~EKernelConfigIpcV1Available); |
|
386 |
||
387 |
K::Initialising=EFalse; |
|
388 |
||
389 |
// resume the supervisor thread |
|
390 |
Kern::ThreadResume(*pN); |
|
391 |
||
392 |
return KErrNone; |
|
393 |
} |
|
394 |
||
395 |
TInt SupervisorThread(TAny*) |
|
396 |
{ |
|
397 |
TInt r=K::Init3(); |
|
398 |
if (r!=KErrNone) |
|
399 |
K::Fault(K::EInit3Failed); |
|
400 |
||
401 |
P::StartExtensions(); |
|
90
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
402 |
|
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
403 |
M::Init4(); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
404 |
|
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
405 |
#ifdef __SMP__ |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
406 |
TheScheduler.InitLB(); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
407 |
TheScheduler.StartPeriodicBalancing(); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
408 |
#endif |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
409 |
|
0 | 410 |
K::StartKernelServer(); |
411 |
return 0; |
|
412 |
} |
|
413 |
||
414 |
TInt K::Init3() |
|
415 |
{ |
|
416 |
__KTRACE_OPT(KBOOT,Kern::Printf("K::Init3")); |
|
417 |
||
418 |
// Initialise Hal array |
|
419 |
K::InitHalEntryArray(); |
|
420 |
||
421 |
// Third phase MMU initialisation |
|
422 |
M::Init3(); |
|
423 |
||
424 |
// Intialize publish and subscribe (depends on demand paging) |
|
425 |
TInt r = PubSubPropertyInit(); |
|
426 |
if (r!=KErrNone) |
|
427 |
return r; |
|
428 |
||
429 |
// Create the event queue |
|
430 |
K::CreateEventQueue(KMaxEventQueue); |
|
431 |
||
432 |
// Initialise the DFC system |
|
433 |
r=Kern::DfcQCreate(K::DfcQ0,KDfcThread0Priority); |
|
434 |
if (r!=KErrNone) |
|
435 |
return r; |
|
436 |
DThread* pT = _LOFF(K::DfcQ0->iThread, DThread, iNThread); |
|
437 |
pT->iFlags |= KThreadFlagSystemPermanent; |
|
438 |
||
439 |
r=Kern::DfcQCreate(K::DfcQ1,KDfcThread1Priority); |
|
440 |
if (r!=KErrNone) |
|
441 |
return r; |
|
442 |
pT = _LOFF(K::DfcQ1->iThread, DThread, iNThread); |
|
443 |
pT->iFlags |= KThreadFlagSystemPermanent; |
|
444 |
||
445 |
// create the DfcQ for DShPool |
|
446 |
r = Kern::DfcQInit(&DShPool::iSharedDfcQue,KDShBufThreadPriority,&KDShBufThreadName); |
|
447 |
if (r!=KErrNone) |
|
448 |
return r; |
|
449 |
||
90
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
450 |
#ifdef __SMP__ |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
451 |
// create thread and DFC queue for load balancing |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
452 |
TScheduler& s = TheScheduler; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
453 |
r = Kern::DfcQCreate(s.iRebalanceDfcQ, KRebalancePriority, &KRebalanceName); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
454 |
if (r!=KErrNone) |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
455 |
return r; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
456 |
NThread* nt = TScheduler::LBThread(); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
457 |
NKern::ThreadSetCpuAffinity(nt, KCpuAffinityAny); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
458 |
pT = _LOFF(nt, DThread, iNThread); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
459 |
pT->iFlags |= KThreadFlagSystemPermanent; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
460 |
#endif |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
461 |
|
0 | 462 |
// Initialise the RAM drive |
463 |
K::InitNvRam(); |
|
464 |
||
465 |
// Start the millisecond timer |
|
466 |
NTimerQ::Init3(K::DfcQ1); |
|
467 |
||
468 |
// Start the system tick timer |
|
469 |
r=K::StartTickQueue(); |
|
470 |
if (r!=KErrNone) |
|
471 |
return r; |
|
90
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
472 |
|
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
473 |
// Initilize the Secure RNG. |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
474 |
SecureRNG = new DSecureRNG; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
475 |
|
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
476 |
// Initialise entropy buffers for secure RNG |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
477 |
r=InitialiseEntropyBuffers(); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
478 |
if (r!=KErrNone) |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
479 |
return r; |
0 | 480 |
|
481 |
// Third phase initialisation of ASIC/Variant |
|
482 |
// This enables the system tick and millisecond timer |
|
483 |
A::Init3(); |
|
484 |
||
485 |
// Mark the super page signature valid |
|
486 |
P::SetSuperPageSignature(); |
|
487 |
||
488 |
return KErrNone; |
|
489 |
} |
|
490 |
||
491 |
extern "C" void KernelMain() |
|
492 |
{ |
|
493 |
K::Initialising=ETrue; |
|
494 |
__KTRACE_OPT(KBOOT,Kern::Printf("KernelMain")); |
|
495 |
||
496 |
// Zeroth phase initialisation of ASIC and VARIANT |
|
497 |
P::CreateVariant(); |
|
498 |
||
499 |
NKern::Init0(K::VariantData[0]); |
|
500 |
||
501 |
TInt r=K::InitialiseMicrokernel(); |
|
502 |
if (r!=KErrNone) |
|
503 |
K::Fault(K::EInitMicrokernelFailed); |
|
504 |
||
505 |
__KTRACE_OPT(KBOOT,Kern::Printf("Null thread running...")); |
|
506 |
__KTRACE_OPT(KBOOT,Kern::Printf("Null calling Idle()")); |
|
507 |
FOREVER |
|
508 |
{ |
|
509 |
NKern::Idle(); |
|
510 |
} |
|
511 |
} |
|
512 |
||
513 |
LOCAL_C TInt PowerHal(TAny*, TInt aFunction, TAny* a1, TAny* a2) |
|
514 |
{ |
|
515 |
if (K::PowerModel) |
|
516 |
return K::PowerModel->PowerHalFunction(aFunction,a1,a2); |
|
517 |
if (aFunction==EPowerHalSupplyInfo) |
|
518 |
{ |
|
519 |
TSupplyInfoV1 info; |
|
520 |
// info.iMainBatteryInsertionTime; |
|
521 |
info.iMainBatteryStatus=EGood; |
|
522 |
// info.iMainBatteryInUseMicroSeconds=0; |
|
523 |
// info.iCurrentConsumptionMilliAmps; |
|
524 |
// info.iMainBatteryConsumedMilliAmpSeconds; |
|
525 |
info.iMainBatteryMilliVolts=3000; |
|
526 |
info.iMainBatteryMaxMilliVolts=3000; |
|
527 |
info.iBackupBatteryStatus=EGood; |
|
528 |
info.iBackupBatteryMilliVolts=3000; |
|
529 |
info.iBackupBatteryMaxMilliVolts=3000; |
|
530 |
info.iExternalPowerPresent=ETrue; |
|
531 |
// info.iExternalPowerInUseMicroSeconds; |
|
532 |
// info.iFlags; |
|
533 |
Kern::InfoCopy(*(TDes8*)a1,TPtrC8((const TUint8*)&info, sizeof(info))); |
|
534 |
return KErrNone; |
|
535 |
} |
|
536 |
else if (aFunction==EPowerHalTestBootSequence) |
|
537 |
return 0; |
|
538 |
return KErrNotSupported; |
|
539 |
} |
|
540 |
||
541 |
LOCAL_C TInt kernelHal(TAny*, TInt aFunc, TAny* a1, TAny* a2) |
|
542 |
{ |
|
543 |
return K::KernelHal(aFunc,a1,a2); |
|
544 |
} |
|
545 |
||
546 |
LOCAL_C TInt variantHal(TAny*, TInt aFunc, TAny* a1, TAny* a2) |
|
547 |
{ |
|
548 |
return A::VariantHal(aFunc,a1,a2); |
|
549 |
} |
|
550 |
||
551 |
void K::InitHalEntryArray() |
|
552 |
{ |
|
553 |
TInt arraySize=KMaxHalGroups*sizeof(SHalEntry2); |
|
554 |
K::HalEntryArray=(SHalEntry2*)Kern::AllocZ(arraySize); |
|
555 |
K::HalEntryArray[0].iFunction=kernelHal; |
|
556 |
K::HalEntryArray[1].iFunction=variantHal; |
|
557 |
K::HalEntryArray[3].iFunction=PowerHal; |
|
558 |
} |
|
559 |
||
560 |
TInt DebuggerInit() |
|
561 |
// |
|
562 |
// Initialise the debugger API |
|
563 |
// |
|
564 |
{ |
|
565 |
Kern::SuperPage().iDebuggerInfo=NULL; |
|
566 |
return KErrNone; |
|
567 |
} |