|
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 // e32\memmodel\epoc\multiple\x86\xkernel.cpp |
|
15 // |
|
16 // |
|
17 |
|
18 #include <x86_mem.h> |
|
19 |
|
20 |
|
21 /******************************************** |
|
22 * Thread |
|
23 ********************************************/ |
|
24 |
|
25 TInt DX86PlatThread::SetupContext(SThreadCreateInfo& aInfo) |
|
26 { |
|
27 switch(iThreadType) |
|
28 { |
|
29 case EThreadSupervisor: |
|
30 case EThreadMinimalSupervisor: |
|
31 case EThreadInitial: |
|
32 case EThreadAPInitial: |
|
33 break; |
|
34 case EThreadUser: |
|
35 break; |
|
36 } |
|
37 iNThread.SetAddressSpace(iOwningProcess); |
|
38 iNThread.SetAttributes(KThreadAttAddressSpace); |
|
39 #ifdef __SMP__ |
|
40 iCpuRestoreCookie = -1; |
|
41 #else |
|
42 iAliasPdePtr = &PageDirectory(((DMemModelProcess*)iOwningProcess)->iOsAsid)[KIPCAlias>>KChunkShift]; |
|
43 #endif |
|
44 return KErrNone; |
|
45 } |
|
46 |
|
47 /******************************************** |
|
48 * Process |
|
49 ********************************************/ |
|
50 |
|
51 DX86PlatProcess::DX86PlatProcess() |
|
52 { |
|
53 iAddressCheckMaskR=0x000fffffu; // addresses<0xA0000000 OK |
|
54 iAddressCheckMaskW=0x0000ffffu; // addresses<0x80000000 OK |
|
55 } |
|
56 |
|
57 DX86PlatProcess::~DX86PlatProcess() |
|
58 { |
|
59 __KTRACE_OPT(KMMU,Kern::Printf("DX86PlatProcess destruct")); |
|
60 DMemModelProcess::Destruct(); |
|
61 } |
|
62 |
|
63 TInt DX86PlatProcess::GetNewChunk(DMemModelChunk*& aChunk, SChunkCreateInfo& aInfo) |
|
64 { |
|
65 aChunk=NULL; |
|
66 DX86PlatChunk* pC=new DX86PlatChunk; |
|
67 if (!pC) |
|
68 return KErrNoMemory; |
|
69 aChunk=pC; |
|
70 TChunkType type = aInfo.iType; |
|
71 pC->iChunkType=type; |
|
72 TInt r=pC->SetAttributes(aInfo); |
|
73 if(r==KErrNone) |
|
74 { |
|
75 if(type==ESharedKernelSingle || type==ESharedKernelMultiple || type==ESharedIo) |
|
76 { |
|
77 DX86PlatChunk* pM=new DX86PlatChunk; |
|
78 if (!pM) |
|
79 return KErrNoMemory; |
|
80 pC->iKernelMirror = pM; |
|
81 pM->iChunkType = ESharedKernelMirror; |
|
82 r=pM->SetAttributes(aInfo); |
|
83 } |
|
84 } |
|
85 return r; |
|
86 } |
|
87 |
|
88 TInt DX86PlatChunk::SetAttributes(SChunkCreateInfo& aInfo) |
|
89 { |
|
90 switch(iChunkType) |
|
91 { |
|
92 case EKernelData: |
|
93 iAttributes = EAddressFixed|EMapTypeGlobal|EPrivate; |
|
94 break; |
|
95 case ERamDrive: |
|
96 iAttributes = EAddressFixed|EMapTypeShared|EPrivate; |
|
97 break; |
|
98 case EKernelStack: |
|
99 iAttributes = EAddressKernel|EMapTypeGlobal|EPrivate; |
|
100 break; |
|
101 case EKernelCode: |
|
102 iAttributes = EAddressKernel|EMapTypeGlobal|EPrivate|ECode; |
|
103 break; |
|
104 case EDll: |
|
105 case EUserCode: |
|
106 if (aInfo.iGlobal) |
|
107 iAttributes = EAddressUserGlobal|EMapTypeGlobal|ECode; |
|
108 else |
|
109 iAttributes = EAddressFixed|EMapTypeLocal|EPrivate|ECode; |
|
110 break; |
|
111 case EUserData: |
|
112 if (aInfo.iGlobal) |
|
113 iAttributes = EAddressShared|EMapTypeShared; |
|
114 else |
|
115 iAttributes = EAddressLocal|EMapTypeLocal|EPrivate; |
|
116 break; |
|
117 case EDllData: |
|
118 iAttributes = EAddressFixed|EMapTypeLocal|EPrivate; |
|
119 break; |
|
120 case EUserSelfModCode: |
|
121 if (aInfo.iGlobal) |
|
122 iAttributes = EAddressShared|EMapTypeShared|ECode; |
|
123 else |
|
124 iAttributes = EAddressLocal|EMapTypeLocal|EPrivate|ECode; |
|
125 break; |
|
126 case ESharedKernelSingle: |
|
127 case ESharedKernelMultiple: |
|
128 case ESharedIo: |
|
129 iAttributes = EAddressShared|EMapTypeShared; |
|
130 break; |
|
131 case ESharedKernelMirror: |
|
132 iAttributes = EAddressKernel|EMapTypeGlobal|EPrivate; |
|
133 break; |
|
134 case EKernelMessage: |
|
135 iAttributes = EAddressKernel|EMapTypeGlobal|EPrivate; |
|
136 break; |
|
137 default: |
|
138 FAULT(); |
|
139 } |
|
140 return KErrNone; |
|
141 } |
|
142 |
|
143 /******************************************** |
|
144 * Chunk |
|
145 ********************************************/ |
|
146 |
|
147 DX86PlatChunk::DX86PlatChunk() |
|
148 {} |
|
149 |
|
150 DX86PlatChunk::~DX86PlatChunk() |
|
151 { |
|
152 DMemModelChunk::Destruct(); |
|
153 } |
|
154 |
|
155 TInt DX86PlatChunk::SetupPermissions() |
|
156 { |
|
157 Mmu& m=Mmu::Get(); |
|
158 if(iChunkType==ESharedKernelSingle || iChunkType==ESharedKernelMultiple || iChunkType==ESharedIo || iChunkType==ESharedKernelMirror) |
|
159 { |
|
160 // override map attributes for shared kernel chunks |
|
161 TUint ma = (iMapAttr &~ EMapAttrAccessMask) | (iChunkType==ESharedKernelMirror?EMapAttrSupRw:EMapAttrUserRw); |
|
162 TInt r = m.PdePtePermissions(ma, iPdePermissions, iPtePermissions); |
|
163 if (r != KErrNone) |
|
164 return r; |
|
165 iMapAttr = ma; |
|
166 } |
|
167 else |
|
168 { |
|
169 iPtePermissions=m.PtePermissions(iChunkType); |
|
170 iPdePermissions=m.PdePermissions(iChunkType,EFalse); |
|
171 } |
|
172 |
|
173 __KTRACE_OPT(KMMU,Kern::Printf("Chunk permissions PTE=%08x PDE=%08x",iPtePermissions,iPdePermissions)); |
|
174 return KErrNone; |
|
175 } |
|
176 |
|
177 TIpcExcTrap::TExcLocation TIpcExcTrap::ExcLocation(DThread* aThread, TAny* aContext) |
|
178 { |
|
179 TX86ExcInfo& info=*(TX86ExcInfo*)aContext; |
|
180 if (info.iExcId==EX86VectorPageFault) |
|
181 { |
|
182 TLinAddr va=(TLinAddr)info.iFaultAddress; |
|
183 |
|
184 TLinAddr aliasAddr = ((DMemModelThread*)aThread)->iAliasLinAddr; |
|
185 TBool remoteError; |
|
186 if(aliasAddr) |
|
187 remoteError = TUint(va^aliasAddr)<TUint(KPageSize); |
|
188 else |
|
189 remoteError = va>=iRemoteBase && (va-iRemoteBase)<iSize; |
|
190 if (remoteError) |
|
191 return EExcRemote; |
|
192 |
|
193 if (iLocalBase && va>=iLocalBase && (va-iLocalBase)<iSize) |
|
194 return EExcLocal; |
|
195 } |
|
196 else if (info.iExcId==EX86VectorGPF) |
|
197 { |
|
198 TUint16 ds=(TUint16)info.iDs; |
|
199 TUint16 es=(TUint16)info.iEs; |
|
200 TUint16 seg=iDir?ds:es; // write -> local read -> DS restricted, else ES restricted |
|
201 if (seg==KRing3DS || seg==KRing3CS) |
|
202 return EExcLocal; |
|
203 } |
|
204 return EExcUnknown; |
|
205 } |