|
1 // Copyright (c) 1994-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 // |
|
15 |
|
16 #include <memmodel.h> |
|
17 #include "mmu/mm.h" |
|
18 #include "mmboot.h" |
|
19 |
|
20 |
|
21 /******************************************** |
|
22 * Thread |
|
23 ********************************************/ |
|
24 |
|
25 TInt DThread::AllocateSupervisorStack() |
|
26 { |
|
27 __KTRACE_OPT(KTHREAD,Kern::Printf("DThread::AllocateSupervisorStack %O %x",this,iSupervisorStackSize)); |
|
28 iSupervisorStackSize = MM::RoundToPageSize(iSupervisorStackSize); |
|
29 if(iThreadType==EThreadInitial) |
|
30 return KErrNone; |
|
31 |
|
32 TUint guardSize = PP::SupervisorThreadStackGuard; |
|
33 TUint virtualSize = guardSize+iSupervisorStackSize; |
|
34 DMemoryObject* memory; |
|
35 TInt r = MM::MemoryNew(memory,EMemoryObjectUnpaged,MM::BytesToPages(virtualSize)); |
|
36 if(r==KErrNone) |
|
37 { |
|
38 r = MM::MemoryAlloc(memory,MM::BytesToPages(guardSize),MM::BytesToPages(iSupervisorStackSize)); |
|
39 if(r==KErrNone) |
|
40 { |
|
41 DMemoryMapping* mapping; |
|
42 r = MM::MappingNew(mapping,memory,ESupervisorReadWrite,KKernelOsAsid); |
|
43 if(r==KErrNone) |
|
44 { |
|
45 __NK_ASSERT_DEBUG(!((DMemModelThread*)this)->iKernelStackMapping); |
|
46 ((DMemModelThread*)this)->iKernelStackMapping = mapping; |
|
47 iSupervisorStack = (TAny*)(MM::MappingBase(mapping)+guardSize); |
|
48 __KTRACE_OPT(KTHREAD,Kern::Printf("Supervisor stack at %x, size %x",iSupervisorStack,iSupervisorStackSize)); |
|
49 } |
|
50 } |
|
51 if(r!=KErrNone) |
|
52 MM::MemoryDestroy(memory); |
|
53 else |
|
54 { |
|
55 #ifdef BTRACE_FLEXIBLE_MEM_MODEL |
|
56 BTrace8(BTrace::EFlexibleMemModel,BTrace::EMemoryObjectIsSupervisorStack,memory,&iNThread); |
|
57 #endif |
|
58 } |
|
59 } |
|
60 return r; |
|
61 } |
|
62 |
|
63 |
|
64 void DThread::FreeSupervisorStack() |
|
65 { |
|
66 __KTRACE_OPT(KTHREAD,Kern::Printf("DThread::FreeSupervisorStack %O",this)); |
|
67 if(iThreadType==EThreadInitial) // !!!??? |
|
68 return; |
|
69 MM::MappingAndMemoryDestroy(((DMemModelThread*)this)->iKernelStackMapping); |
|
70 } |
|
71 |
|
72 |
|
73 TInt DThread::AllocateUserStack(TInt aSize, TBool aPaged) |
|
74 { |
|
75 __KTRACE_OPT(KTHREAD,Kern::Printf("DThread::AllocateUserStack %O %x",this,aSize)); |
|
76 aSize = MM::RoundToPageSize(aSize); |
|
77 if(aSize>PP::MaxUserThreadStack) |
|
78 return KErrTooBig; |
|
79 |
|
80 TMemoryObjectType memoryType = (aPaged)? EMemoryObjectPaged : EMemoryObjectMovable; |
|
81 TUint guardSize = PP::UserThreadStackGuard; |
|
82 TUint virtualSize = guardSize+aSize; |
|
83 // wipe user thread stack with 0x29292929 |
|
84 TMemoryCreateFlags flags = (TMemoryCreateFlags)(EMemoryCreateDefault | EMemoryCreateUseCustomWipeByte | (0x29 << EMemoryCreateWipeByteShift)); |
|
85 DMemoryObject* memory; |
|
86 TInt r = MM::MemoryNew(memory, memoryType, MM::BytesToPages(virtualSize),flags); |
|
87 if(r==KErrNone) |
|
88 { |
|
89 r = MM::MemoryAlloc(memory,MM::BytesToPages(guardSize),MM::BytesToPages(aSize)); |
|
90 if(r==KErrNone) |
|
91 { |
|
92 DMemoryMapping* mapping; |
|
93 // Get os asid, no need to open a reference as this only invoked where |
|
94 // the current thread is owned by iOwningProcess, iOwningProcess is |
|
95 // the kernel process or this is the first thread of a process that |
|
96 // isn't fully created yet. |
|
97 TUint osAsid = ((DMemModelProcess*)iOwningProcess)->OsAsid(); |
|
98 r = MM::MappingNew(mapping,memory,EUserReadWrite,osAsid); |
|
99 if(r==KErrNone) |
|
100 { |
|
101 __NK_ASSERT_DEBUG(!((DMemModelThread*)this)->iUserStackMapping); |
|
102 ((DMemModelThread*)this)->iUserStackMapping = mapping; |
|
103 iUserStackSize = aSize; |
|
104 iUserStackRunAddress = MM::MappingBase(mapping)+guardSize; |
|
105 __KTRACE_OPT(KTHREAD,Kern::Printf("User stack at %x, size %x",iUserStackRunAddress,iUserStackSize)); |
|
106 } |
|
107 } |
|
108 if(r!=KErrNone) |
|
109 MM::MemoryDestroy(memory); |
|
110 else |
|
111 { |
|
112 #ifdef BTRACE_FLEXIBLE_MEM_MODEL |
|
113 BTrace8(BTrace::EFlexibleMemModel,BTrace::EMemoryObjectIsUserStack,memory,&iNThread); |
|
114 #endif |
|
115 } |
|
116 } |
|
117 return r; |
|
118 } |
|
119 |
|
120 |
|
121 void DThread::FreeUserStack() |
|
122 { |
|
123 __KTRACE_OPT(KTHREAD,Kern::Printf("DThread::FreeUserStack %O",this)); |
|
124 MM::MappingAndMemoryDestroy(((DMemModelThread*)this)->iUserStackMapping); |
|
125 } |
|
126 |
|
127 |
|
128 void DMemModelThread::SetPaging(TUint& aCreateFlags) |
|
129 { |
|
130 TUint pagingAtt = aCreateFlags & EThreadCreateFlagPagingMask; |
|
131 TUint dataPolicy = TheSuperPage().KernelConfigFlags() & EKernelConfigDataPagingPolicyMask; |
|
132 if (dataPolicy == EKernelConfigDataPagingPolicyNoPaging || |
|
133 !(K::MemModelAttributes & EMemModelAttrDataPaging)) |
|
134 {// No paging policy set or no data paging device installed. |
|
135 pagingAtt = EThreadCreateFlagUnpaged; |
|
136 } |
|
137 else if (dataPolicy == EKernelConfigDataPagingPolicyAlwaysPage) |
|
138 { |
|
139 pagingAtt = EThreadCreateFlagPaged; |
|
140 } |
|
141 else if (pagingAtt == EThreadCreateFlagPagingUnspec) |
|
142 {// No data paging attribute specified for this chunk so use the process's. |
|
143 if (iOwningProcess->iAttributes & DProcess::EDataPaged) |
|
144 pagingAtt = EThreadCreateFlagPaged; |
|
145 else |
|
146 pagingAtt = EThreadCreateFlagUnpaged; |
|
147 } |
|
148 #ifdef _DEBUG |
|
149 else |
|
150 { |
|
151 __NK_ASSERT_DEBUG( pagingAtt == EThreadCreateFlagPaged || |
|
152 pagingAtt == EThreadCreateFlagUnpaged); |
|
153 } |
|
154 #endif |
|
155 // Save the paging attributes for when the stack and heap are created later. |
|
156 aCreateFlags &= ~EThreadCreateFlagPagingMask; |
|
157 aCreateFlags |= pagingAtt; |
|
158 } |
|
159 |
|
160 |
|
161 void DMemModelThread::DoExit1() |
|
162 { |
|
163 // Regularize the thread state before main exit processing. |
|
164 // We must remove any existing alias before we do any operation |
|
165 // which requires aliasing (e.g. logon completion). |
|
166 __KTRACE_OPT(KTHREAD,Kern::Printf("DMemModelThread %O DoExit1",this)); |
|
167 RemoveAlias(); |
|
168 } |
|
169 |
|
170 |
|
171 void DThread::IpcExcHandler(TExcTrap* aTrap, DThread* aThread, TAny* aContext) |
|
172 { |
|
173 aThread->iIpcClient = 0; |
|
174 TIpcExcTrap& xt=*(TIpcExcTrap*)aTrap; |
|
175 switch (xt.ExcLocation(aThread, aContext)) |
|
176 { |
|
177 case TIpcExcTrap::EExcRemote: |
|
178 // problem accessing remote address - 'leave' so an error code will be returned |
|
179 ((DMemModelThread*)aThread)->RemoveAlias(); |
|
180 xt.Exception(KErrBadDescriptor); // does not return |
|
181 |
|
182 case TIpcExcTrap::EExcLocal: |
|
183 // problem accessing local address - return and panic current thread as usual |
|
184 ((DMemModelThread*)aThread)->RemoveAlias(); |
|
185 return; |
|
186 |
|
187 default: |
|
188 // otherwise return and fault kernel |
|
189 NKern::LockSystem(); |
|
190 return; |
|
191 } |
|
192 } |
|
193 |
|
194 |
|
195 void DMemModelThread::BTracePrime(TInt aCategory) |
|
196 { |
|
197 DThread::BTracePrime(aCategory); |
|
198 #ifdef BTRACE_FLEXIBLE_MEM_MODEL |
|
199 if(aCategory==BTrace::EFlexibleMemModel || aCategory==-1) |
|
200 { |
|
201 if (iKernelStackMapping) |
|
202 { |
|
203 DMemoryObject* memory = MM::MappingGetAndOpenMemory(iKernelStackMapping); |
|
204 if (memory) |
|
205 { |
|
206 MM::MemoryBTracePrime(memory); |
|
207 BTrace8(BTrace::EFlexibleMemModel,BTrace::EMemoryObjectIsSupervisorStack,memory,&iNThread); |
|
208 MM::MemoryClose(memory); |
|
209 } |
|
210 } |
|
211 if (iUserStackMapping) |
|
212 { |
|
213 DMemoryObject* memory = MM::MappingGetAndOpenMemory(iUserStackMapping); |
|
214 if (memory) |
|
215 { |
|
216 MM::MemoryBTracePrime(memory); |
|
217 BTrace8(BTrace::EFlexibleMemModel,BTrace::EMemoryObjectIsUserStack,memory,&iNThread); |
|
218 MM::MemoryClose(memory); |
|
219 } |
|
220 } |
|
221 } |
|
222 #endif |
|
223 } |